<template>
  <view style="z-index: 999;">
    <uni-popup ref="popup" :is-mask-click="false" borderRadius="10px 10px 0 0" background-color="#eee" @change="popupChange">
      <view class="popup-content">
        <view class="popup-content-close">
          <view class="icon" @tap="handleClose">
            <uni-icons
              type="closeempty"
              color="#999"
              size="24"
            />
          </view>
        </view>
        <view class="popup-content-main">
          <view class="popup-content-main-count">
            <view class="title">{{ title }}</view>
            <view class="pay">
              <uni-icons color="#000" type="icon-renminbi1688" size="16" custom-prefix="iconfont"></uni-icons>
              <view>{{ amount }}</view>
            </view>
          </view>
          <view class="popup-content-main-type">
            <view v-if="payTypeList?.length" class="card">
              <radio-group @change="radioChange">
                <label class="card-label" v-for="item in payTypeList" :key="item.value">
                  <view class="name">
                    <uni-icons :color="item.color" class="mr-1" :type="item.icon" size="24" custom-prefix="iconfont"></uni-icons>
                    {{item.name}}
                  </view>
                  <view>
                    <radio :value="item.value" :disabled="item.disabled" :checked="item.value === channelValue" />
                  </view>
                </label>
              </radio-group>
            </view>
          </view>
        </view>
        <view class="popup-content-btn">
          <button class="popup-content-btn-s" @tap="handlePay(false)">
            确认支付 
            <uni-icons color="#FFF" type="icon-renminbi1688" size="16" custom-prefix="iconfont"></uni-icons>
            {{ amount }}
          </button>
        </view>
      </view>
    </uni-popup>
  </view>
</template>
<script setup>
import { ref } from 'vue'
import { onHide, onShow } from '@dcloudio/uni-app'
// import { userStore } from '@/store/user'; const useUserStore = userStore()
import { getSocialUser, socialUserBind, payOrderSubmit, getOrderPayStatus, getEnableCodeList } from '@/api/common'
import { createTradeOrder, getUnpaidOrder } from '@/api/new/position'
const emit = defineEmits(['paySuccess'])

const props = defineProps({
  title: { // 标题
    type: String,
    default: '支付'
  },
  amount: { // 支付金额
    type: [String, Number],
    default: '金额获取失败'
  },
})

const payType = [
  {
    name: '微信支付',
    value: 'wx_lite',
    icon: 'icon-weixinzhifu',
    color: '#1AAD19'
  },
  // {
  //   name: '钱包支付',
  //   value: 'wallet',
  //   disabled: true,
  //   icon: 'icon-qianbao1',
  //   color: '#00B760'
  // }
]

// 余额和其他还没有接暂时只支持微信支付
const payTypeList = ref([])
// 获取支付方式
const getPayMethodsList = async () => {
  payTypeList.value = []
  try {
    const res = await getEnableCodeList({appId: 10})
    if (!res?.data?.length) {
      return
    }
    payTypeList.value.push(...payType.filter(e => res.data.includes(e.value)))
    const result = payType.find(item => !item.disabled && item.value)
    if (result) channelValue.value = result.value
  } catch (error) {
    console.log(error)
  }
}
getPayMethodsList()

const channelValue = ref('')
const radioChange = (e) => {
  channelValue.value = e?.detail?.value || ''
}

const tabBarShow = (show = false) => { // 显示/隐藏TabBar
  const currentPage = getCurrentPages()
  if (!currentPage) return
  const currentTabBar = currentPage[0]?.getTabBar?.()
  currentTabBar?.setData({ show })
}

const popup = ref()
const handleClose = () => {
  tabBarShow(true)
  popup.value.close()
}
const query = ref(null)
const handleOpen = (val) => {
  query.value = val
  tabBarShow(false)
  popup.value.open('bottom')
}

// 设置 openid 到本地存储，目前只有 pay 支付时会使用
const setOpenid = (openid) => {
  uni.setStorageSync('openid', openid)
}

const bind = () => {
  return new Promise(async (resolve, reject) => {
    // 1. 获得微信 code
    const codeResult = await uni.login()
    if (codeResult.errMsg !== 'login:ok') {
      return resolve(false)
    }
    // 2. 绑定账号 // // 社交快捷登录
    const obj = {
      type: socialType,
      code: codeResult.code,
      state: 'default',
    }
    const bindResult = await socialUserBind(obj);
    if (bindResult.code === 0) {
      setOpenid(bindResult.data)
      return resolve(true)
    } else {
      return resolve(false)
    }
  })
}

