import React, { useState, useEffect, useCallback } from 'react'
import { View, Text } from '@tarojs/components'
import { Button, Cell, Price, Divider } from '@nutui/nutui-react-taro'
import { Check, Close, Tips, Clock } from '@nutui/icons-react-taro'
import Taro from '@tarojs/taro'
import { request } from '@/utils/request'
import { getOpenId, loginByOpenId } from '@/api/passport/wx-login'
import { saveStorageByLoginUser } from '@/utils/server'
import { TenantId } from '@/config/app'

/**
 * 小程序支付页面
 * 接收参数 subscriptionNo，完成 JSAPI 支付
 *
 * 重要：判断订单是否已支付，必须用 payStatus（0=未支付 1=已支付），
 * 不能用 status（订阅生命周期：active/pending/expired/cancelled）。
 * 续费场景下后端 renewPay 会保留原 status=active、仅设 payStatus=0，
 * 若用 status 判支付会直接误判为"已支付"。
 */
interface SubscriptionDetail {
  id: number
  subscriptionNo: string
  productId: number
  productName: string
  productLogo?: string
  productIcon?: string
  status: string
  // 支付状态: 0-未支付 1-已支付
  payStatus?: number
  payTime?: string
  transactionId?: string
  priceType: string
  payPrice: number
  subscriptionPeriod?: string
}

interface JsapiPayParams {
  timeStamp: string
  nonceStr: string
  package: string
  signType: string
  paySign: string
  outTradeNo: string
}

