<!-- 支付方式 -->
<template>
  <v-card elevation="0" :loading="loading" :disabled="loading">
    <!-- 加载样式 -->
    <template v-slot:loader="{ isActive }">
      <v-progress-linear
        :active="isActive"
        color="var(--v-primary-base)"
        height="1"
        indeterminate
      ></v-progress-linear>
    </template>
    <div>{{ countdown }}</div>
    <div style="color: var(--v-error-base); font-weight: bold; text-align: center;">
      <span class="font-size-13 mr-2">￥</span>
      <span class="font-size-40"> {{ orderInfo?.price ? orderInfo?.price / 100 : 0 }}</span>
    </div>
    <template v-if="payMethods?.length">
      <v-chip-group v-model="payment" selected-class="text-primary" column mandatory @update:modelValue="payTypeChange">
        <v-chip filter v-for="k in payMethods" :key="k.code" :value="k.code" class="mr-3" label>
          {{ k.name }}
          <svg-icon v-if="k.icon" class="ml-1" :name="k.icon" :size="k.size"></svg-icon>
        </v-chip>
      </v-chip-group>
      <div v-if="tip" style="text-align: center;" class="mt-2">{{ tip }}</div>
      <div v-if="isQrCodePay && remainder<=0" style="text-align: center;" class="my-10">
        二维码失效，请重试！
        <!-- 二维码刷新 -->
        <span @click="submitOrderFun(true)">
          <v-icon size="20" style="color: var(--v-primary-base)">mdi-refresh</v-icon>
          <span class="text-decoration-underline cursor-pointer mr-2" style="color: var(--v-primary-base)">刷新</span>
        </span>
      </div>
      <div>
        <!-- 钱包支付 -->
        <div v-if="isWalletPay" class="py-10" style="text-align: center;">
          <div>
            <span>剩余现金：</span>
            <span style="color: var(--v-primary-base);">{{ balance ? (balance / 100.0).toFixed(2) : 0 }}</span>
          </div>
          <!-- 余额刷新 -->
          <div class="mt-3" @click="updateAccountInfo">
            <v-icon size="20" style="color: var(--v-primary-base)">mdi-refresh</v-icon>
            <span class="text-decoration-underline cursor-pointer mr-2" style="color: var(--v-primary-base)">刷新</span>
          </div>
          <div class="my-3" v-if="notEnoughMoney">
            <span class="color-error">
              余额不足，请微信扫码付款
              <span class="text-decoration-underline cursor-pointer" @click="open">（充值）</span>
            </span>
          </div>
        </div>
        <!-- 模拟支付 -->
        <div v-if="payment === 'mock'" class="py-10"></div>
        <!-- 二维码支付 -->
        <div v-if="isQrCodePay && remainder>0" style="text-align: center;">
          <QrCode :text="payQrCodeTxt" :width="170" style="margin: 0 auto;" />
          <div
            v-if="payQrCodeTxt"
            class="mb-5"
            style="color: var(--v-error-base);"
          >
            扫码支付时请勿离开
            <span v-if="remainderZhShow">{{ remainderZhShow }}</span>
          </div>
        </div>
        <!-- 钱包支付确认按钮 -->
        <div v-if="(isWalletPay && !notEnoughMoney) || payment === 'mock'" class="mt-2" style="text-align: center;">
          <v-btn
            class="buttons" color="primary"
            :loading="payLoading"
            @click="submitBtn"
          >
            确认
          </v-btn>
        </div>
      </div>
    </template>
  </v-card>
</template>

<script setup>
defineOptions({ name: 'mall-pay'})
import { computed, onBeforeUnmount, ref } from 'vue'
import QrCode from '@/components/QrCode'
import { definePayTypeList, qrCodePay, walletPay } from '@/utils/payType'
import { getEnableCodeList, getOrderPayStatus } from '@/api/common'
import { getOrder, submitOrder } from '@/api/mall/trade'
const emit = defineEmits(['payTypeChange', 'paySuccess', 'stopInterval', 'getOrderFail', 'payed'])
const props = defineProps({
  code: {
    type: String,
    default: 'mall' // mall:商城付款
  },
  appId: {
    type: Number,
    default: 12 // 12:商城付款
  },
  id: {
    type: String,
    default: '',
  }
})
const loading = ref(true)
const tip = ref('')
// const orderType = ref('goods') // 订单类型; goods - 商品订单, recharge - 充值订单
const orderInfo = ref({})
const payStatus = ref(0) // 0=检测支付环境, -2=未查询到支付单信息， -1=支付已过期， 1=待支付，2=订单已支付
const payMethods = ref([]) // 可选的支付方式
const payment = ref('') // 选中的支付方式

