import 'dart:io';

import 'package:agile_pay/flutter_pay.dart';
import 'package:apple_pay/apple_pay.dart';
import 'package:carousel_slider/carousel_controller.dart';
import 'package:carousel_slider/carousel_options.dart';
import 'package:flutter/cupertino.dart';
import 'package:get/get.dart';
import 'package:injectable/injectable.dart';
import 'package:keyboard/base/base_controller.dart';
import 'package:keyboard/data/api/response/config_response.dart';
import 'package:keyboard/data/bean/pay_way_info.dart';
import 'package:keyboard/data/bean/goods_info.dart';
import 'package:keyboard/data/repository/account_repository.dart';
import 'package:keyboard/data/repository/characters_repository.dart';
import 'package:keyboard/data/repository/store_repository.dart';
import 'package:keyboard/dialog/login/login_dialog.dart';
import 'package:keyboard/dialog/payment_fail_dialog.dart';
import 'package:keyboard/dialog/payment_success_dialog.dart';
import 'package:keyboard/module/store/new_discount/new_discount_page.dart';
import 'package:keyboard/module/store/store_banner_bean.dart';
import 'package:keyboard/module/store/store_user_reviews_bean.dart';
import 'package:keyboard/module/store/subscribe/recover_subscribe_dialog.dart';
import 'package:keyboard/module/store/suprise/surprise_dialog.dart';
import 'package:keyboard/module/store/ticket/discount_ticket_dialog.dart';
import 'package:keyboard/module/store/util/store_goods_countdown_manager.dart';
import 'package:keyboard/utils/async_util.dart';
import 'package:keyboard/utils/atmob_log.dart';
import 'package:keyboard/widget/platform_util.dart';
import 'package:lottie/lottie.dart';

import '../../data/api/response/user_info_response.dart';
import '../../data/bean/member_info.dart';
import '../../data/bean/wechat_payment_sign_bean.dart';
import '../../data/consts/error_code.dart';
import '../../data/consts/event_report.dart';
import '../../data/consts/payment_type.dart';
import '../../data/repository/config_repository.dart';
import '../../dialog/alipay_qr_code_dialog.dart';
import '../../dialog/loading_dialog.dart';
import '../../dialog/member_agreement_dialog.dart';
import '../../dialog/wechat_qr_code_dialog.dart';
import '../../handler/event_handler.dart';
import '../../resource/assets.gen.dart';
import '../../resource/string.gen.dart';
import '../../utils/date_util.dart';
import '../../utils/error_handler.dart';
import '../../utils/http_handler.dart';
import '../../utils/payment_status_manager.dart';
import '../../utils/toast_util.dart';
import '../login/login_page.dart';

@injectable
class StoreController extends BaseController implements PaymentStatusCallback {
  final tag = 'StoreController';

  final StoreRepository storeRepository;

  final AccountRepository accountRepository;

  final PaymentStatusManager paymentStatusManager;

  /// 倒计时管理器
  final StoreGoodsCountdownManager storeGoodsCountdownManager;

  final ConfigRepository configRepository ;

  final RxList<GoodsInfo> goodsInfoList = <GoodsInfo>[].obs;

  final Rxn<GoodsInfo> _selectedGoodsInfoItem = Rxn<GoodsInfo>();

  GoodsInfo? get selectedGoodsInfoItem => _selectedGoodsInfoItem.value;

  final Rxn<PayWayInfo> _selectedPayWay = Rxn<PayWayInfo>();

  PayWayInfo? get selectedPayWay => _selectedPayWay.value;

  final RxList<PayWayInfo> payWayList = <PayWayInfo>[].obs;

  CancelableFuture? _storeDataFuture;

  String? get phone => accountRepository.loginPhoneNum.value;

  bool get isLogin => accountRepository.isLogin.value;

  final isAgree = false.obs;

  MemberInfo? get memberStatusInfo => accountRepository.memberStatusInfo.value;

  UserInfoResponse? get userInfo => accountRepository.userInfo.value;

  // 过滤不同支付的商品
  final RxList<GoodsInfo> filteredGoodsList = <GoodsInfo>[].obs;

  final List<StoreBannerBean> bannerList = [
    StoreBannerBean(
      banner: Assets.images.iconStoreBanner1,
      indicatorImg: Assets.images.iconStoreIndicator1,
      unSelectedDesc: "定制人设",
    ),
    StoreBannerBean(
      banner: Assets.images.iconStoreBanner2,
      indicatorImg: Assets.images.iconStoreIndicator2,
      unSelectedDesc: "追爱助攻",
    ),
    StoreBannerBean(
      banner: Assets.images.iconStoreBanner3,
      indicatorImg: Assets.images.iconStoreIndicator3,
      unSelectedDesc: "自动回复",
    ),
  ];

