<script setup lang="ts">
import {
  fetchCreateEquityOrder,
  fetchGetEquityPayQrCode,
  fetchGetPayStatus,
  fetchGetPointsGiftPackageList,
} from '@/apis/equity'
import { useSystemLanguageStore } from '@/store/modules/system-language'
import { useUserStore } from '@/store/modules/user'
import { computed, ref, watch } from 'vue'
import { useI18n } from 'vue-i18n'

const isShowPointRechargeModal = defineModel<boolean>('isShowPointRechargeModal', { default: false })

const { t } = useI18n()
const userStore = useUserStore()
const systemLanguageStore = useSystemLanguageStore()

const currentSelectPackage = ref<0 | 1 | 2>(0) // 1：100积分 2：350积分 3：600积分
const currentPaymentMethod = ref<'alipay' | 'wechatpay'>('alipay')
const isPaymentSuccess = ref(false)
const pointsGiftPackageListLoading = ref(false)
const pointsGiftPackageList = ref([
  {
    id: 0,
    amount: 9.9,
    points: 100,
  },
  {
    id: 1,
    amount: 29.9,
    points: 350,
  },
  {
    id: 2,
    amount: 49.9,
    points: 600,
  },
])

const payInfo = ref({
  url: '',
  payOrderSn: '',
})
const isPayQrcodeInvalid = ref(false)
const currentPayPrice = ref(0)
let payStatusTimer: NodeJS.Timeout | null = null
let controller: AbortController | null = null

const isEnglishLanguage = computed(() => systemLanguageStore.currentLanguageInfo.key === 'en')

watch(isShowPointRechargeModal, (newVal) => {
  if (newVal) {
    getPointsGiftPackageList()
    getEquityPayQrCode()
  }
})

function getPointsGiftPackageList() {
  pointsGiftPackageListLoading.value = true

  fetchGetPointsGiftPackageList<{
    normal: { amount: number; points: number }
    professional: { amount: number; points: number }
    ultimate: { amount: number; points: number }
  }>().then((res) => {
    if (res.code !== 0) return ''

    if (res.data.normal) {
      pointsGiftPackageList.value[0] = { id: 0, amount: res.data.normal.amount, points: res.data.normal.points }
    }
    if (res.data.professional) {
      pointsGiftPackageList.value[1] = {
        id: 0,
        amount: res.data.professional.amount,
        points: res.data.professional.points,
      }
    }
    if (res.data.ultimate) {
      pointsGiftPackageList.value[2] = { id: 0, amount: res.data.ultimate.amount, points: res.data.ultimate.points }
    }

    currentPayPrice.value = pointsGiftPackageList.value[0].amount

    pointsGiftPackageListLoading.value = false
  })
}

function getEquityPayQrCode() {
  controller && controller.abort()

  clearPayStatusTimer()
  clearPayInfo()

  controller = new AbortController()

  const payload = {
    type: '',
    domain: 'point',
    validityUnit: 'indefinite',
  }

  switch (currentSelectPackage.value) {
    case 0:
      payload.type = 'normal'
      currentPayPrice.value = pointsGiftPackageList.value[0].amount
      break
    case 1:
      payload.type = 'professional'
      currentPayPrice.value = pointsGiftPackageList.value[1].amount
      break
    case 2:
      payload.type = 'ultimate'
      currentPayPrice.value = pointsGiftPackageList.value[2].amount
      break
  }

  fetchCreateEquityOrder<string>(payload, controller).then((orderRes) => {
    if (orderRes.code !== 0) return ''

    const payQrCodePayload = {
      payChannel: '',
      payOrderSn: orderRes.data,
    }

    switch (currentPaymentMethod.value) {
      case 'alipay':
        payQrCodePayload.payChannel = 'ALI_NATIVE'
        break
      case 'wechatpay':
        payQrCodePayload.payChannel = 'WX_NATIVE'
        break
    }

    fetchGetEquityPayQrCode<{ packageExtra: string; payOrderSn: string }>(payQrCodePayload, controller!).then(
      (qrcodeRes) => {
        if (orderRes.code !== 0) return ''

        isPayQrcodeInvalid.value = false

        payInfo.value = {
          url: qrcodeRes.data.packageExtra.replace('code_url=', ''),
          payOrderSn: qrcodeRes.data.payOrderSn,
        }

        /* 延迟自动取消支付查询 */
        setTimeout(
          () => {
            isPayQrcodeInvalid.value = true
          },
          10 * 60 * 1000,
        )

        getPayStatus()
      },
    )
  })
}

