<template>
  <!-- 支付加载提示 -->
  <view v-if="showPayLoading" class="pay-loading-mask">
    <view class="pay-loading-box">
      <view class="loading-spinner"></view>
      <text class="loading-text">处理支付中...</text>
    </view>
  </view>
</template>

<script setup>
import { ref, getCurrentInstance } from "vue";
import { createPaymentOrder, queryPaymentStatus } from "@/api/payment";
import { generateCustomId } from "@/utils/util.js";

// 组件实例
const instance = getCurrentInstance();

// 状态管理
const orderNo = ref("");
const orderId = ref("");
const showPayLoading = ref(false);
const paymentInProgress = ref(false);

// 回调函数存储
const callbacks = ref({
  onUniPayCreate: null,
  onUniPaySuccess: null,
  onUniPayCancel: null,
  onUniPayFail: null,
});

/**
 * 发起微信支付
 * @param {Object} options - 支付参数
 * @param {number} options.amount - 支付金额(分)
 * @param {string} options.description - 商品描述
 * @param {string} options.openId - 用户openId
 * @param {string} options.orderPrefix - 订单号前缀
 * @param {string} options.orderNo - 订单号
 * @param {Function} options.onUniPayCreate - 订单创建成功回调
 * @param {Function} options.onUniPaySuccess - 支付成功回调
 * @param {Function} options.onUniPayCancel - 取消支付回调
 * @param {Function} options.onUniPayFail - 支付失败回调
 */
const createUniPay = async (options) => {
  // 防止重复发起支付
  if (paymentInProgress.value) return;

  try {
    paymentInProgress.value = true;
    showPayLoading.value = true;

    // 保存回调函数
    Object.keys(callbacks.value).forEach((key) => {
      callbacks.value[key] =
        options[key] && typeof options[key] === "function"
          ? options[key]
          : () => {};
    });

    if (options.orderNo) {
      // 若传入订单号则使用传入的订单号
      orderNo.value = options.orderNo;
    } else {
      // 生成订单号（使用公共组件）
      orderNo.value = generateCustomId(options.orderPrefix || "WX_");
    }

    // 调用后端创建支付订单
    const { data: payRes } = await createPaymentOrder({
      amount: options.amount,
      description: options.description,
      openId: options.openId,
      orderNo: orderNo.value,
    });
    // return console.log("payRes", payRes);
    // 订单创建成功，触发回调
    callbacks.value.onUniPayCreate({
      out_trade_no: options.orderNo,
      ...payRes,
    });

    // 调起微信支付
    await uni.requestPayment({
      provider: "wxpay",
      timeStamp: payRes.timeStamp.toString(),
      nonceStr: payRes.nonceStr,
      package: payRes.package,
      signType: payRes.signType,
      paySign: payRes.paySign,
      success: () => {
        confirmPaymentStatus();
      },
      fail: (err) => {
        showPayLoading.value = false;
        paymentInProgress.value = false;
        if (err.errMsg && err.errMsg.includes("cancel")) {
          callbacks.value.onUniPayCancel(err);
        } else {
          callbacks.value.onUniPayFail(err);
        }
      },
    });
  } catch (err) {
    showPayLoading.value = false;
    paymentInProgress.value = false;
    console.error("支付流程异常:", err);
    callbacks.value.onUniPayFail(err);
  }
};

/**
 * 确认支付状态（轮询查询）
 */
const confirmPaymentStatus = async () => {
  try {
    let checkCount = 0;
    const maxCheckCount = 10; // 最多查询10次
    const checkInterval = 1000; // 每次查询间隔1秒

    const checkStatus = async () => {
      // 超过最大查询次数，视为超时
      if (checkCount >= maxCheckCount) {
        showPayLoading.value = false;
        paymentInProgress.value = false;
        callbacks.value.onUniPayFail(
          new Error("支付结果查询超时，请稍后查看订单状态")
        );
        return;
      }

      checkCount++;

      try {
        // 查询支付状态
        const res = await queryPaymentStatus(orderNo.value);
        // 根据后端返回的支付状态进行处理
        if (res.code === 200) {
          showPayLoading.value = false;
          paymentInProgress.value = false;
          callbacks.value.onUniPaySuccess({
            ...res.data,
            out_trade_no: orderNo.value,
          });
        }
      } catch (err) {
        // 查询接口出错，重试
        console.error(`第${checkCount}次查询支付状态失败:`, err);
        setTimeout(checkStatus, checkInterval);
      }
    };

    // 开始第一次查询
    checkStatus();
  } catch (err) {
    showPayLoading.value = false;
    paymentInProgress.value = false;
    console.error("确认支付状态异常:", err);
    callbacks.value.onUniPayFail(err);
  }
};

// 对外暴露方法
defineExpose({
  createUniPay,
});
</script>

<style scoped>
/* 支付加载提示样式 */
.pay-loading-mask {
  position: fixed;
  top: 0;
  left: 0;
  right: 0;
  bottom: 0;
  background-color: rgba(0, 0, 0, 0.5);
  display: flex;
  justify-content: center;
  align-items: center;
  z-index: 9999;
}

.pay-loading-box {
  background-color: white;
  padding: 30rpx 40rpx;
  border-radius: 16rpx;
  display: flex;
  flex-direction: column;
  align-items: center;
}

.loading-spinner {
  width: 50rpx;
  height: 50rpx;
  border: 4rpx solid #eee;
  border-top-color: #07c160;
  border-radius: 50%;
  animation: spin 1s linear infinite;
  margin-bottom: 20rpx;
}

.loading-text {
  color: #333;
  font-size: 28rpx;
}

/* 旋转动画 */
@keyframes spin {
  to {
    transform: rotate(360deg);
  }
}
</style>