const bindWeiXin = () => {
  uni.showModal({
    title: '微信支付',
    content: '请先绑定微信再使用微信支付',
    success: function (res) {
      if (res.confirm) {
        // 微信小程序绑定
        bind()
      }
    },
  });
}

const socialType = 34; // 社交类型 - 微信小程序

// 预支付
const prepay = async (channel, orderData) => { 
  return new Promise(async (resolve, reject) => {
    let data = {
      id: orderData?.payOrder?.id,
      channelCode: channel,
      channelExtras: {},
    };
    // 特殊逻辑：微信公众号、小程序支付时，必须传入 openid
    if (['wx_pub', 'wx_lite'].includes(channel)) {
      const userRes = await getSocialUser(socialType)
      const openid = userRes?.data?.openid ? userRes.data.openid : null
      // 如果获取不到 openid，微信无法发起支付，此时需要引导
      if (!openid) {
        bindWeiXin()
        return
      }
      data.channelExtras.openid = openid
    }
    // 发起预支付 API 调用
    payOrderSubmit(data).then((res) => {
      // 成功时
      res.code === 0 && resolve(res)
      // 失败时
      if (res.code !== 0 && res.msg.indexOf('无效的openid') >= 0) {
        // 特殊逻辑：微信公众号、小程序支付时，必须传入 openid 不正确的情况
        if (
          res.msg.indexOf('无效的openid') >= 0 || // 获取的 openid 不正确时，或者随便输入了个 openid
          res.msg.indexOf('下单账号与支付账号不一致') >= 0
        ) {
          bindWeiXin()
        }
      }
    })
  })
}

let interTimer = null
let payLoading = false
const checkPayStatus = async (id) => {
  if (!id) return
  try {
    if (payLoading || !interTimer) return
    payLoading = true
    const res = await getOrderPayStatus({ id })
    if (res?.data?.status === 10) {
      if (interTimer) clearInterval(interTimer)
      uni.showToast({ title: '支付成功', icon: 'none'})
      setTimeout(async () => {
        emit('paySuccess')
      }, 1500)
    }
  } catch (error) {
    console.log(error)
  } finally {
    payLoading = false
  }
}

// 计时器
const initIntervalFun = () => {
  if (interTimer) clearInterval(interTimer)

  // 查询是否已经支付
  const id = orderInfo.value?.payOrder?.id || orderInfo.value?.order?.payOrderId
  if (id) {
    interTimer = setInterval(() => {
      checkPayStatus(id)
    }, 1000)
  }
}

const orderInfo = ref({})
const weChatMiniProgramPay = async (data) => {
  orderInfo.value = data
  let res = await prepay(channelValue.value, data); // 预支付
  if (res?.code !== 0) {
    return;
  }
  // 调用微信小程序支付
  const payConfig = res?.data?.displayContent ? JSON.parse(res.data.displayContent) : null
  if (!payConfig) return uni.showToast({ title: '购买失败', icon: 'none'})
  uni.requestPayment({
    provider: 'wxpay',
    timeStamp: payConfig.timeStamp,
    nonceStr: payConfig.nonceStr,
    package: payConfig.packageValue,
    signType: 'RSA',
    paySign: payConfig.paySign,
    success: (res) => {
      // 用户支付成功
      initIntervalFun()
      handleClose()
    },
    fail: (err) => {
      if (err.errMsg === 'requestPayment:fail cancel') {
        uni.showToast({ title: '支付已取消', icon: 'none'})
      } else {
        uni.showToast({ title: '支付失败', icon: 'none'})
      }
    },
  });
}

// 确认支付
const handlePay = async (retry = false) => {
  if (!channelValue.value) {
    uni.showToast({ title: '请选择支付方式', icon: 'none'})
    return
  }
  // 判断是否已有创建好的订单，有就直接跳转支付，没有就创建订单
  try {
    const params = {
      spuId: query.value?.spuId, // 商品编号
      type: query.value?.type // 订单类型 0平台订单|1发布职位|2发布众聘职位|3会员套餐|4企业会员套餐|5招聘会门票
    }
    if (!params.spuId || params.type === null || params.type === undefined) return
    const res = await getUnpaidOrder(params) // 查询订单
    if (res.data) {
      // 获取支付码
      weChatMiniProgramPay(res.data)
      return
    }
    if (!retry) setOrderCreated() // 创建订单
  } catch (error) {
    console.log(error)
  }
}