import { useUserStore } from '@/store/user'; const userStore = useUserStore()
const userAccount = ref(JSON.parse(localStorage.getItem('userAccount')) || {}) // 账户信息
userStore.$subscribe((mutation, state) => {
  if (Object.keys(state.userAccount).length) userAccount.value = state.userAccount
})

const updateAccountInfo = async (isSnackbar = true) => {
  await userStore.getUserAccountBalance()
  userAccount.value = JSON.parse(localStorage.getItem('userAccount')) || {}
  if (isSnackbar) Snackbar.success('刷新成功！')
}

// 对比余额是否不足 订单金额:orderInfo?.price-0
const balance = computed(() => {
  return userAccount.value?.balance ? userAccount.value.balance-0 : 0
})
const notEnoughMoney = computed(() => {
  return orderInfo.value?.price-0 > balance.value
})

const Destroyed = ref(false)
onBeforeUnmount(() => {
  Destroyed.value = true // 避免执行paySubmit中关闭支付弹窗，造成setInterval一直存在
  clear()
})

// 提交支付订单 (提交后倒计时显示及支付状态轮巡)
const timer = ref(null) // 支付状态轮询
const submitOrderFun = async (showLoading = false) => {
  if (!payment.value) return
  try {
    if (orderInfo.value) {
      // 提交支付订单
      // channelExtras: { openid: null} // 特殊逻辑：微信公众号、小程序支付时，必须传入 openid
      const params = {
        id: orderInfo.value.id, // 支付单编号
        channelCode: payment.value, // 支付渠道
        // returnUrl: , // 支付成功后，支付渠道跳转回当前页；再由当前页，跳转回 {@link returnUrl} 对应的地址
      }
      if (showLoading) loading.value = true
      const res = await submitOrder(params)
      // 二维码内容赋值
      payQrCodeTxt.value = res?.displayContent || ''
      remainder.value = 1 
      //
      initIntervalFun() // 倒计时显示及支付状态轮巡
    }
  } catch (error) {
    console.log(error)
  } finally {
    if (showLoading) loading.value = false
  }
}

// 状态转换：payOrder.status => payStatus
const checkPayStatus = () => {
  if (orderInfo.value.status === 10 || orderInfo.value.status === 20) {
    // 支付成功 (订单已支付)
    payStatus.value = 2;
    emit('payed')
    return
  }
  if (orderInfo.value.status === 30) {
    // 支付关闭
    payStatus.value = -1;
    return;
  }
  payStatus.value = 1; // 待支付
}

const countdownInterval = ref(null)
const countdownIntervalInit = () => {
  countdownInterval.value = setInterval(() => {
    countdown.value
  }, 1000)
}

// 获得支付订单信息
const setOrder = async () => {
  if (!props.id-0) return emit('getOrderFail')
  try {
    const data = await getOrder(props.id, true) // 获取待支付的订单 (order:业务订单; orderInfo:支付订单)
    if (!data) {
      payStatus.value = -2;
      return
    }
    orderInfo.value = data || null
    // 剩余支付时间倒计时
    countdownIntervalInit()
    // 设置支付状态
    checkPayStatus()
    // await updateAccountInfo()
    // 获得支付方式
    await setPayMethods()
    // 获得支付方式
    // await setPayMethods();
    if (isQrCodePay.value) submitOrderFun() // 二维码支付时自动创建订单获取二维码内容展示
  } catch (error) {
    console.log('error:', error)
  } finally {
    loading.value = false
  }
}
setOrder()

// 清空setInterval
function clear() {
  remainder.value = 1
  payQrCodeTxt.value = '' // 二维码内容
  if (countdownInterval.value) clearInterval(countdownInterval.value); countdownInterval.value = null
  if (timer.value) clearInterval(timer.value); timer.value = null
  if (remainderTimer.value) clearInterval(remainderTimer.value); remainderTimer.value = null
}