  final List<StoreUserReviewsBean> userReviewsList = [
    StoreUserReviewsBean(
      avatar: Assets.images.iconStoreUserReview1,
      userName: "执****念",
      userReviews: "用了3天，crush居然主动约我吃饭！AI比我还会撩！",
    ),
    StoreUserReviewsBean(
      avatar: Assets.images.iconStoreUserReview2,
      userName: "过****人",
      userReviews: "之前总把天聊死，现在TA说我‘突然变会说话’了😂",
    ),
    StoreUserReviewsBean(
      avatar: Assets.images.iconStoreUserReview3,
      userName: "不当****solo",
      userReviews: "星座分析超准！按攻略撩天蝎座，他真的一步步上钩了！",
    ),
    StoreUserReviewsBean(
      avatar: Assets.images.iconStoreUserReview4,
      userName: "用户****5476",
      userReviews: "社恐救星！键盘帮我回的消息比我自己发可爱100倍🥰",
    ),
  ];

  final CarouselSliderController carouselSliderController =
      CarouselSliderController();

  final RxInt _currentBanner = 0.obs;

  int get currentBannerIndex => _currentBanner.value;

  /// 商品倒计时，假的倒计时，只会第一个商品会显示
  get goodsCountdown => storeGoodsCountdownManager.currentDuration;

  StoreController(
    this.storeRepository,
    this.accountRepository,
    this.paymentStatusManager,
    this.storeGoodsCountdownManager,
      this.configRepository,
  );

  onBannerChanged(int index, CarouselPageChangedReason reason) {
    _currentBanner.value = index;
  }

  void refreshStoreData() {
    _storeDataFuture?.cancel();
    _storeDataFuture = AsyncUtil.retryWithExponentialBackoff(
      () => _requestGoodsInfoList(),
      4,
    );
    _storeDataFuture?.catchError((error) {
      ErrorHandler.toastError(error);
    });
  }

  Future<void> _requestGoodsInfoList() async {
    try {
      final response = await storeRepository.getGoodsInfoList();
      goodsInfoList.clear();
      payWayList.clear();
      _selectedGoodsInfoItem.value = null;
      if (response.goodsInfoList?.isNotEmpty == true) {
        goodsInfoList.addAll(response.goodsInfoList!);
        _selectedGoodsInfoItem.value = goodsInfoList.first;
      }
      if (response.payInfoList?.isNotEmpty == true) {
        payWayList.addAll(response.payInfoList!);
        _selectedPayWay.value = payWayList.last;
        updateFilteredGoodsList();
      }
    } catch (e) {
      AtmobLog.e(tag, e.toString());
    }
  }

  void updateFilteredGoodsList() {
    if (_selectedPayWay.value == null) {
      return;
    }
    _selectedGoodsInfoItem.value = null;
    int selectedPayWayId = _selectedPayWay.value!.id;
    filteredGoodsList.assignAll(
      goodsInfoList.where((goods) {
        return goods.payOptionIds == null ||
            goods.payOptionIds!.contains(selectedPayWayId);
      }).toList(),
    );
    if (filteredGoodsList.isNotEmpty) {
      _selectedGoodsInfoItem.value = filteredGoodsList.first;
    }
  }

  void onGoodsItemClick(GoodsInfo goodsInfo) {
    _selectedGoodsInfoItem.value = goodsInfo;
    debugPrint("'item: ${goodsInfo.toJson()}");
  }

  void clickPayWaySwitch() {
    if (payWayList.isNotEmpty) {
      int currentIndex = payWayList.indexOf(
        _selectedPayWay.value ?? payWayList.first,
      );
      int nextIndex = (currentIndex + 1) % payWayList.length;
      _selectedPayWay.value = payWayList[nextIndex];
      updateFilteredGoodsList(); // 切换支付方式后，更新商品列表
    }
  }

  void clickBack() {
    EventHandler.report(EventId.event_02005);
    Get.back();
  }

