<template>
  <view class="page fade-in">
    <!-- 状态栏：当前方案 + 引力值 -->
    <view class="status-bar">
      <view class="status-left">
        <text class="status-label">当前方案</text>
        <text class="status-plan">{{ currentPlanName || '免费版' }}</text>
      </view>
      <view class="status-right">
        <text class="grav-label">⚡ 引力值</text>
        <text class="grav-num">{{ gravity }}</text>
      </view>
    </view>

    <!-- 未登录提示 -->
    <view class="login-bar" v-if="!isLoggedIn">
      <text class="login-text">登录后可购买引力值、查看套餐</text>
      <text class="login-btn" @click="goLogin">去登录</text>
    </view>

    <!-- 购买引力值（最上面，登录后可见） -->
    <view class="section" v-if="isLoggedIn">
      <text class="section-title">⚡ 补充引力值</text>
      <view class="buy-card">
        <view class="qty-row">
          <text class="qty-label">购买数量</text>
          <view class="qty-controls">
            <text class="qty-btn" :class="{ disabled: buyQty <= 1 }" @click="buyQty = Math.max(1, buyQty - 1)">−</text>
            <input class="qty-input" type="number" v-model.number="buyQty" min="1" max="99" @blur="buyQty = Math.max(1, Math.min(99, buyQty || 1))" />
            <text class="qty-btn" :class="{ disabled: buyQty >= 99 }" @click="buyQty = Math.min(99, buyQty + 1)">+</text>
          </view>
        </view>
        <view class="summary">
          <view class="summary-row">
            <text class="summary-label">单价</text>
            <text class="summary-val">¥{{ (unitPrice / 100).toFixed(1) }} / 份</text>
          </view>
          <view class="summary-row">
            <text class="summary-label">可得引力值</text>
            <text class="summary-val highlight">{{ buyQty * gravityPerUnit }} ⚡</text>
          </view>
          <view class="summary-row total">
            <text class="summary-label">合计</text>
            <text class="summary-val total-price">¥{{ (buyQty * unitPrice / 100).toFixed(2) }}</text>
          </view>
        </view>
        <button class="buy-btn" :disabled="payLoading" @click="startGravityPay">
          {{ payLoading ? '处理中...' : '立即购买' }}
        </button>
      </view>
    </view>

    <!-- 套餐对比 -->
    <view class="section">
      <text class="section-title">📋 套餐对比</text>
      <view class="plan-list">
        <view v-for="p in planList" :key="p.id" class="plan-card"
          :class="{ current: p.id === plan, popular: p.popular }">
          <view class="plan-header">
            <text class="plan-name">{{ p.name }}</text>
            <view class="plan-price">
              <text class="price-num">{{ p.priceDisplay }}</text>
            </view>
            <view class="plan-badge" v-if="p.id === plan">
              <text>当前方案</text>
            </view>
          </view>
          <view class="plan-features">
            <text class="feature" v-for="(f, i) in p.features" :key="i">✓ {{ f }}</text>
          </view>
          <view class="plan-footer" v-if="p.id !== 'free'">
            <view class="plan-action owned" v-if="p.id === plan">✅ 已开通</view>
            <view class="plan-action" v-else-if="!isLoggedIn" @click="goLogin">登录后开通</view>
            <view class="plan-action" v-else-if="plan === 'free'" @click="startPlanPay(p.id)">
              {{ p.priceDisplay }} 开通
            </view>
            <view class="plan-action" v-else @click="startPlanPay(p.id)">
              升级至{{ p.name }}
            </view>
          </view>
        </view>
      </view>
    </view>

    <!-- 支付弹窗 -->
    <view class="modal-overlay" v-if="showPayModal" @click="cancelPay">
      <view class="modal-content" @click.stop>
        <template v-if="payLoading">
          <text class="modal-title">正在创建支付...</text>
        </template>
        <template v-else-if="!isMp && payCodeUrl">
          <text class="modal-title">微信扫码支付</text>
          <canvas canvas-id="payQrcode" class="qr-canvas"></canvas>
          <text class="modal-hint">请用微信扫码完成支付</text>
          <text class="modal-close" @click="cancelPay">取消支付</text>
        </template>
        <template v-else-if="vpStatus">
          <text class="modal-title" :class="vpSuccess ? '' : 'pay-error'">{{ vpSuccess ? '✅ 支付成功' : '支付失败' }}</text>
          <text class="modal-hint">{{ vpStatusText }}</text>
          <text class="modal-close" @click="cancelPay">关闭</text>
        </template>
        <template v-if="payError && !vpStatus">
          <text class="modal-title pay-error">支付异常</text>
          <text class="modal-hint">{{ payError }}</text>
          <text class="modal-close" @click="cancelPay">关闭</text>
        </template>
      </view>
    </view>
  </view>