// 1.获得支付方式
const isWalletPay = ref(false)
const isQrCodePay = ref(false)
const payTypeChange = (value) => {
  payment.value = value
  tip.value = payMethods.value.find(e => e.code === payment.value)?.tip || ''
  isQrCodePay.value = qrCodePay.includes(payment.value)
  isWalletPay.value = walletPay.includes(payment.value)
  if (isQrCodePay.value) submitOrderFun() // 二维码支付时自动创建订单获取二维码内容展示
  else { clear() }
}
// 1.支付方式
const setPayMethods = async () => {
  let list = []
  payMethods.value = []
  try {
    // list = await getEnableCodeList2(props.code)
    list = await getEnableCodeList({ appId: props.appId })
  } catch (error) {
    console.log(error)
  } finally {
    if (definePayTypeList?.length && list?.length) {
      list.forEach(code => {
        const item = definePayTypeList.find(p => p.code === code)
        if (item) {
          if (!payment.value) {
            tip.value = item.tip || ''
            payTypeChange(code) // 默认值赋值
          }
          payMethods.value.push(item)
        }
      })
    }
  }
}


const payLoading = ref(false)
const payQrCodeTxt = ref('')

// 钱包支付（余额支付）、模拟支付
const submitBtn = () => {
  payLoading.value = true
  submitOrderFun()
}

import Snackbar from '@/plugins/snackbar'
import { useRoute } from 'vue-router'; const route = useRoute()
import { useRouter } from 'vue-router'; const router = useRouter()
const getPayStatus = async () => {
  if (Destroyed.value) return clear() // 用户关闭支付
  try {
    const data = await getOrderPayStatus({ id: orderInfo.value.id || orderInfo.value.payOrderId })
    if ((data?.status - 0) === 10) {
      // 支付成功
      clear()
      setTimeout(() => {
        emit('paySuccess', { price: orderInfo.value.price })
        if (isWalletPay.value) updateAccountInfo() // 更新余额
        // Snackbar.success('支付成功')
        if (route.fullPath === props.returnUrl) router.go(0) // 刷新页面
        else if (props.returnUrl) router.push(props.returnUrl) // 返回指定页面
      }, 2000);
    }
  } catch (error) {
    console.log(error)
  }
}

// 倒计时
const countdownTime = 60000 * 3 // 倒计时三分钟
const remainder = ref(1) // number 初始化不能为假，否则不能显示二维码
const remainderZhShow = ref('') // 倒计时展示

const remainderTimer = ref(null)
// 初始化倒计时
const initIntervalFun = async () => {
  remainder.value = countdownTime // 初始倒计时时间
  if (remainderTimer.value) clearInterval(remainderTimer.value); remainderTimer.value = null // 每一次点击都清除上一个轮询
  if (timer.value) clearInterval(timer.value); timer.value = null
  //
  await getPayStatus() // 立即查询一次支付状态
  remainderCalc(); remainderTimer.value = setInterval(() => { remainderCalc() }, 1000) // 倒计时计算
  timer.value = setInterval(() => { getPayStatus() }, 2000) // 轮巡支付状态
}

const remainderCalc = () => {
  if (Destroyed.value) return clear() // 用户关闭支付
  remainder.value -= 1000
  remainderZhShow.value = formatDuration(remainder.value)
  if (remainder.value <= 0) { // 倒计时结束
    tip.value = ''
    if (timer.value) clearInterval(timer.value); timer.value = null
    emit('stopInterval') // 倒计时结束，关闭倒计时弹窗
  }
}

const formatDuration = (remainder) => {
  // 将毫秒转换为秒
  var seconds = Math.floor(remainder / 1000)
  // 计算分钟和剩余的秒数
  var minutes = Math.floor(seconds / 60)
  var remainingSeconds = seconds % 60
  // 格式化分钟和秒数，确保秒数为两位数（如果小于10，则前面补0）
  minutes = minutes.toString().padStart(2, '0')
  remainingSeconds = remainingSeconds.toString().padStart(2, '0')
  // 返回格式化的字符串
  return `${minutes}分${remainingSeconds}秒`
}

// 支付倒计时文案提示
const countdown = computed(() => {
  const now = Date.now();
  const distance = orderInfo.value.expireTime - now

  if (distance < 0) {
    clearInterval(countdownInterval.value)
    router.go(0)
    return '已过期'
  }

  const seconds = Math.floor((distance / 1000) % 60)
  const minutes = Math.floor((distance / (1000 * 60)) % 60)
  const hours = Math.floor((distance / (1000 * 60 * 60)) % 24)
  // const days = Math.floor(distance / (1000 * 60 * 60 * 24))

  return '剩余支付时间: ' + hours + ':' + minutes + ':' + seconds
});

const open = () => {
  window.open('/personalRecharge')
}

</script>

<style lang="scss" scoped>
.font-size-40 { font-size: 40px; }
</style>