const PayPage: React.FC = () => {
  const [loading, setLoading] = useState(true)
  const [paying, setPaying] = useState(false)
  const [detail, setDetail] = useState<SubscriptionDetail | null>(null)
  const [errorMsg, setErrorMsg] = useState('')
  const [paid, setPaid] = useState(false)

  // 从页面参数中获取 subscriptionNo
  // 小程序码 scene 会作为 query.scene 传入，需解码
  const getSubscriptionNo = useCallback(() => {
    const instance = Taro.getCurrentInstance()
    const params = instance?.router?.params || {}
    console.log('[PayPage] ===== 参数调试开始 =====')
    console.log('[PayPage] 原始 params:', JSON.stringify(params))
    console.log('[PayPage] params.scene:', params.scene)
    console.log('[PayPage] params.subscriptionNo:', params.subscriptionNo)
    // 优先读取 scene（小程序码参数），再读取 subscriptionNo（普通链接参数）
    const scene = params.scene ? decodeURIComponent(params.scene) : ''
    const subscriptionNo = scene || params.subscriptionNo || ''
    console.log('[PayPage] decodeURIComponent(scene):', scene)
    console.log('[PayPage] 最终 subscriptionNo:', subscriptionNo)
    console.log('[PayPage] ===== 参数调试结束 =====')
    return subscriptionNo
  }, [])

  // 获取订阅详情
  const fetchDetail = useCallback(async () => {
    const subscriptionNo = getSubscriptionNo()
    if (!subscriptionNo) {
      console.error('[PayPage] subscriptionNo 为空，无法请求')
      setErrorMsg('缺少订单参数')
      setLoading(false)
      return
    }

    console.log('[PayPage] ===== 请求调试开始 =====')
    console.log('[PayPage] 请求 URL:', `/app/subscription/detail-by-no/${subscriptionNo}`)
    console.log('[PayPage] 当前 token:', Taro.getStorageSync('access_token') || '(无token)')

    try {
      // request 默认 returnRaw=false，拦截器已拆包，返回的就是 data 部分（订阅对象）
      const data: any = await request({
        url: `/app/subscription/detail-by-no/${subscriptionNo}`,
        method: 'GET',
        returnRaw: true  // 先用 returnRaw=true 拿到完整响应，方便调试
      })

      console.log('[PayPage] 接口完整返回（returnRaw=true）:', JSON.stringify(data))
      console.log('[PayPage] data.code:', data?.code)
      console.log('[PayPage] data.message:', data?.message)
      console.log('[PayPage] data.data:', data?.data)

      // 判断业务状态码
      if (data?.code === 0 || data?.code === 200) {
        const subscription = data.data || data
        console.log('[PayPage] 订阅对象:', JSON.stringify(subscription))
        console.log('[PayPage] 订阅状态 status:', subscription?.status)
        console.log('[PayPage] 支付状态 payStatus:', subscription?.payStatus)
        console.log('[PayPage] 支付时间 payTime:', subscription?.payTime)

        // 关键修复：判断是否已支付，必须用 payStatus 而非 status
        // 续费场景下后端 renewPay 会保留原 status=active、仅设 payStatus=0
        const isPaid = subscription?.payStatus === 1
        const isCancelled = subscription?.status === 'cancelled'
        const isExpired = subscription?.status === 'expired'

        if (isCancelled) {
          setErrorMsg('订单已取消，无法继续支付')
        } else if (isExpired) {
          setErrorMsg('订单已过期，请重新下单')
        } else if (isPaid) {
          setPaid(true)
          setDetail(subscription)
        } else {
          setDetail(subscription)
        }
      } else {
        console.error('[PayPage] 业务错误 code:', data?.code, 'message:', data?.message)
        setErrorMsg(data?.message || `业务错误(code=${data?.code})`)
      }
    } catch (err: any) {
      console.error('[PayPage] ===== 请求异常 =====')
      console.error('[PayPage] err.name:', err?.name)
      console.error('[PayPage] err.type:', err?.type)
      console.error('[PayPage] err.code:', err?.code)
      console.error('[PayPage] err.message:', err?.message)
      console.error('[PayPage] err.data:', err?.data)
      console.error('[PayPage] err 完整:', JSON.stringify(err))
      setErrorMsg(err?.message || '网络异常，请重试')
    } finally {
      setLoading(false)
      console.log('[PayPage] ===== 请求调试结束 =====')
    }
  }, [getSubscriptionNo])

  useEffect(() => {
    fetchDetail()
  }, [fetchDetail])

  // 执行支付
  const handlePay = async () => {
    if (!detail) return

    setPaying(true)
    try {
      // 1. 获取微信登录凭证（code）
      const loginRes = await Taro.login()
      if (!loginRes.code) {
        throw new Error('获取登录凭证失败')
      }

      console.log('[PayPage] Taro.login code:', loginRes.code)

      // 2. 用 code 换取 openid（关键步骤，之前遗漏了）
      const openIdRes = await getOpenId(loginRes.code)
      console.log('[PayPage] getOpenId 结果:', openIdRes)

      if (!openIdRes.success || !openIdRes.openid) {
        throw new Error(openIdRes.message || '获取 openid 失败，请重试')
      }

      const openid = openIdRes.openid
      // 缓存 openid，后续支付确认等接口可用
      Taro.setStorageSync('openid', openid)
      console.log('[PayPage] 获取到 openid:', openid)

      // 3. 尝试自动登录（获取 token，mp-prepay 接口需要登录态）
      // 如果用户已在小程序注册过，loginByOpenId 会返回 token
      // 如果用户未注册，不影响 openid 已获取，但 mp-prepay 可能需要特殊处理
      try {
        const loginResult = await loginByOpenId({
          code: loginRes.code,
          tenantId: TenantId
        })
        console.log('[PayPage] loginByOpenId 结果:', loginResult)

        if (loginResult.success && loginResult.data) {
          // 登录成功，保存 token
          saveStorageByLoginUser(loginResult.data.access_token || '', loginResult.data.user)
          console.log('[PayPage] 自动登录成功，已保存 token')
        } else {
          console.warn('[PayPage] 自动登录失败:', loginResult.message)
          // 未注册用户：openid 已经有了，但 mp-prepay 需要 userId
          // 提示用户先注册/登录
          if (loginResult.message?.includes('未注册') || loginResult.message?.includes('不存在')) {
            Taro.showModal({
              title: '需要先登录',
              content: '支付前需要先注册账号，是否前往登录？',
              confirmText: '去登录',
              cancelText: '取消'
            }).then(modalRes => {
              if (modalRes.confirm) {
                Taro.navigateTo({ url: '/passport/login' })
              }
            })
            return // 不继续支付流程
          }
        }
      } catch (loginErr) {
        console.warn('[PayPage] 自动登录异常:', loginErr)
        // 登录异常但不阻断支付，openid 已拿到，尝试继续
      }

      // 4. 请求后端创建 JSAPI 预支付订单
      const prepayRes: any = await request({
        url: `/app/subscription/mp-prepay/${detail.id}`,
        method: 'POST',
        data: { openid },
        returnRaw: true
      })

      console.log('[PayPage] mp-prepay 完整返回:', JSON.stringify(prepayRes))

      if (prepayRes?.code !== 0 && prepayRes?.code !== 200) {
        throw new Error(prepayRes?.message || '创建支付订单失败')
      }

      const payParams: JsapiPayParams = prepayRes.data || prepayRes

      if (!payParams.timeStamp || !payParams.package || !payParams.paySign) {
        throw new Error('支付参数不完整')
      }

      // 5. 调用微信支付
      await Taro.requestPayment({
        timeStamp: payParams.timeStamp,
        nonceStr: payParams.nonceStr,
        package: payParams.package,
        signType: (payParams.signType || 'RSA') as any,
        paySign: payParams.paySign
      })

      // 6. 支付成功后通知后端确认
      try {
        await request({
          url: `/app/subscription/mp-confirm/${detail.subscriptionNo}`,
          method: 'POST',
          data: {}
        })
      } catch (confirmErr) {
        console.warn('支付确认通知失败，等待轮询:', confirmErr)
      }

      // 7. 显示成功状态
      setPaid(true)
      Taro.showToast({ title: '支付成功', icon: 'success' })

      // 8. 延迟自动跳转到已购产品页面
      setTimeout(() => {
        Taro.navigateTo({ url: '/user/apps/index' }).catch(() => {
          // 如果 navigateTo 失败（比如在 tab 页），回退到用户页
          Taro.switchTab({ url: '/pages/user/user' })
        })
      }, 1500)

    } catch (err: any) {
      console.error('[PayPage] 支付失败:', err)
      console.error('[PayPage] err.name:', err?.name, 'err.type:', err?.type)
      console.error('[PayPage] err.code:', err?.code, 'err.message:', err?.message)

      if (err?.errMsg?.includes('cancel')) {
        Taro.showToast({ title: '支付已取消', icon: 'none' })
      } else {
        const msg = err?.message || err?.errMsg || '支付失败，请重试'
        Taro.showToast({ title: msg, icon: 'error', duration: 2000 })
      }
    } finally {
      setPaying(false)
    }
  }

  // 返回
  const handleBack = () => {
    Taro.navigateBack({ delta: 1 }).catch(() => {
      Taro.switchTab({ url: '/pages/user/user' })
    })
  }

  // 格式化价格描述
  const getPriceDesc = () => {
    if (!detail) return ''
    if (detail.priceType === 'one_time') return '永久买断'
    if (detail.priceType === 'subscription') {
      return detail.subscriptionPeriod === 'year' ? '按年订阅' : '按月订阅'
    }
    return ''
  }

  // --- 加载中 ---
  if (loading) {
    return (
      <View className="pay-page min-h-screen bg-gray-50 flex items-center justify-center">
        <View className="text-center">
          <Clock className="text-blue-500 mb-4" size="48" />
          <Text className="block text-gray-500">加载订单信息...</Text>
        </View>
      </View>
    )
  }

  // --- 错误 ---
  if (errorMsg) {
    return (
      <View className="pay-page min-h-screen bg-gray-50 flex items-center justify-center">
        <View className="text-center p-8">
          <Close className="text-red-500 mb-4" size="48" />
          <Text className="block text-gray-800 text-lg mb-2">获取订单失败</Text>
          <Text className="block text-gray-500 mb-6">{errorMsg}</Text>
          <Button type="primary" onClick={handleBack}>返回</Button>
        </View>
      </View>
    )
  }

  // --- 已支付 ---
  if (paid) {
    return (
      <View className="pay-page min-h-screen bg-gray-50 flex items-center justify-center">
        <View className="text-center p-8">
          <View className="w-20 h-20 bg-green-100 rounded-full flex items-center justify-center mx-auto mb-4">
            <Check className="text-green-500" size="40" />
          </View>
          <Text className="block text-green-600 text-xl font-bold mb-2">支付成功</Text>
          <Text className="block text-gray-500 mb-2">{detail?.productName || '应用订阅'}</Text>
          {detail?.payPrice ? (
            <Text className="block text-gray-400 mb-6">
              已支付 ¥{Number(detail.payPrice).toFixed(2)}
            </Text>
          ) : null}
          <Button type="primary" onClick={handleBack}>完成</Button>
        </View>
      </View>
    )
  }

  // --- 支付确认 ---
  return (
    <View className="pay-page min-h-screen bg-gray-50">
      <View className="p-4">
        {/* 订单信息 */}
        <View className="bg-white rounded-lg shadow-sm p-4 mb-4">
          <Text className="block text-lg font-bold text-gray-800 mb-3">确认支付</Text>

          <Cell title="商品名称" description={detail?.productName || '-'} />
          <Cell title="价格类型" description={getPriceDesc()} />

          <View className="flex items-center justify-between px-4 py-3">
            <Text className="text-gray-600">支付金额</Text>
            <Price
              price={detail?.payPrice}
              size="large"
              thousands
            />
          </View>

          <Divider />

          <View className="flex items-start px-4 py-2">
            <Tips className="text-orange-500 mr-2 mt-1" size="16" />
            <Text className="text-sm text-gray-500">
              支付成功后即可在「已购产品」中使用该应用
            </Text>
          </View>
        </View>

        {/* 支付按钮 */}
        <View className="fixed bottom-0 left-0 right-0 p-4 bg-white border-t border-gray-100">
          <View className="flex gap-3">
            <Button
              block
              onClick={handleBack}
              className="flex-1"
            >
              取消
            </Button>
            <Button
              type="primary"
              block
              loading={paying}
              onClick={handlePay}
              className="flex-1"
            >
              {paying ? '支付中...' : '立即支付'}
            </Button>
          </View>
        </View>
      </View>

      {/* 底部安全距离占位 */}
      <View style={{ height: '100px' }} />
    </View>
  )
}

export default PayPage
