import '../../models/contribution_model.dart';
import '../../models/contribution_record_model.dart';
import '../../models/contribution_stats_model.dart';
import '../../../core/network/api_client.dart';
import '../../../core/network/api_endpoints.dart';
import '../../../core/error/exceptions.dart';
import '../../../domain/entities/contribution_record.dart';

abstract class ContributionRemoteDataSource {
  Future<ContributionModel> getUserContribution(String accountSequence);
  Future<ContributionRecordsPageModel> getContributionRecords(
    String accountSequence, {
    ContributionSourceType? sourceType,
    bool includeExpired = false,
    int page = 1,
    int pageSize = 50,
  });
  Future<ContributionStatsModel> getContributionStats();
}

class ContributionRemoteDataSourceImpl implements ContributionRemoteDataSource {
  final ApiClient client;

  ContributionRemoteDataSourceImpl({required this.client});

  @override
  Future<ContributionModel> getUserContribution(String accountSequence) async {
    try {
      final response = await client.get(ApiEndpoints.contribution(accountSequence));
      return ContributionModel.fromJson(response.data);
    } catch (e) {
      throw ServerException(e.toString());
    }
  }

  @override
  Future<ContributionRecordsPageModel> getContributionRecords(
    String accountSequence, {
    ContributionSourceType? sourceType,
    bool includeExpired = false,
    int page = 1,
    int pageSize = 50,
  }) async {
    try {
      final queryParams = <String, dynamic>{
        'page': page,
        'pageSize': pageSize,
        'includeExpired': includeExpired,
      };

      if (sourceType != null) {
        queryParams['sourceType'] = _sourceTypeToString(sourceType);
      }

      final response = await client.get(
        ApiEndpoints.contributionRecords(accountSequence),
        queryParameters: queryParams,
      );
      return ContributionRecordsPageModel.fromJson(response.data);
    } catch (e) {
      throw ServerException(e.toString());
    }
  }

  @override
  Future<ContributionStatsModel> getContributionStats() async {
    try {
      final response = await client.get(ApiEndpoints.contributionStats);
      return ContributionStatsModel.fromJson(response.data);
    } catch (e) {
      throw ServerException(e.toString());
    }
  }

  String _sourceTypeToString(ContributionSourceType type) {
    switch (type) {
      case ContributionSourceType.personal:
        return 'PERSONAL';
      case ContributionSourceType.teamLevel:
        return 'TEAM_LEVEL';
      case ContributionSourceType.teamBonus:
        return 'TEAM_BONUS';
    }
  }
}