</template>

<script setup>
import { ref, onMounted } from 'vue'
import { onLoad, onShow } from '@dcloudio/uni-app'
import { api } from '../../config'
import { checkAuth, friendlyVpError } from '../../utils/auth'

const isLoggedIn = ref(false)
const isMp = ref(false)
const plan = ref('free')
const currentPlanName = ref('免费版')
const gravity = ref(0)
const planList = ref([])

// 购买引力值
const buyQty = ref(1)
const unitPrice = ref(500)
const gravityPerUnit = ref(5)
const payLoading = ref(false)

// 支付弹窗
const showPayModal = ref(false)
const payCodeUrl = ref('')
const payError = ref('')
const currentOutTradeNo = ref('')
const payingPlan = ref('')
const paySuccess = ref(false)
const vpStatus = ref(false)
const vpSuccess = ref(false)
const vpStatusText = ref('')

// 套餐特征后备值（API 取不到时使用）
const defaultFreeFeatures = ['AI 模拟面试 1 次（体验）', '基础面试报告', '通用题库随机出题', '简历优化（限 3 次免费）']
const defaultGrowthFeatures = ['免费版全部权益', 'AI 数字人面试无限次', '详细面试报告（四维评分）', '进步轨迹雷达图 + 打卡', '每日一题', '参考回答思路', '公司真题库']
const defaultSprintFeatures = ['成长版全部权益', 'AI 语音分析（语气词/语速检测）', '技能缺口分析报告', '公司真题库精选']

const token = () => uni.getStorageSync('token') || ''

const refreshState = async () => {
  // #ifdef MP-WEIXIN
  isMp.value = true
  // #endif

  const t = token()
  isLoggedIn.value = !!t

  // 1. 先拉套餐配置（公开接口，未登录也拉）
  try {
    const pres = await uni.request({ url: api('/member/plans'), method: 'GET' })
    if (pres.statusCode >= 200 && pres.statusCode < 300 && pres.data) {
      const d = pres.data
      if (d.products?.interview) {
        unitPrice.value = d.products.interview.price || 500
        gravityPerUnit.value = d.products.interview.gravity || 5
      }
      planList.value = buildPlanList(d.plans)
    } else {
      planList.value = buildPlanList(null)
    }
  } catch (e) { /* silent */ }

  // 2. 用户信息需要登录
  if (!t) return
  try {
    const ures = await uni.request({ url: api('/user/info'), method: 'GET', header: { 'Authorization': `Bearer ${t}` } })
    if (ures.statusCode >= 200 && ures.statusCode < 300 && ures.data) {
      const u = ures.data
      plan.value = u.plan || 'free'
      gravity.value = u.gravity ?? 0
      currentPlanName.value = ({ free: '免费版', growth: '成长版', sprint: '冲刺版' })[plan.value] || '免费版'
    } else if (checkAuth(ures)) {
      return // token 过期，已清除并跳转登录
    }
  } catch (e) { /* silent */ }
}

