import 'package:dio/dio.dart';
import 'package:injectable/injectable.dart';

import '../../../../core/constants/api_constants.dart';
import '../../../../core/network/dio_client.dart';
import '../models/kyc_level_model.dart';
import '../models/kyc_application_model.dart';

abstract class KycRemoteDataSource {
  Future<List<KycLevelModel>> getKycLevels();
  Future<KycLevelModel> getKycLevelById(String levelId);
  Future<List<KycApplicationModel>> getKycApplications();
  Future<KycApplicationModel> getKycApplicationById(String applicationId);
  Future<KycApplicationModel> submitKycApplication({
    required String levelId,
    required Map<String, dynamic> fields,
  });
  Future<KycApplicationModel> updateKycApplication({
    required String applicationId,
    required Map<String, dynamic> fields,
  });
  Future<String> uploadKycDocument({
    required String filePath,
    required String fieldId,
    String? applicationId,
  });
  Future<Map<String, dynamic>> getKycStatus();
}

@Injectable(as: KycRemoteDataSource)
class KycRemoteDataSourceImpl implements KycRemoteDataSource {
  final DioClient _dioClient;

  KycRemoteDataSourceImpl(this._dioClient);

  @override
  Future<List<KycLevelModel>> getKycLevels() async {
    print('🔵 KYC_REMOTE: Getting KYC levels');

    try {
      final response = await _dioClient.get(ApiConstants.kycLevels);
      print('🟢 KYC_REMOTE: Got KYC levels response: ${response.data}');

      if (response.data is List) {
        return (response.data as List)
            .map((json) => KycLevelModel.fromJson(json))
            .toList();
      } else {
        throw const FormatException('Invalid response format for KYC levels');
      }
    } catch (e) {
      print('🔴 KYC_REMOTE: Error getting KYC levels: $e');
      rethrow;
    }
  }

  @override
  Future<KycLevelModel> getKycLevelById(String levelId) async {
    print('🔵 KYC_REMOTE: Getting KYC level by ID: $levelId');

    try {
      final response =
          await _dioClient.get('${ApiConstants.kycLevelById}/$levelId');
      print('🟢 KYC_REMOTE: Got KYC level response: ${response.data}');

      return KycLevelModel.fromJson(response.data);
    } catch (e) {
      print('🔴 KYC_REMOTE: Error getting KYC level: $e');
      rethrow;
    }
  }

  @override
  Future<List<KycApplicationModel>> getKycApplications() async {
    print('🔵 KYC_REMOTE: Getting KYC applications');

    try {
      final response = await _dioClient.get(ApiConstants.kycApplications);
      print('🟢 KYC_REMOTE: Got KYC applications response: ${response.data}');

      if (response.data is List) {
        return (response.data as List)
            .map((json) => KycApplicationModel.fromJson(json))
            .toList();
      } else {
        throw const FormatException(
            'Invalid response format for KYC applications');
      }
    } catch (e) {
      print('🔴 KYC_REMOTE: Error getting KYC applications: $e');
      rethrow;
    }
  }

  @override
  Future<KycApplicationModel> getKycApplicationById(
      String applicationId) async {
    print('🔵 KYC_REMOTE: Getting KYC application by ID: $applicationId');

    try {
      final response = await _dioClient
          .get('${ApiConstants.kycApplicationById}/$applicationId');
      print('🟢 KYC_REMOTE: Got KYC application response: ${response.data}');

      return KycApplicationModel.fromJson(response.data);
    } catch (e) {
      print('🔴 KYC_REMOTE: Error getting KYC application: $e');
      rethrow;
    }
  }

  @override
  Future<KycApplicationModel> submitKycApplication({
    required String levelId,
    required Map<String, dynamic> fields,
  }) async {
    print('🔵 KYC_REMOTE: Submitting KYC application for level: $levelId');

    try {
      final data = {
        'levelId': levelId,
        'fields': fields,
      };

      final response = await _dioClient.post(
        ApiConstants.submitKycApplication,
        data: data,
      );

      print(
          '🟢 KYC_REMOTE: Submitted KYC application response: ${response.data}');

      // Handle both direct application response and wrapped response
      final applicationData = response.data['application'] ?? response.data;
      return KycApplicationModel.fromJson(applicationData);
    } catch (e) {
      print('🔴 KYC_REMOTE: Error submitting KYC application: $e');
      rethrow;
    }
  }

  @override
  Future<KycApplicationModel> updateKycApplication({
    required String applicationId,
    required Map<String, dynamic> fields,
  }) async {
    print('🔵 KYC_REMOTE: Updating KYC application: $applicationId');

    try {
      final data = {
        'fields': fields,
      };

      final response = await _dioClient.put(
        '${ApiConstants.updateKycApplication}/$applicationId',
        data: data,
      );

      print(
          '🟢 KYC_REMOTE: Updated KYC application response: ${response.data}');

      return KycApplicationModel.fromJson(response.data);
    } catch (e) {
      print('🔴 KYC_REMOTE: Error updating KYC application: $e');
      rethrow;
    }
  }

  @override
  Future<String> uploadKycDocument({
    required String filePath,
    required String fieldId,
    String? applicationId,
  }) async {
    print('🔵 KYC_REMOTE: Uploading KYC document for field: $fieldId');

    try {
      final formData = FormData.fromMap({
        'file': await MultipartFile.fromFile(filePath),
        'fieldId': fieldId,
        if (applicationId != null) 'applicationId': applicationId,
      });

      final response = await _dioClient.post(
        ApiConstants.kycDocumentUpload,
        data: formData,
      );

      print('🟢 KYC_REMOTE: Uploaded KYC document response: ${response.data}');

      // Return the file URL from response
      return response.data['url'] ?? response.data['fileUrl'] ?? '';
    } catch (e) {
      print('🔴 KYC_REMOTE: Error uploading KYC document: $e');
      rethrow;
    }
  }

  @override
  Future<Map<String, dynamic>> getKycStatus() async {
    print('🔵 KYC_REMOTE: Getting KYC status');

    try {
      final response = await _dioClient.get(ApiConstants.kycStatus);
      print('🟢 KYC_REMOTE: Got KYC status response: ${response.data}');

      return response.data as Map<String, dynamic>;
    } catch (e) {
      print('🔴 KYC_REMOTE: Error getting KYC status: $e');
      rethrow;
    }
  }
}