function getPayStatus() {
  function request() {
    fetchGetPayStatus<{ payStatus: 'Paid' | 'NoPayment' | 'Cancel' }>(payInfo.value.payOrderSn).then((res) => {
      if (res.code !== 0) return ''

      if (res.data.payStatus === 'Paid') {
        isPaymentSuccess.value = true
        clearPayStatusTimer()

        setTimeout(() => {
          userStore.fetchUpdateEquityInfo()
          window.$message.success(t('common_module.payment_success'))

          isShowPointRechargeModal.value = false
        }, 1400)
      }
    })
  }

  clearPayStatusTimer()
  payStatusTimer = setInterval(() => {
    request()
  }, 1000)
}

function handlePaymentMethodSwitch(method: 'alipay' | 'wechatpay') {
  currentPaymentMethod.value = method

  getEquityPayQrCode()
}

function handlePackageSwitch(key: typeof currentSelectPackage.value) {
  currentSelectPackage.value = key

  getEquityPayQrCode()
}

function clearPayInfo() {
  payInfo.value = {
    url: '',
    payOrderSn: '',
  }

  isPayQrcodeInvalid.value = false
  isPaymentSuccess.value = false
}

function clearPayStatusTimer() {
  if (payStatusTimer !== null) {
    clearInterval(payStatusTimer)
    payStatusTimer = null
  }
}

function onModalAfterLeave() {
  currentSelectPackage.value = 0
  currentPaymentMethod.value = 'alipay'

  clearPayStatusTimer()
  clearPayInfo()
}

function handlePayQrCodeRefresh() {
  getEquityPayQrCode()
}
</script>