const buildPlanList = (plans) => {
  const growth = plans?.find?.(p => p.id === 'growth')
  const sprint = plans?.find?.(p => p.id === 'sprint')
  return [
    {
      id: 'free', name: '免费版', priceDisplay: '免费',
      features: defaultFreeFeatures,
      popular: false,
    },
    {
      id: 'growth', name: '成长版',
      priceDisplay: growth ? `¥${(growth.price / 100).toFixed(1)}/月` : '¥19/月',
      features: growth?.features || defaultGrowthFeatures,
      popular: true,
    },
    {
      id: 'sprint', name: '冲刺版',
      priceDisplay: sprint ? `¥${(sprint.price / 100).toFixed(1)}/月` : '¥49/月',
      features: sprint?.features || defaultSprintFeatures,
      popular: false,
    },
  ]
}

onLoad(() => { /* silent */ })
onMounted(refreshState)
onShow(refreshState)

const goLogin = () => uni.navigateTo({ url: '/pages/login/login' })

const cancelPay = () => {
  showPayModal.value = false
  payCodeUrl.value = ''
  payLoading.value = false
  payError.value = ''
  paySuccess.value = false
  vpStatus.value = false
  vpSuccess.value = false
  vpStatusText.value = ''
}

/** 购买引力值 → MP 用 VP / H5 用扫码 */
const startGravityPay = async () => {
  const t = token()
  if (!t) { uni.showToast({ title: '请先登录', icon: 'none' }); return }

  showPayModal.value = true
  payLoading.value = true
  payError.value = ''
  vpStatus.value = false

  if (isMp.value) {
    // 小程序：虚拟支付 VP
    try {
      console.log('[VP] wx.login...')
      const [loginErr, loginRes] = await new Promise((resolve) => {
        uni.login({
          provider: 'weixin',
          success: r => { console.log('[VP] wx.login 成功:', JSON.stringify(r)); resolve([null, r]) },
          fail: e => { console.error('[VP] wx.login 失败:', JSON.stringify(e)); resolve([e, null]) },
        })
      })
      if (loginErr || !loginRes?.code) {
        payLoading.value = false
        payError.value = '微信登录失败: ' + (loginErr?.errMsg || 'no code')
        console.error('[VP] login failed', loginErr, loginRes)
        uni.showToast({ title: '微信登录失败', icon: 'none' })
        return
      }
      console.log('[VP] code:', loginRes.code.slice(0, 20) + '...')
      const res = await uni.request({
        url: api('/virtual-payment/create'), method: 'POST',
        data: { type: 'interview', quantity: buyQty.value, wxCode: loginRes.code },
        header: { 'Authorization': `Bearer ${t}`, 'Content-Type': 'application/json' },
        timeout: 30000,
      })
      console.log('[VP] 创建订单:', res.statusCode, JSON.stringify(res.data).slice(0, 500))
      payLoading.value = false

      if (res.statusCode >= 200 && res.statusCode < 300 && res.data?.paySig) {
        const vp = res.data
        currentOutTradeNo.value = vp.outTradeNo
        wx.requestVirtualPayment({
          env: vp.env, mode: vp.mode, offerId: vp.offerId,
          signData: vp.signData,
          paySig: vp.paySig, signature: vp.signature,
          success: () => {
            console.log('[VP] 支付成功')
            vpStatus.value = true
            vpSuccess.value = true
            vpStatusText.value = '引力值已到账'
            uni.showToast({ title: '充值成功！', icon: 'success' })
            refreshState()
          },
          fail: (err2) => {
            console.error('[VP] 支付失败:', JSON.stringify(err2))
            vpStatus.value = true
            vpSuccess.value = false
            vpStatusText.value = friendlyVpError(err2?.errMsg) || '你已取消支付'
          },
        })
      } else {
        const msg = res.data?.message || res.data?.msg || `请求失败(${res.statusCode})`
        if (checkAuth(res)) return
        payError.value = msg
        console.error('[VP] 订单创建失败:', res.statusCode, JSON.stringify(res.data))
      }
    } catch (e) {
      payLoading.value = false
      payError.value = '网络错误，请重试'
      console.error('[VP] 异常:', e)
    }
  } else {
    // H5：扫码支付
    try {
      const res = await uni.request({
        url: api('/payment/create-product'), method: 'POST',
        data: { type: 'interview', quantity: buyQty.value },
        header: { 'Authorization': `Bearer ${t}`, 'Content-Type': 'application/json' },
      })
      payLoading.value = false
      if (res.statusCode >= 200 && res.statusCode < 300 && res.data?.codeUrl) {
        payCodeUrl.value = res.data.codeUrl
        currentOutTradeNo.value = res.data.outTradeNo
        pollPayResult(res.data.outTradeNo, 'growth')
      } else {
        if (checkAuth(res)) return
        payError.value = res.data?.message || '创建订单失败'
      }
    } catch (e) {
      payLoading.value = false
      payError.value = '网络错误，请重试'
    }
  }
}

