import 'dart:io';

import 'package:agile_pay/flutter_pay.dart';
import 'package:apple_pay/apple_pay.dart';
import 'package:flutter/cupertino.dart';
import 'package:flutter_screenutil/flutter_screenutil.dart';
import 'package:get/get.dart';
import 'package:get/get_core/src/get_main.dart';
import 'package:injectable/injectable.dart';
import 'package:location/data/bean/goods_bean.dart';
import 'package:location/data/bean/pay_item_bean.dart';
import 'package:location/data/repositories/member_repository.dart';
import 'package:location/utils/common_expand.dart';

import '../data/api/response/request_pay_response.dart';
import '../data/bean/wechat_payment_sign_bean.dart';
import '../data/consts/channel_id.dart';
import '../data/consts/error_code.dart';
import '../data/consts/payment_type.dart';
import '../data/repositories/account_repository.dart';
import '../device/atmob_platform_info.dart';
import '../dialog/alipay_qr_code_dialog.dart';
import '../dialog/common_confirm_dialog.dart';
import '../dialog/loading_dialog.dart';
import '../dialog/wechat_qr_code_dialog.dart';
import '../module/login/login_page.dart';
import '../resource/string.gen.dart';
import '../utils/http_handler.dart';
import '../utils/payment_status_manager.dart';
import '../utils/toast_util.dart';

@lazySingleton
class MemberPayHelper implements PaymentStatusCallback {
  final PaymentStatusManager paymentStatusManager;
  final MemberRepository memberRepository;

  MemberPayHelper(this.paymentStatusManager, this.memberRepository);

  Future<void> launchPay(GoodsBean? bean, PayItemBean? payWay) async {
    if (bean == null) {
      ToastUtil.show(StringName.memberPleaseChoiceGoods);
      return;
    }
    if (payWay == null) {
      ToastUtil.show(StringName.memberPleaseChoicePayment);
      return;
    }
    memberRepository.setLastSelectedMember(bean, payWay);
    //增加渠道登录判断
    if (Platform.isAndroid && atmobPlatformInfo.tgPlatform == ChannelId.sd) {
      if (!AccountRepository.getInstance().isLogin.value) {
        ToastUtil.show(StringName.accountNoLogin);
        final isLogin = await LoginPage.start();
        if (!isLogin) {
          return;
        }
      }
    }

    int goodsId = bean.id;
    int payPlatform = payWay!.payPlatform;
    int payMethod = payWay.payMethod;

    LoadingDialog.show(StringName.payLoading,
        backDismiss: true, clickMaskDismiss: true);
    try {
      final RequestPayResponse response = await MemberRepository.getInstance()
          .submitAndRequestPay(
              goodsId: goodsId, payPlatform: payPlatform, payMethod: payMethod);
      int payWayType =
          getPayWayType(payMethod: payMethod, payPlatform: payPlatform);
      if (payWayType == PayWayType.paymentWayWechat) {
        _onWeChatPay(response.outTradeNo, response.wechatPayPrepayJson!,
            payMethod, bean, payWay);
      } else if (payWayType == PayWayType.paymentWayWechatScan) {
        _onWechatScanPay(
            response.outTradeNo, response.wechatPayQrcodeUrl!, payWay, bean);
      } else if (payWayType == PayWayType.paymentWayAlipay) {
        _onAliPay(response.outTradeNo, response.alipayOrderString!, payMethod,
            bean, payWay);
      } else if (payWayType == PayWayType.paymentWayAlipayScan) {
        _onAliScanPay(
            response.outTradeNo, response.alipayQrcodeHtml!, payWay, bean);
      } else if (payWayType == PayWayType.paymentWayApple) {
        _onApplePay(
            response.outTradeNo, response.appAccountToken ?? "", payWay, bean);
      } else {
        LoadingDialog.hide();
        ToastUtil.show(StringName.payNotSupport);
      }
    } catch (error) {
      LoadingDialog.hide();
      if (error is ServerErrorException) {
        if (error.code == ErrorCode.payOrderError) {
          ToastUtil.show(error.message);
        } else if (error.code == ErrorCode.noLoginError) {
          ToastUtil.show(StringName.accountNoLogin);
          LoginPage.start();
        } else {
          ToastUtil.show(error.message);
        }
      } else {
        ToastUtil.show(StringName.memberPaymentFailed);
      }
      rethrow;
    }
  }

  Future<void> _onApplePay(
    String outTradeNo,
    String appAccountToken,
    PayItemBean payWayInfo,
    GoodsBean goodsInfo,
  ) async {
    final result = await ApplePay().purchase(
      productId: goodsInfo.appleGoodsId ?? "",
      appAccountToken: appAccountToken,
    );
    if (result["success"] == true) {
      var receipt = result['receipt'];
      print('购买成功: ${result['receipt']}');
      checkPaymentStatus(
        outTradeNo,
        payWayInfo,
        goodsInfo,
        receiptData: receipt,
      );
    } else {
      LoadingDialog.hide();
      ToastUtil.show("支付失败，请稍后重试");
      print('购买失败: ${result['error']}');
    }
  }