<template>
  <n-modal
    v-model:show="isShowPointRechargeModal"
    preset="card"
    :title="t('equity_module.point_recharge')"
    size="medium"
    class="!w-[850px]"
    :on-after-leave="onModalAfterLeave"
  >
    <div v-if="!pointsGiftPackageListLoading">
      <ul class="mt-[10px] flex" :class="isEnglishLanguage ? 'h-[285px]' : 'h-[255px]'">
        <li
          v-for="(packageItem, packageIndex) in pointsGiftPackageList"
          :key="packageItem.id"
          class="mr-[19px] max-w-[260px] flex-1 rounded-[10px] border text-center transition last:mr-0"
          :class="currentSelectPackage === packageIndex ? 'border-[#FFC07B]' : 'border-[#F4DEC5]'"
          :style="
            currentSelectPackage === packageIndex
              ? { backgroundImage: 'linear-gradient(45deg, #FFD063, #FFF1D5, #FEBB57)' }
              : { backgroundImage: 'linear-gradient(45deg, #ffe9cd, #fffbf2, #ffefd1)' }
          "
        >
          <div class="font-600 mt-[32px] text-[16px] text-[#482801]">
            {{ packageItem.points }} {{ t('equity_module.points2') }}
          </div>
          <div class="font-600 mt-[10px] text-[24px] text-[#482801]">
            {{ packageItem.amount }} <span class="text-[14px] text-[#482801]">￥</span>
          </div>

          <button
            class="flex-center mx-auto mt-[12px] flex h-[34px] w-[86px] rounded-[5px] bg-[#FDC386] text-[14px] text-[#fff] transition hover:bg-[#F1B273]"
            :style="
              currentSelectPackage === packageIndex
                ? { backgroundImage: 'linear-gradient(to bottom, #FFF598, #FFAA00)' }
                : {}
            "
            @click="handlePackageSwitch(packageIndex as 0 | 1 | 2)"
          >
            {{ t('common_module.buy_now') }}
          </button>

          <ul class="ml-[20px] mt-[26px] pr-[8px]">
            <li class="mb-[8px] flex text-[14px] text-[#482801]">
              <span
                class="mr-[5px] mt-[8px] inline-block h-[6px] w-[6px] shrink-0 rounded-full"
                :class="currentSelectPackage === packageIndex ? 'bg-[#FFEAC8]' : 'bg-[#EBD8BE]'"
              ></span>
              <div class="text-start">
                {{ t('equity_module.get_points_for_interacting_with_the_ai', { points: packageItem.points }) }}
              </div>
            </li>
            <li class="mb-[8px] flex items-center text-[14px] text-[#482801]">
              <span
                class="mr-[5px] inline-block h-[6px] w-[6px] rounded-full"
                :class="currentSelectPackage === packageIndex ? 'bg-[#FFEAC8]' : 'bg-[#EBD8BE]'"
              ></span>
              {{ t('equity_module.no_time_limit_when_used_up') }}
            </li>
          </ul>
        </li>
      </ul>

      <div class="mt-[28px] flex items-center justify-center">
        <h4 class="mr-[14px] text-[14px]">{{ t('equity_module.payment_method') }}：</h4>
        <ul class="flex select-none items-center">
          <li
            class="mr-[12px] flex cursor-pointer items-center rounded-[5px] border border-[#999999] px-[16px] py-[6px] text-[14px] transition"
            :class="currentPaymentMethod === 'alipay' ? '!border-[#000DFF]' : ''"
            @click="handlePaymentMethodSwitch('alipay')"
          >
            <img class="mr-[5px] h-[16px] w-[16px]" src="@/assets/images/equity/alipay-icon.png" alt="alipay" />
            <span>{{ t('common_module.alipay') }}</span>
          </li>
          <li
            class="mr-[12px] flex cursor-pointer items-center rounded-[5px] border border-[#999999] px-[16px] py-[6px] text-[14px] text-[#333] transition"
            :class="currentPaymentMethod === 'wechatpay' ? '!border-[#000DFF]' : ''"
            @click="handlePaymentMethodSwitch('wechatpay')"
          >
            <img class="mr-[5px] h-[16px] w-[16px]" src="@/assets/images/equity/wechat-icon.png" alt="alipay" />
            <span>{{ t('common_module.wechat') }}</span>
          </li>
        </ul>
      </div>
      <div class="mt-[26px] flex justify-center">
        <template v-if="payInfo.url">
          <div v-if="currentPaymentMethod === 'wechatpay'" class="relative">
            <n-qr-code
              class="align-bottom"
              :class="isPayQrcodeInvalid ? 'blur-sm' : ''"
              :value="payInfo.url"
              :size="140"
              :padding="0"
            />
            <Transition name="mask">
              <div v-show="isPaymentSuccess" class="flex-center absolute inset-0 flex bg-[rgba(0,0,0,0.6)]">
                <div
                  class="flex-center flex h-[50px] w-[50px] rounded-full border-[4px] border-solid border-[#fff] bg-[#52c41a]"
                >
                  <i class="iconfont icon-queren font-600 text-[28px] text-white"></i>
                </div>
              </div>
            </Transition>

            <Transition name="mask">
              <div v-show="isPayQrcodeInvalid" class="flex-center absolute inset-0 flex">
                <div class="absolute inset-0 bg-[rgba(0,0,0,0.6)] blur-sm"></div>

                <i
                  class="iconfont icon-huanyihuan font-600 z-1 relative cursor-pointer text-[30px] text-[#fff]"
                  @click="handlePayQrCodeRefresh"
                ></i>
              </div>
            </Transition>
          </div>
          <div v-else-if="currentPaymentMethod === 'alipay'" class="flex-center flex">
            <iframe
              :src="payInfo.url"
              frameborder="0"
              width="140"
              height="140"
              class="object-center"
              scrolling="no"
            ></iframe>
          </div>
        </template>
        <div v-else class="flex-center flex h-[140px] w-[140px]">
          <n-spin size="large" />
        </div>
      </div>

      <div class="mt-[10px] flex items-center justify-center">
        <template v-if="currentPaymentMethod === 'alipay'">
          <img class="mr-[5px] mt-[6px] h-[16px] w-[16px]" src="@/assets/images/equity/alipay-icon.png" alt="alipay" />
          <span class="font-600 text-[16px]">
            {{ t('common_module.alipay') }} {{ t('equity_module.scan_code_payment') }}
            <span class="text-[24px] text-[#F25744]">{{ currentPayPrice }}</span>
            ￥
          </span>
        </template>
        <template v-else-if="currentPaymentMethod === 'wechatpay'">
          <img class="mr-[5px] mt-[6px] h-[16px] w-[16px]" src="@/assets/images/equity/wechat-icon.png" alt="alipay" />
          <span class="font-600 text-[16px]">
            {{ t('common_module.wechat') }} {{ t('equity_module.scan_code_payment') }}
            <span class="text-[24px] text-[#F25744]"> {{ currentPayPrice }}</span>
            ￥
          </span>
        </template>
      </div>
    </div>
    <div v-else class="flex-center flex h-[534px]">
      <n-spin size="large" />
    </div>
  </n-modal>
</template>

<style lang="scss" scoped>
.mask-enter-active,
.mask-leave-active {
  transition-timing-function: ease-in-out;
  transition-duration: 0.2s;
  transition-property: opacity;
}

.mask-enter-from,
.mask-leave-to {
  opacity: 0;
}
</style>