/** 套餐升级 → MP 用虚拟支付 VP / H5 用扫码支付 */
const startPlanPay = async (selectedPlan) => {
  const t = token()
  if (!t) { uni.showToast({ title: '请先登录', icon: 'none' }); return }

  payingPlan.value = selectedPlan
  showPayModal.value = true
  payLoading.value = true
  payError.value = ''
  vpStatus.value = false

  if (isMp.value) {
    // 小程序：虚拟支付 VP（套餐升级）
    try {
      console.log('[VP-plan] wx.login...')
      const [loginErr, loginRes] = await new Promise((resolve) => {
        uni.login({
          provider: 'weixin',
          success: r => { console.log('[VP-plan] wx.login 成功:', JSON.stringify(r)); resolve([null, r]) },
          fail: e => { console.error('[VP-plan] wx.login 失败:', JSON.stringify(e)); resolve([e, null]) },
        })
      })
      if (loginErr || !loginRes?.code) {
        payLoading.value = false
        payError.value = '微信登录失败: ' + (loginErr?.errMsg || 'no code')
        console.error('[VP-plan] login failed', loginErr, loginRes)
        uni.showToast({ title: '微信登录失败', icon: 'none' })
        return
      }
      console.log('[VP-plan] code:', loginRes.code.slice(0, 20) + '...')
      const res = await uni.request({
        url: api('/virtual-payment/create'), method: 'POST',
        data: { type: selectedPlan, quantity: 1, wxCode: loginRes.code },
        header: { 'Authorization': `Bearer ${t}`, 'Content-Type': 'application/json' },
        timeout: 30000,
      })
      console.log('[VP-plan] 创建订单:', res.statusCode, JSON.stringify(res.data).slice(0, 500))
      payLoading.value = false

      if (checkAuth(res)) return
      if (res.statusCode >= 200 && res.statusCode < 300 && res.data?.paySig) {
        const vp = res.data
        currentOutTradeNo.value = vp.outTradeNo
        wx.requestVirtualPayment({
          env: vp.env, mode: vp.mode, offerId: vp.offerId,
          signData: vp.signData,
          paySig: vp.paySig, signature: vp.signature,
          success: () => {
            console.log('[VP-plan] 支付成功')
            vpStatus.value = true
            vpSuccess.value = true
            vpStatusText.value = '套餐已激活'
            uni.showToast({ title: '开通成功！', icon: 'success' })
            plan.value = selectedPlan
            currentPlanName.value = selectedPlan === 'sprint' ? '冲刺版' : '成长版'
            refreshState()
          },
          fail: (err2) => {
            console.error('[VP-plan] 支付失败:', JSON.stringify(err2))
            vpStatus.value = true
            vpSuccess.value = false
            vpStatusText.value = friendlyVpError(err2?.errMsg) || '你已取消支付'
          },
        })
      } else {
        const msg = res.data?.message || res.data?.msg || `请求失败(${res.statusCode})`
        payError.value = msg
        console.error('[VP-plan] 订单创建失败:', res.statusCode, JSON.stringify(res.data))
        uni.showToast({ title: msg, icon: 'none' })
      }
    } catch (e) {
      payLoading.value = false
      payError.value = '网络错误，请重试'
      console.error('[VP-plan] 异常:', e)
      uni.showToast({ title: '网络错误', icon: 'none' })
    }
  } else {
    try {
      const res = await uni.request({
        url: api('/payment/create'), method: 'POST',
        data: { plan: selectedPlan },
        header: { 'Authorization': `Bearer ${t}`, 'Content-Type': 'application/json' },
      })
      payLoading.value = false
      if (res.statusCode >= 200 && res.statusCode < 300 && res.data?.codeUrl) {
        payCodeUrl.value = res.data.codeUrl
        currentOutTradeNo.value = res.data.outTradeNo
        pollPayResult(res.data.outTradeNo, selectedPlan)
      } else {
        if (checkAuth(res)) return
        payError.value = res.data?.message || '创建订单失败'
      }
    } catch (e) {
      payLoading.value = false
      payError.value = '网络错误，请重试'
    }
  }
}