  void _onAliScanPay(String outTradeNo, String qrHtml, PayItemBean paymentWay,
      GoodsBean goodsBean) {
    LoadingDialog.hide();
    AlipayQrCodeDialog.show(
        qrCodeHtml: qrHtml,
        loadSuccessCallback: () {
          checkPaymentStatus(outTradeNo, paymentWay, goodsBean);
        },
        onCloseCallback: () async {
          //关闭后再持续查询几秒
          CustomLoadingDialog.show();
          await Future.delayed(Duration(seconds: 4));
          paymentStatusManager.removePollingSubscription(outTradeNo);
          CustomLoadingDialog.hide();
        });
  }

  void _onAliPay(String outTradeNo, String payJson, int payMethod,
      GoodsBean buyGoods, PayItemBean buyPayWay) {
    final payInfo = AliPayInfo(payJson);
    requestSdkPay(payInfo, outTradeNo, payMethod, buyGoods, buyPayWay);
  }

  void _onWeChatPay(String outTradeNo, String payJson, int payMethod,
      GoodsBean buyGoods, PayItemBean buyPayWay) {
    final bean = WechatPaymentSignBean.stringToBean(payJson);
    final payInfo = WechatPayInfo(
        appId: bean.appId,
        partnerId: bean.partnerId,
        prepayId: bean.prepayId,
        package: bean.package,
        noncestr: bean.nonceStr,
        timestamp: bean.timeStamp,
        sign: bean.sign);
    requestSdkPay(payInfo, outTradeNo, payMethod, buyGoods, buyPayWay);
  }

  void _onWechatScanPay(String outTradeNo, String qrCodeUrl,
      PayItemBean paymentWay, GoodsBean goodsBean) {
    LoadingDialog.hide();
    WechatQrCodeDialog.show(
        qrCodeUrl: qrCodeUrl,
        loadSuccessCallback: () {
          checkPaymentStatus(outTradeNo, paymentWay, goodsBean);
        },
        onCloseCallback: () async {
          //关闭后再持续查询几秒
          CustomLoadingDialog.show();
          await Future.delayed(Duration(seconds: 4));
          paymentStatusManager.removePollingSubscription(outTradeNo);
          CustomLoadingDialog.hide();
        });
  }

  void requestSdkPay(dynamic payInfo, String outTradeNo, int payMethod,
      GoodsBean buyGoods, PayItemBean buyPayWay) {
    AgilePay.startPay(payInfo, success: (String? result) {
      checkPaymentStatus(outTradeNo, buyPayWay, buyGoods, receiptData: result);
    }, payError: (int errno, String? errorMessage) {
      LoadingDialog.hide();
      debugPrint('MemberPayHelper---payError: $errno, $errorMessage');
      errorPayToast(errno);
    }, error: (int errno, String? error) {
      LoadingDialog.hide();
      debugPrint('MemberPayHelper---error: $errno, $error');
      errorPayToast(errno);
    });
  }

  void checkPaymentStatus(
      String orderNo, PayItemBean paymentWay, GoodsBean goodsBean,
      {String? receiptData}) {
    LoadingDialog.show(StringName.payQuerypayState);
    paymentStatusManager.registerPaymentSuccessCallback(orderNo, this);
    paymentStatusManager.checkPaymentStatus(orderNo, paymentWay, goodsBean,
        receiptData: receiptData);
  }

  void errorPayToast(int errno) {
    if (errno == AgilePayCode.payCodeNotSupport) {
      ToastUtil.show(StringName.payNotSupport);
    } else if (errno == AgilePayCode.payCodeCancelError) {
      ToastUtil.show(StringName.payUserCancel);
    } else if (errno == AgilePayCode.payCodeWxEnvError) {
      ToastUtil.show(StringName.payWxEvnError);
    } else if (errno == AgilePayCode.payCodeNotConnectStore) {
      ToastUtil.show(StringName.payNotConnectStore);
    } else {
      ToastUtil.show(StringName.payError);
    }
  }

  @override
  void onPaymentFail() {
    LoadingDialog.hide();
  }

  @override
  void onPaymentSuccess(
      String orderNo, PayItemBean paymentWay, GoodsBean storeItemBean) {
    ///购买成功消失
    LoadingDialog.hide();
    memberRepository.clearLastSelectedMember();

    ///购买成功之后弹出
    onPaySucessShow();
  }

  void onPaySucessShow() {
    try {
      WechatQrCodeDialog.dismiss();
      AlipayQrCodeDialog.dismiss();
      CustomLoadingDialog.hide();
      LoadingDialog.hide();
    } catch (e) {
      debugPrint('zk---onPaymentSuccess error: $e');
    }
    showPaymentSuccessDialog(onConfirm: () {
      if (Get.key.currentState?.canPop() ?? false) {
        Get.back();
      }
    }, onCancel: () {
      if (Get.key.currentState?.canPop() ?? false) {
        Get.back();
      }
    });
  }

  void showPaymentSuccessDialog(
      {required VoidCallback onConfirm, required VoidCallback onCancel}) {
    CommonConfirmDialog.show(
        backDismiss: false,
        clickMaskDismiss: false,
        titleWidget: Text(StringName.paySuccessTitle,
            style: TextStyle(
                fontSize: 17.sp,
                color: '#333333'.color,
                fontWeight: FontWeight.bold)),
        descWidget: Text(
          StringName.paySuccessDesc,
          style: TextStyle(fontSize: 14.sp, color: '#404040'.color),
        ),
        confirmText: StringName.dialogSure,
        cancelOnTap: onCancel,
        confirmOnTap: onConfirm);
  }
}
