import 'package:amazon_payfort/amazon_payfort.dart';
import 'package:flutter/material.dart';
import 'package:hmg_patient_app_new/core/api_consts.dart';
import 'package:hmg_patient_app_new/features/payfort/models/apple_pay_request_insert_model.dart';
import 'package:hmg_patient_app_new/features/payfort/models/payfort_check_payment_status_response_model.dart';
import 'package:hmg_patient_app_new/features/payfort/models/payfort_project_details_resp_model.dart';
import 'package:hmg_patient_app_new/features/payfort/models/sdk_token_response_model.dart';
import 'package:hmg_patient_app_new/features/payfort/payfort_repo.dart';
import 'package:hmg_patient_app_new/services/error_handler_service.dart';
import 'package:network_info_plus/network_info_plus.dart';

class PayfortViewModel extends ChangeNotifier {
  PayfortRepo payfortRepo;
  ErrorHandlerService errorHandlerService;

  bool isApplePayConfigurationLoading = false;

  PayfortProjectDetailsRespModel? payfortProjectDetailsRespModel;
  PayfortCheckPaymentStatusResponseModel? payfortCheckPaymentStatusResponseModel;
  late AmazonPayfort _payfort;
  final NetworkInfo _info = NetworkInfo();

  PayfortViewModel({required this.payfortRepo, required this.errorHandlerService});

  setIsApplePayConfigurationLoading(bool value) {
    isApplePayConfigurationLoading = value;
    notifyListeners();
  }

  initPayfortViewModel() async {
    _payfort = AmazonPayfort.instance;
    await AmazonPayfort.initialize(
      PayFortOptions(environment: ApiConsts.payFortEnvironment),
    );
    notifyListeners();
  }

  Future<void> getPayfortConfigurations({int? serviceId, int? projectId, int integrationId = 2, Function(dynamic)? onSuccess, Function(String)? onError}) async {
    final result = await payfortRepo.getPayfortConfigurations(serviceId: serviceId, projectId: projectId, integrationId: integrationId);

    result.fold(
      (failure) async => await errorHandlerService.handleError(failure: failure),
      (apiResponse) {
        if (apiResponse.messageStatus == 2) {
          // dialogService.showErrorDialog(message: apiResponse.errorMessage!, onOkPressed: () {});
        } else if (apiResponse.messageStatus == 1) {
          payfortProjectDetailsRespModel = apiResponse.data!;
          // isApplePayConfigurationLoading = false;
          notifyListeners();
          if (onSuccess != null) {
            onSuccess(apiResponse);
          }
        }
      },
    );
  }

  Future<void> applePayRequestInsert({required ApplePayInsertRequest applePayInsertRequest, Function(dynamic)? onSuccess, Function(String)? onError}) async {
    final result = await payfortRepo.applePayRequestInsert(applePayInsertRequest: applePayInsertRequest);

    result.fold(
      (failure) async => await errorHandlerService.handleError(failure: failure),
      (apiResponse) {
        if (apiResponse.messageStatus == 2) {
          // dialogService.showErrorDialog(message: apiResponse.errorMessage!, onOkPressed: () {});
        } else if (apiResponse.messageStatus == 1) {
          // payfortProjectDetailsRespModel = apiResponse.data!;
          notifyListeners();
          if (onSuccess != null) {
            onSuccess(apiResponse);
          }
        }
      },
    );
  }

  Future<void> checkPaymentStatus({required String transactionID, Function(dynamic)? onSuccess, Function(String)? onError}) async {
    final result = await payfortRepo.checkPaymentStatus(transactionID: transactionID);

    result.fold(
      (failure) async => await errorHandlerService.handleError(failure: failure),
      (apiResponse) {
        if (apiResponse.messageStatus == 2) {
          // dialogService.showErrorDialog(message: apiResponse.errorMessage!, onOkPressed: () {});
        } else if (apiResponse.messageStatus == 1) {
          payfortCheckPaymentStatusResponseModel = apiResponse.data!;
          notifyListeners();
          if (onSuccess != null) {
            onSuccess(apiResponse);
          }
        }
      },
    );
  }

  Future<SdkTokenResponse?> _generateSdkResponse({
    String? applePayAccessCode,
    String? merchantIdentifier,
    String? applePayShaType,
    String? applePayShaRequestPhrase,
  }) async {
    try {
      String? deviceId = await _payfort.getDeviceId();

      /// Step 2:  Generate the Signature
      SdkTokenRequest tokenRequest = SdkTokenRequest(
        accessCode: applePayAccessCode!,
        deviceId: deviceId ?? '',
        merchantIdentifier: merchantIdentifier!,
      );

      String? signature = await _payfort.generateSignature(
        shaType: applePayShaType!,
        concatenatedString: tokenRequest.toConcatenatedString(applePayShaRequestPhrase!),
      );

      tokenRequest = tokenRequest.copyWith(signature: signature);

      /// Step 3: Generate the SDK Token
      final result = await payfortRepo.generateSdkSignatureFromAPI(tokenRequest: tokenRequest);
      result.fold(
        (failure) async => await errorHandlerService.handleError(failure: failure),
        (apiResponse) {
          if (apiResponse.messageStatus == 2) {
            // dialogService.showErrorDialog(message: apiResponse.errorMessage!, onOkPressed: () {});
          } else if (apiResponse.messageStatus == 1) {
            // payfortProjectDetailsRespModel = apiResponse.data!;
            isApplePayConfigurationLoading = false;
            notifyListeners();
          }
        },
      );
    } catch (e) {
      print("Error here: ${e.toString()}");
    }
    return null;
  }

  Future<void> paymentWithApplePay({
    SucceededCallback? onSucceeded,
    FailedCallback? onFailed,
    String? customerName,
    String? customerEmail,
    String? orderDescription,
    num? orderAmount,
    String? merchantIdentifier,
    String? applePayAccessCode,
    String? applePayShaRequestPhrase,
    String? merchantReference,
    String currency = "SAR",
    String applePayShaType = "SHA-256",
    String countryIsoCode = "SA",
  }) async {
    try {
      SdkTokenResponse? sdkTokenResponse = await _generateSdkResponse(
        applePayAccessCode: applePayAccessCode,
        merchantIdentifier: merchantIdentifier,
        applePayShaType: applePayShaType,
        applePayShaRequestPhrase: applePayShaRequestPhrase,
      );

      if (sdkTokenResponse != null && sdkTokenResponse.sdkToken == null) {
        onFailed!((sdkTokenResponse.responseMessage ?? '') as PayFortFailureResult);
        return;
      }

      /// Step 4: Processing Payment [Don't multiply with 100]
      /// Amount value send always round ex. [100] not [100.00, 100.21]
      FortRequest request = FortRequest(
          command: FortCommand.purchase,
          amount: orderAmount!,
          customerName: customerName!,
          customerEmail: customerEmail!,
          // orderDescription: orderDescription!,
          orderDescription: "Dr. Sulaiman Al Habib Hospital",
          sdkToken: sdkTokenResponse?.sdkToken ?? '',
          merchantReference: merchantReference!,
          currency: currency,
          customerIp: (await _info.getWifiIP() ?? ''),
          language: 'en');

      isApplePayConfigurationLoading = false;
      notifyListeners();

      _payfort.callPayFortForApplePay(
        request: request,
        countryIsoCode: countryIsoCode,
        applePayMerchantId: ApiConsts.applePayMerchantId,
        callback: ApplePayResultCallback(
          onSucceeded: onSucceeded!,
          onFailed: onFailed!,
        ),
      );
    } catch (e) {
      onFailed!(e.toString() as PayFortFailureResult);
    }
  }
}
