import 'dart:developer';
import 'package:dio/dio.dart';
import 'package:kmobile/core/errors/exceptions.dart';
import 'package:kmobile/data/models/ifsc.dart';
import 'package:kmobile/data/models/beneficiary.dart';

class BeneficiaryService {
  final Dio _dio;

  BeneficiaryService(this._dio);

  Future<String> validateBeneficiaryWithinBank(String accountNumber) async {
    try {
      final response = await _dio
          .get('/api/beneficiary/validate/within-bank', queryParameters: {
        'accountNumber': accountNumber,
      });

      if (response.statusCode == 200) {
        return response.data['name'];
      } else {
        throw Exception(
            response.data['error'] ?? 'Failed to validate beneficiary');
      }
    } on DioException catch (e) {
      throw Exception('Network error: ${e.message}');
    } catch (e) {
      throw Exception('Unexpected error: ${e.toString()}');
    }
  }

  Future<Ifsc> validateIFSC(String ifscCode) async {
    try {
      final response = await _dio.get('/api/beneficiary/ifsc-details',
          queryParameters: {"ifscCode": ifscCode});

      if (response.statusCode == 200) {
        return Ifsc.fromJson(response.data);
      }
    } on DioException catch (e) {
      if (e.response?.statusCode == 404) {
        throw Exception('INVALID IFSC CODE');
      } else if (e.response?.statusCode == 401) {
        throw Exception('INVALID IFSC CODE');
      }
    } catch (e) {
      throw UnexpectedException(
          'Unexpected error during login: ${e.toString()}');
    }
    return Ifsc.fromJson({});
  }

  Future<String> validateBeneficiary({
    required String accountNo,
    required String ifscCode,
    required String remitterName,
  }) async {
    log('inside validate beneficiary service');
    final response = await _dio.get(
      '/api/beneficiary/validate/outside-bank',
      queryParameters: {
        'accountNo': accountNo,
        'ifscCode': ifscCode,
        'remitterName': remitterName,
      },
      options: Options(
        sendTimeout: const Duration(seconds: 60),
        receiveTimeout: const Duration(seconds: 60),
      ),
    );
    if (response.statusCode != 200) {
      throw Exception("Invalid Beneficiary Details");
    }
    return response.data['name'];
  }

  // Beneficiary Validate And ADD
  Future<bool> sendForValidation(Beneficiary beneficiary) async {
    try {
      final response = await _dio.post(
        '/api/beneficiary',
        data: beneficiary.toJson(),
      );

      if (response.statusCode == 200) {
        return true;
      } else {
        return false;
      }
    } catch (e) {
      rethrow;
    }
  }

  Future<List<Beneficiary>> fetchBeneficiaryList() async {
    try {
      final response = await _dio.get(
        "/api/beneficiary",
        options: Options(
          headers: {
            "Content-Type": "application/json",
          },
        ),
      );

      if (response.statusCode == 200) {
        return Beneficiary.listFromJson(response.data);
      } else {
        throw Exception("Failed to fetch beneficiaries");
      }
    } catch (e) {
      return [];
    }
  }

  Future<void> deleteBeneficiary(String accountNo) async {
    try {
      final response = await _dio.delete('/api/beneficiary/$accountNo');

      if (response.statusCode != 204) {
        throw Exception('Failed to delete beneficiary');
      }
    } on DioException catch (e) {
      throw Exception('Network error: ${e.message}');
    } catch (e) {
      throw Exception('Unexpected error: ${e.toString()}');
    }
  }

  Future<Response> updateLimit({
    required String beneficiaryAccountNo,
    required String newLimit,
  }) async {
    log('inside update limit of beneficiary service');
    final response = await _dio.patch(
      '/api/beneficiary/update-limit',
      data: {
        'beneficiaryAccountNo': beneficiaryAccountNo,
        'newLimit': int.tryParse(newLimit),
      },
      options: Options(
        sendTimeout: const Duration(seconds: 60),
        receiveTimeout: const Duration(seconds: 60),
      ),
    );
    if (response.statusCode != 200) {
      throw Exception("INTERNAL SERVER ERROR");
    }
    return response;
  }
}