const setOrderCreated = async () => {
  const params = {
    spuId: query.value?.spuId, // 商品编号
    type: query.value?.type, // 订单类型 0平台订单|1发布职位|2发布众聘职位|3会员套餐|4企业会员套餐|5招聘会门票
    price: query.value?.price, // 价格
    spuName: query.value?.spuName, // 商品名称
  }
  if (!params.spuId || params.type === null || params.type === undefined || !params.price || !params.spuName) return
  await createTradeOrder(params)
  handlePay(true) // 避免死循环
}

onShow(() => {
  if (orderInfo && orderInfo.value?.id) initIntervalFun()
})
onHide(() => {
  if (interTimer) clearInterval(interTimer)
})

const popupChange = (e) => {
  if (!e || e.show === undefined) return
  if (e.show) {
    // 支付弹窗打开
    tabBarShow(false)
    if (orderInfo && orderInfo.value?.id) initIntervalFun()
  } else {
    // 支付弹窗关闭
    tabBarShow(true)
    if (interTimer) clearInterval(interTimer)
  }
}

defineExpose({
	handleOpen
})
</script>
<style lang="scss" scoped>
.pay {
  position: sticky;
  bottom: 0;
  padding: 0 40rpx 50rpx 40rpx;
  box-sizing: border-box;
  &-box {
    width: 100%;
    background: linear-gradient(121deg,#fde2c2 29.02%,#c19164 104.03%);
    border-radius: 180rpx 0 180rpx 0;
    box-shadow: 3rpx 6rpx 10rpx 0rpx rgb(216 160 82);
    display: flex;
    justify-content: space-between;
    align-items: center;
    height: 100rpx;
    .price {
      padding: 0 40rpx;
      font-size: 40rpx;
      font-weight: 600;
      color: #e68735;
    }
    .btn {
      height: 100%;
      display: flex;
      align-items: center;
      padding: 0 40rpx;
      border: 2rpx solid #00B760;
      background: #00B760;
      color: #FFF;
      border-radius: 180rpx 0 180rpx 0;
      position: relative;
      // &::after {
      //   content: '';
      //   position: absolute;
      //   width: 50rpx;
      //   height: 50rpx;
      //   background: radial-gradient(top right, transparent 50%, #00B760 50%);
      //   left: 0;
      //   top: 0;
      //   margin-left: -25rpx;
      //   border-radius: 180rpx;
      // }
    }
  }
}

.popup-content {
  z-index: 999;
  max-height: 500px;
  display: flex;
  flex-direction: column;
  &-close {
    display: flex;
    padding: 10px;
    justify-content: flex-end;
    .icon {
      width: 30px;
      height: 30px;
      background: #ccc;
      border-radius: 30px;
      display: flex;
      align-items: center;
      justify-content: center;
    }
  }
  &-main {
    flex: 1;
    height: 0;
    overflow-y: auto;
    &-count {
      margin-bottom: 20px;
      text-align: center;
      .title {
        font-size: 28rpx;
        color: #666
      }
      .pay {
        font-size: 52rpx;
        color: #000;
        font-weight: 600;
        display: flex;
        align-items: center;
        justify-content: center;
        padding: 10px 0;
      }
    }
    &-type {
      width: 100%;
      padding: 0 20px;
      box-sizing: border-box;
      .card {
        border-radius: 10px;
        margin: 0 auto;
        background: #FFF;
        padding: 10px;
        &-label {
          padding: 15px 0;
          box-sizing: border-box;
          display: flex;
          justify-content: space-between;
          border-bottom: 1px solid #eee;
          &:last-of-type {
            border-bottom: none;
          }
          .name {
            display: flex;
            align-items: center;
            color: #333;
          }
        }
      }
    }
  }
  &-btn {
    height: 70px;
    width: 100%;
    margin-top: 10px;
    display: flex;
    align-items: center;
    justify-content: center;
    &-s {
      height: 40px;
      width: 75%;
      line-height: 40px;
      color: #FFF;
      // color: #724d2b;
      background: #00B760;
      // background: linear-gradient(121deg,#fde2c2 29.02%,#c19164 104.03%);
      border-radius: 90px;
    }
  }
}
.mr-1 {
  margin-right: 10px;
}
</style>