  void clickPayNow() {
    EventHandler.report(EventId.event_02004);
    if (selectedGoodsInfoItem == null) {
      ToastUtil.show(StringName.memberPleaseChoiceGoods);
      return;
    }
    if (selectedPayWay == null) {
      ToastUtil.show(StringName.memberPleaseChoicePayment);
      return;
    }
    if (!isAgree.value) {
      MemberAgreementDialog.show(
        btnConfirm: () {
          isAgree.value = true;
          clickPayNow();
        },
      );
      return;
    }
    AtmobLog.d(tag, 'clickPayNow: ${selectedGoodsInfoItem!.toJson()}');
    final buyGoods = selectedGoodsInfoItem!;
    final buyPayWay = selectedPayWay!;

    int goodsId = buyGoods.id;
    int payPlatform = buyPayWay.payPlatform;
    int payMethod = buyPayWay.payMethod;
    int payWayType = getPayWayType(
      payMethod: payMethod,
      payPlatform: payPlatform,
    );

    LoadingDialog.show(StringName.payLoading);
    storeRepository
        .submitAndRequestPay(
          goodsId: goodsId,
          payPlatform: payPlatform,
          payMethod: payMethod,
        )
        .then((response) {
          if (payWayType == PayWayType.paymentWayWechat) {
            _onWeChatPay(
              response.outTradeNo,
              response.wechatPayPrepayJson!,
              payMethod,
              buyGoods,
              buyPayWay,
            );
          } else if (payWayType == PayWayType.paymentWayWechatScan) {
            _onWechatScanPay(
              response.outTradeNo,
              response.wechatPayQrcodeUrl!,
              buyPayWay,
              buyGoods,
            );
          } else if (payWayType == PayWayType.paymentWayAlipay) {
            _onAliPay(
              response.outTradeNo,
              response.alipayOrderString!,
              payMethod,
              buyGoods,
              buyPayWay,
            );
          } else if (payWayType == PayWayType.paymentWayAlipayScan) {
            _onAliScanPay(
              response.outTradeNo,
              response.alipayQrcodeHtml!,
              buyPayWay,
              buyGoods,
            );
          } else if (payWayType == PayWayType.paymentWayApple) {
            _onApplePay(
              response.outTradeNo,
              response.appAccountToken ?? "",
              buyPayWay,
              buyGoods,
            );
          } else {
            ToastUtil.show(StringName.payNotSupport);
          }
        })
        .catchError((error) {
          LoadingDialog.hide();
          if (error is ServerErrorException) {
            if (error.code == ErrorCode.payOrderError) {
              refreshStoreData();
              ToastUtil.show(error.message);
            } else if (error.code == ErrorCode.noLoginError) {
              ToastUtil.show(StringName.accountNoLogin);
              LoginDialog.show();
            } else {
              ToastUtil.show(error.message);
              paymentFail();
            }
          } else {
            ToastUtil.show(StringName.memberPaymentFailed);
            paymentFail();
          }
        })
        .whenComplete(() {
          if (PlatformUtil.isAndroid) {
            LoadingDialog.hide();
          }
        });
  }

  void paymentFail() {
    PaymentFailDialog.show(
      btnConfirm: () {
        clickPayNow();
      },
    );
  }

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

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

  void _onWeChatPay(
    String outTradeNo,
    String payJson,
    int payMethod,
    GoodsInfo buyGoods,
    PayWayInfo 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,
    PayWayInfo payWayInfo,
    GoodsInfo goodsInfo,
  ) {
    WechatQrCodeDialog.show(
      qrCodeUrl: qrCodeUrl,
      loadSuccessCallback: () {
        checkPaymentStatus(outTradeNo, payWayInfo, goodsInfo);
      },
      onCloseCallback: () async {
        //关闭后再持续查询几秒
        CustomLoadingDialog.show();
        await Future.delayed(Duration(seconds: 4));
        paymentStatusManager.removePollingSubscription(outTradeNo);
        CustomLoadingDialog.hide();
      },
    );
  }

