import 'package:dartz/dartz.dart';
import '../../domain/entities/share_account.dart';
import '../../domain/entities/global_state.dart';
import '../../domain/entities/planting_record.dart';
import '../../domain/entities/batch_mining_record.dart';
import '../../domain/repositories/mining_repository.dart';
import '../../core/error/exceptions.dart';
import '../../core/error/failures.dart';
import '../datasources/remote/mining_remote_datasource.dart';
import '../datasources/local/cache_manager.dart';

class MiningRepositoryImpl implements MiningRepository {
  final MiningRemoteDataSource remoteDataSource;
  final CacheManager cacheManager;

  MiningRepositoryImpl({
    required this.remoteDataSource,
    required this.cacheManager,
  });

  @override
  Future<Either<Failure, ShareAccount>> getShareAccount(String accountSequence) async {
    try {
      final result = await remoteDataSource.getShareAccount(accountSequence);
      return Right(result);
    } on ServerException catch (e) {
      return Left(ServerFailure(e.message));
    } on NetworkException {
      return Left(const NetworkFailure());
    }
  }

  @override
  Future<Either<Failure, MiningRecordsPage>> getMiningRecords(
    String accountSequence, {
    int page = 1,
    int pageSize = 20,
  }) async {
    try {
      final result = await remoteDataSource.getMiningRecords(
        accountSequence,
        page: page,
        pageSize: pageSize,
      );
      return Right(result);
    } on ServerException catch (e) {
      return Left(ServerFailure(e.message));
    } on NetworkException {
      return Left(const NetworkFailure());
    }
  }

  @override
  Future<Either<Failure, GlobalState>> getGlobalState() async {
    try {
      final cached = await cacheManager.getGlobalState();
      if (cached != null && !cached.isExpired) {
        return Right(cached.data);
      }

      final result = await remoteDataSource.getGlobalState();
      await cacheManager.cacheGlobalState(result);
      return Right(result);
    } on ServerException catch (e) {
      return Left(ServerFailure(e.message));
    } on NetworkException {
      final cached = await cacheManager.getGlobalState();
      if (cached != null) {
        return Right(cached.data);
      }
      return Left(const NetworkFailure());
    }
  }

  @override
  Future<Either<Failure, PlantingLedgerPage>> getPlantingLedger(
    String accountSequence, {
    int page = 1,
    int pageSize = 10,
  }) async {
    try {
      final result = await remoteDataSource.getPlantingLedger(
        accountSequence,
        page: page,
        pageSize: pageSize,
      );
      return Right(result);
    } on ServerException catch (e) {
      return Left(ServerFailure(e.message));
    } on NetworkException {
      return Left(const NetworkFailure());
    }
  }

  @override
  Future<Either<Failure, BatchMiningRecordsPage>> getBatchMiningRecords(
    String accountSequence, {
    int page = 1,
    int pageSize = 20,
  }) async {
    try {
      final result = await remoteDataSource.getBatchMiningRecords(
        accountSequence,
        page: page,
        pageSize: pageSize,
      );
      return Right(result);
    } on ServerException catch (e) {
      return Left(ServerFailure(e.message));
    } on NetworkException {
      return Left(const NetworkFailure());
    }
  }
}