/** 轮询订单状态 */
const pollPayResult = (outTradeNo, selectedPlan) => {
  if (!outTradeNo) return
  let attempts = 0
  const poll = async () => {
    attempts++
    try {
      const res = await uni.request({
        url: api(`/payment/check/${outTradeNo}`), method: 'GET',
        header: { 'Authorization': `Bearer ${token()}` },
      })
      if (checkAuth(res)) return
      if (res.statusCode >= 200 && res.statusCode < 300 && res.data?.status === 'success') {
        await activatePlan(outTradeNo, selectedPlan)
        return
      }
    } catch (e) { /* ignore */ }
    if (attempts < 30) setTimeout(poll, 2000)
    else { payError.value = '支付结果查询超时，请联系客服' }
  }
  setTimeout(poll, 2000)
}

/** 激活套餐 */
const activatePlan = async (outTradeNo, selectedPlan) => {
  try {
    const res = await uni.request({
      url: api('/payment/activate'), method: 'POST',
      data: { outTradeNo },
      header: { 'Authorization': `Bearer ${token()}`, 'Content-Type': 'application/json' },
    })
    if (res.statusCode >= 200 && res.statusCode < 300 && res.data?.success) {
      paySuccess.value = true
      showPayModal.value = false
      plan.value = selectedPlan
      currentPlanName.value = selectedPlan === 'sprint' ? '冲刺版' : '成长版'
      uni.showToast({ title: '🎉 开通成功！', icon: 'success' })
      refreshState()
    } else {
      if (checkAuth(res)) return
      uni.showToast({ title: res.data?.message || '激活失败', icon: 'none' })
    }
  } catch (e) {
    payError.value = '激活失败，请联系客服'
    uni.showToast({ title: '激活失败', icon: 'none' })
  }
}
</script>

<style scoped>
.page { min-height: 100vh; background: var(--color-bg); padding-bottom: 40rpx; }