  Future<void> _onApplePay(
      String outTradeNo,
      String appAccountToken,
      PayWayInfo payWayInfo,
      GoodsInfo 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 checkPaymentStatus(
    String orderNo,
    PayWayInfo payWayInfo,
    GoodsInfo goodsInfo, {
    String? receiptData,
  }) {
    paymentStatusManager.registerPaymentSuccessCallback(orderNo, this);
    paymentStatusManager.checkPaymentStatus(
      orderNo,
      payWayInfo,
      goodsInfo,
      receiptData: receiptData,
    );
  }

  void requestSdkPay(
    dynamic payInfo,
    String outTradeNo,
    int payMethod,
    GoodsInfo buyGoods,
    PayWayInfo buyPayWay,
  ) {
    AgilePay.startPay(
      payInfo,
      success: (String? result) {
        LoadingDialog.show(StringName.payQuerypayState);
        checkPaymentStatus(
          outTradeNo,
          buyPayWay,
          buyGoods,
          receiptData: result,
        );
      },
      payError: (int error, String? errorMessage) {
        debugPrint('zk---payError: $error, $errorMessage');
        paymentFail();
        errorPayToast(error);

        errorEventReport(payMethod);
      },
      error: (int errno, String? error) {
        debugPrint('zk---error: $errno, $error');
        errorPayToast(errno);
        errorEventReport(payMethod);
      },
    );
  }

  void errorEventReport(int payMethod) {
    if (payMethod == PayMethod.wechat) {
      // EventHandler.report();
    } else if (payMethod == PayMethod.alipay) {
      // EventHandler.report();
    } else if (payMethod == PayMethod.apple) {
      // EventHandler.report();
    }
  }

  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 onReady() {
    super.onReady();
    EventHandler.report(EventId.event_02003);
    refreshStoreData();
  }

  @override
  void onInit() async {
    super.onInit();
  }

  @override
  void onClose() async {
    super.onClose();
    _storeDataFuture?.cancel();
    paymentStatusManager.unregisterPaymentSuccessCallback(this);
    if (memberStatusInfo != null && memberStatusInfo!.isMember && isLogin) {
      return;
    }
    if (PlatformUtil.isAndroid) {
      SurpriseDialog.show(
        clickConfirm: () {
          NewDiscountPage.start();
        },
        clickCancel: () {},
      );
    }
    if (PlatformUtil.isIOS) {
      DiscountTicketDialog.show(
        clickConfirm: () {
          NewDiscountPage.start();
        },
        clickCancel: () {},
      );
    }
  }

  @override
  void onPaymentSuccess(
    String orderNo,
    PayWayInfo payWayInfo,
    GoodsInfo goodsInfo,
  ) {

    if (PlatformUtil.isIOS) {
      accountRepository.refreshUserInfo();
      // 300ms后关闭弹窗
      Future.delayed(Duration(seconds: 2), () {
        LoadingDialog.hide();
        Get.back();
        PaymentSuccessDialog.show(
          goodsInfo: goodsInfo,
          btnConfirm: () {
            AtmobLog.d(tag, 'onGoodsItemClick: ${goodsInfo.toJson()}');
          },
        );
      });
    } else {
      LoadingDialog.hide();
      Get.back();
      PaymentSuccessDialog.show(
        goodsInfo: goodsInfo,
        btnConfirm: () {
          AtmobLog.d(tag, 'onGoodsItemClick: ${goodsInfo.toJson()}');
        },
      );
    }
  }

  @override
  void onPaymentError(Error error) {
    // TODO: implement onPaymentError
    if (PlatformUtil.isIOS) {
      LoadingDialog.hide();
      ErrorHandler.toastError(error);
    }
  }

  String getUserName() {
    if (isLogin && phone != null && phone!.length > 4) {
      return '${StringName.mineAccountLoggedDesc}${phone!.substring(phone!.length - 4)}';
    } else {
      return "";
    }
  }

  /// 点击了恢复订阅
  Future<void> clickRecoverSubscribe() async {
    PayWayInfo? paymentWay = _selectedPayWay.value;
    if (paymentWay == null) {
      return;
    }
    int payPlatform = paymentWay.payPlatform;
    int payMethod = paymentWay.payMethod;

    CustomLoadingDialog.show();

    Future.delayed(const Duration(seconds: 20), () {
      CustomLoadingDialog.hide();
      ToastUtil.show("没有发现可恢复的记录");
    });

    final result = await ApplePay().restore();
    if (result["success"] == true) {
      // CustomLoadingDialog.hide();
      var receipt = result['receipt'];
      print('查找恢复记录成功: ${result['receipt']}');
      checkRestoreStatus(receipt);
    } else {
      CustomLoadingDialog.hide();
      ToastUtil.show("恢复失败");
      print('恢复失败: ${result['error']}');
    }

    // 显示恢复订阅弹窗
    // RecoverSubscribeDialog.show("周会员2025年3月6日到期。", () {
    //   AtmobLog.d(tag, "恢复订阅弹窗 => 点击确认");
    // });
  }

  /// 检查恢复订阅结果
  Future<void> checkRestoreStatus(String? receiptData) async {
    PayWayInfo? paymentWay = _selectedPayWay.value;
    if (paymentWay == null) {
      // ToastUtil.showToast(StringName.storeChoicePayment.tr);
      return;
    }
    if (receiptData == null) {
      return;
    }
    int payPlatform = paymentWay.payPlatform;
    int payMethod = paymentWay.payMethod;
    // var code = await storeRepository.resume(payPlatform, payMethod, receiptData);
    storeRepository
        .subscribeResume(payPlatform, payMethod, receiptData)
        .then((data) {
          CustomLoadingDialog.hide();
          ToastUtil.show("恢复成功");
          accountRepository.getUserInfo();
          Get.back();
        })
        .catchError((error) {
          CustomLoadingDialog.hide();
          ToastUtil.show("恢复失败");
        });

    // if (code == 0) {
    //   CustomLoadingDialog.hide();
    //   ToastUtil.show("Restore success");
    //   userRepository.getUserInfo();
    //   Get.back();
    // } else {
    //   CustomLoadingDialog.hide();
    //   ToastUtil.show("Restore fail");
    // }
  }
}
