import { createOrder, getEcardPrices, queryOrder } from "@/api/modules/pay";
import { useEnv } from "./useEnv";
import { usePayStore } from "@/store/payStore";
import config from "@/config";
import type { Pay } from "@/types";

export const usePay = () => {
  const { isH5, isWap2App, isMP } = useEnv();
  const payStore = usePayStore();
  const { price } = storeToRefs(payStore);
  const ready = ref(false);
  const loading = ref(false);
  const outTradeNo = ref('');
  const h5url = ref('');
  const queryTimes = ref(10);
  const callback = ref<Pay.OrderPayCallback>({});
  let webview: PlusWebviewWebviewObject | HTMLIFrameElement | undefined = undefined;

  const payType = computed(() => {
    if (isH5.value || isWap2App.value) {
      return undefined;
    } else if (isMP.value) {
      return 'jsapi'; // ???
    }
  });

  const formatPrice = computed(() => {
    return price.value / 100;
  });
  const getPrice = async () => {
    const res = await getEcardPrices({});
    const card = res.data?.at(0);
    if (card) {
      payStore.setPrice(card.price)
      ready.value = true;
    }
  }
  const pay = async () => {
    loading.value = true;
    uni.$ie.showLoading('支付中...');
    try {
      const { data } = await createOrder({
        totalFee: price.value,
        type: payType.value
      });
      loading.value = false;
      uni.$ie.hideLoading();
      outTradeNo.value = data.outTradeNo;
      const no = outTradeNo.value.split('_')[1];
      if (no) {
        payStore.setOrderId(Number(no));
      }
      if (isH5.value || isWap2App.value) {
        h5url.value = data.h5url;
        if (outTradeNo && h5url) {
          clearResultFrame()
          webview = await createResultFrame(h5url.value);
        } else {
          throw new Error('支付地址缺失');
        }
      } else if (isMP.value) {
        if (data.wcPayData) {
          const payJson = JSON.parse(data.wcPayData);
          uni.requestPayment({
            provider: "wxpay",
            orderInfo: {},
            nonceStr: payJson.nonceStr,
            package: payJson.packageValue,
            paySign: payJson.paySign,
            timeStamp: payJson.timeStamp,
            signType: payJson.signType,
            success(res) {
              checkOrderStatus();
            },
            fail(e) {
              uni.$ie.showToast('支付失败');
              payStore.setOrderId(null);
            }
          })
        } else {
          throw new Error('缺少支付参数');
        }
      }
    } catch (error) {
      console.error(error);
      loading.value = false;
      uni.$ie.showToast('下单失败，请稍后再试');
    }
  }

  const queryPayStatus = () => {
    if (payStore.orderId) {
      return queryOrderStatus(payStore.orderId + '')
    }
    return null;
  }

  const queryOrderStatus = async (orderId: string) => {
    try {
      const { data } = await queryOrder(orderId);
      if (!data) {
        return null;
      }
      return data;
    } catch (error) {
      return null;
    }
  }
  const checkOrderStatus = async () => {
    const no = payStore.orderId;
    if (no == null) {
      return;
    }
    let queryCount = 0; // 当前查询次数
    const queryInterval = 3000; // 查询间隔（毫秒）
    let timerId: ReturnType<typeof setTimeout> | null = null;

    /**
     * 停止查询
     */
    const stopQuery = () => {
      if (timerId) {
        clearTimeout(timerId);
        timerId = null;
        clearResultFrame();
      }
      loading.value = false;
      uni.$ie.hideLoading();
    };

    /**
     * 执行查询
     */
    const query = async () => {
      try {
        queryCount++;
        const data = await queryOrderStatus(no + '');
        console.log(`checkOrderStatus: 第 ${queryCount} 次查询订单状态`);
        console.log(JSON.stringify(data))
        if (!data) {
          console.error('checkOrderStatus: 查询结果为空');
          stopQuery();
          callback.value.onFailed?.();
          return;
        }

        // 支付成功
        if (data.isPaySuccess) {
          console.log('checkOrderStatus: 支付成功');
          stopQuery();
          callback.value.onSuccess?.();
          return;
        }

        // 支付失败
        if (data.isPayFailed) {
          console.log('checkOrderStatus: 支付失败');
          stopQuery();
          callback.value.onFailed?.();
          return;
        }

        // 未支付状态
        if (data.isUnPaid) {
          // 如果已达到最大查询次数，回调失败
          if (queryCount >= queryTimes.value) {
            console.log(`checkOrderStatus: 已查询 ${queryTimes.value} 次，仍未支付，回调失败`);
            stopQuery();
            callback.value.onFailed?.();
            return;
          }

          // 继续查询
          timerId = setTimeout(() => {
            query();
          }, queryInterval);
        } else {
          // 未知状态，回调失败
          console.error('checkOrderStatus: 未知的支付状态', data);
          stopQuery();
          callback.value.onFailed?.();
        }
      } catch (error) {
        // 查询过程中发生错误，回调失败
        console.error('checkOrderStatus: 查询订单状态失败', error);
        stopQuery();
        callback.value.onFailed?.();
      }
    };

    // 开始第一次查询
    uni.$ie.showLoading('支付查询中...')
    query();
  }

  const createResultFrame = async (url: string) => {
    if (isH5.value) {
      await sleep()
      const iframe = document.createElement('iframe');
      const style = `width:0px;height:0px;position: absolute;opacity: 0;z-index: -1;outline:none;border:none;`;
      iframe.setAttribute('style', style);
      iframe.setAttribute('sandbox', 'allow-scripts allow-top-navigation allow-same-origin');
      iframe.style.position = 'absolute';
      iframe.src = url;
      iframe.onload = () => checkOrderStatus()
      iframe.onerror = () => console.error('Payment: iframe加载失败')
      document.body.appendChild(iframe);
      return iframe
    } else if (isWap2App.value) {
      const style: PlusWebviewWebviewStyles = {
        webviewBGTransparent: true,
        opacity: 0,
        render: 'always',
        zindex: -1,
        width: '1px',
        height: '1px',
        top: '0px',
        left: '0px',
        additionalHttpHeaders: {
          Referer: config.paySiteUrl,
        }
      };
      const wv = plus.webview.create(url, 'wechatPayWebview', style);
      wv.addEventListener('loaded', (e) => {
        checkOrderStatus();
      }, false);
      wv.show();
      return wv;
    }
  }

  const clearResultFrame = () => {
    const { isH5, isWap2App } = useEnv();
    if (webview) {
      if (isH5.value) {
        document.body.removeChild(webview as HTMLIFrameElement)
      } else if (isWap2App.value) {
        (webview as PlusWebviewWebviewObject).close();
      }
      webview = undefined;
    }
  }

  const sleep = (time: number = 300) => {
    return new Promise(resolve => {
      setTimeout(resolve, time);
    });
  }

  const setCallback = (cb: Pay.OrderPayCallback) => {
    callback.value = cb;
  }

  return {
    getPrice,
    price,
    formatPrice,
    ready,
    pay,
    loading,
    setCallback,
    queryPayStatus
  }
}