/* 状态栏 */
.status-bar { display: flex; justify-content: space-between; align-items: center; background: linear-gradient(135deg, var(--color-gradient-start), var(--color-gradient-mid)); padding: 32rpx; color: #fff; }
.status-left { display: flex; flex-direction: column; gap: 4rpx; }
.status-label { font-size: 22rpx; opacity: 0.85; }
.status-plan { font-size: 34rpx; font-weight: 700; }
.status-right { display: flex; flex-direction: column; align-items: flex-end; gap: 4rpx; }
.grav-label { font-size: 22rpx; opacity: 0.85; }
.grav-num { font-size: 40rpx; font-weight: 800; }

/* 登录提示 */
.login-bar { display: flex; align-items: center; justify-content: space-between; margin: 24rpx 24rpx 0; background: #FEF3C7; border-radius: var(--radius-lg); padding: 20rpx 24rpx; }
.login-text { font-size: 24rpx; color: #92400E; }
.login-btn { font-size: 24rpx; color: #FFF; background: var(--color-primary); padding: 8rpx 24rpx; border-radius: var(--radius-sm); }

/* 区块 */
.section { padding: 0 24rpx; margin-top: 24rpx; }
.section-title { font-size: 28rpx; font-weight: 700; color: var(--color-text); display: block; margin-bottom: 16rpx; }

/* 购买区 */
.buy-card { background: #fff; border-radius: var(--radius-lg); padding: 24rpx; box-shadow: var(--shadow-sm); }
.qty-row { margin-bottom: 16rpx; }
.qty-label { font-size: 24rpx; font-weight: 600; color: var(--color-text); display: block; margin-bottom: 12rpx; }
.qty-controls { display: flex; align-items: center; justify-content: center; gap: 24rpx; }
.qty-btn { width: 60rpx; height: 60rpx; border-radius: 50%; background: #F3F4F6; display: flex; align-items: center; justify-content: center; font-size: 32rpx; font-weight: 500; color: var(--color-text); }
.qty-btn.disabled { color: #D1D5DB; background: #F9FAFB; }
.qty-input { width: 120rpx; height: 64rpx; text-align: center; font-size: 32rpx; font-weight: 700; color: var(--color-text); border: 2rpx solid #E5E7EB; border-radius: var(--radius-sm); }
.summary { margin-bottom: 20rpx; }
.summary-row { display: flex; justify-content: space-between; padding: 8rpx 0; border-bottom: 1rpx solid #F3F4F6; }
.summary-row.total { border-bottom: none; padding-top: 12rpx; }
.summary-label { font-size: 22rpx; color: var(--color-text-secondary); }
.summary-val { font-size: 24rpx; font-weight: 600; color: var(--color-text); }
.summary-val.highlight { color: var(--color-primary); }
.total-price { font-size: 32rpx; font-weight: 800; color: var(--color-primary); }
.buy-btn { width: 100%; height: 80rpx; background: linear-gradient(135deg, var(--color-gradient-start), var(--color-gradient-mid)); color: #fff; font-size: 28rpx; font-weight: 600; border-radius: var(--radius-lg); display: flex; align-items: center; justify-content: center; border: none; }
.buy-btn:active { opacity: 0.85; }
.buy-btn[disabled] { opacity: 0.5; }

/* 套餐列表 */
.plan-list { display: flex; flex-direction: column; gap: 16rpx; }
.plan-card { background: #fff; border-radius: var(--radius-lg); padding: 24rpx; box-shadow: var(--shadow-sm); position: relative; }
.plan-card.popular { border: 2rpx solid var(--color-primary); }
.plan-card.current { background: #F0F7FF; border: 2rpx solid var(--color-primary); }
.plan-header { display: flex; justify-content: space-between; align-items: baseline; margin-bottom: 12rpx; }
.plan-name { font-size: 30rpx; font-weight: 700; color: var(--color-text); }
.price-num { font-size: 32rpx; font-weight: 800; color: var(--color-primary); }
.plan-badge { background: var(--color-primary); color: #fff; font-size: 20rpx; padding: 4rpx 14rpx; border-radius: 20rpx; }
.plan-features { display: flex; flex-direction: column; gap: 8rpx; margin-bottom: 16rpx; }
.feature { font-size: 22rpx; color: var(--color-text-secondary); }
.plan-action { text-align: center; padding: 16rpx; border-radius: var(--radius-md); font-size: 26rpx; font-weight: 600; background: linear-gradient(135deg, var(--color-gradient-start), var(--color-gradient-mid)); color: #fff; }
.plan-action.owned { background: #ECFDF5; color: var(--color-success); }

/* 弹窗 */
.modal-overlay { position: fixed; top: 0; left: 0; right: 0; bottom: 0; background: rgba(0,0,0,0.5); display: flex; align-items: center; justify-content: center; z-index: 100; }
.modal-content { background: #FFF; border-radius: var(--radius-xl); padding: 40rpx; width: 70%; display: flex; flex-direction: column; align-items: center; gap: 20rpx; }
.modal-title { font-size: 28rpx; font-weight: 600; color: var(--color-text); }
.pay-error { color: var(--color-error); }
.qr-canvas { width: 400rpx; height: 400rpx; }
.modal-hint { font-size: 22rpx; color: var(--color-text-tertiary); }
.modal-close { font-size: 22rpx; color: var(--color-text-tertiary); padding: 8rpx; }
</style>
