import { ref, computed, nextTick } from 'vue'
import { api } from '../config'

export function useGravityPurchase(onPaymentSuccess?: () => void) {
  const showQuantityModal = ref(false)
  const buyQuantity = ref(1)
  const products = ref<any[]>([])
  const buyProductType = ref('interview')
  const payLoading = ref(false)
  const payError = ref('')
  const showPayModal = ref(false)
  const payCodeUrl = ref('')
  const currentOutTradeNo = ref('')
  const isMp = ref(false)
  const paySuccess = ref(false)

  const unitPrice = computed(() => {
    const p = products.value.find(p => p.type === buyProductType.value)
    return p?.price || 0
  })
  const totalPrice = computed(() => unitPrice.value * buyQuantity.value / 100)
  const buyGravityPerUnit = computed(() => {
    const p = products.value.find(p => p.type === buyProductType.value)
    return p?.gravity || 0
  })

  const changeQty = (delta: number) => {
    const next = buyQuantity.value + delta
    if (next >= 1 && next <= 99) buyQuantity.value = next
  }
  const clampQty = () => {
    if (buyQuantity.value < 1) buyQuantity.value = 1
    if (buyQuantity.value > 99) buyQuantity.value = 99
  }

  const loadProducts = async () => {
    try {
      const res = await uni.request({ url: api('/member/plans'), method: 'GET' })
      if (res.statusCode >= 200 && res.statusCode < 300 && res.data?.products) {
        const prodList: any[] = []
        for (const [key, val] of Object.entries(res.data.products as Record<string, any>)) {
          if (val?.price > 0) prodList.push({ type: key, ...val })
        }
        products.value = prodList
      }
    } catch (e) { /* silent */ }
  }

  const openGravityPurchase = async (productType = 'interview') => {
    buyProductType.value = productType
    buyQuantity.value = 1
    // #ifdef MP-WEIXIN
    isMp.value = true
    // #endif
    // 加载产品信息
    await loadProducts()
    showQuantityModal.value = true
  }

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

  const confirmProductBuy = () => {
    showQuantityModal.value = false
    startProductPay(buyProductType.value, buyQuantity.value)
  }

  const startProductPay = async (type: string, quantity = 1) => {
    const token = uni.getStorageSync('token') || ''
    if (!token) {
      uni.showToast({ title: '请先登录', icon: 'none' })
      return
    }
    showPayModal.value = true
    payLoading.value = true
    payError.value = ''

    if (isMp.value) {
      try {
        const loginRes = await new Promise<{ code: string }>((resolve, reject) => {
          uni.login({ provider: 'weixin', success: r => resolve(r), fail: reject })
        })
        if (!loginRes.code) {
          payLoading.value = false
          payError.value = '微信登录失败，请重试'
          uni.showToast({ title: '微信登录失败', icon: 'none' })
          return
        }

        const res = await uni.request({
          url: api('/virtual-payment/create'), method: 'POST',
          data: { type, quantity, wxCode: loginRes.code },
          header: { 'Authorization': `Bearer ${token}`, 'Content-Type': 'application/json' },
          timeout: 30000,
        })
        payLoading.value = false

        if (res.statusCode >= 200 && res.statusCode < 300 && res.data?.paySig) {
          const vp = res.data as any
          currentOutTradeNo.value = vp.outTradeNo

          ;(wx as any).requestVirtualPayment({
            env: vp.env,
            offerId: vp.offerId,
            signData: vp.signData,
            paySig: vp.paySig,
            signature: vp.signature,
            success: () => {
              const no = currentOutTradeNo.value || vp.outTradeNo
              pollPayResult(no)
            },
            fail: (err: any) => {
              payError.value = '支付未完成'
              uni.showToast({ title: err?.errMsg || '支付未完成', icon: 'none' })
            },
          })
        } else if (!res.statusCode || res.statusCode === 0) {
          payError.value = '网络连接失败，请检查网络后重试'
          uni.showToast({ title: '网络连接失败', icon: 'none' })
        } else {
          const errMsg = res.data?.message || '购买失败'
          payError.value = errMsg
          uni.showToast({ title: errMsg, icon: 'none' })
        }
      } catch (e: any) {
        payLoading.value = false
        payError.value = e?.errMsg || '网络错误，请重试'
        uni.showToast({ title: '网络错误', icon: 'none' })
      }
    } else {
      try {
        const res = await uni.request({
          url: api('/payment/create-product'), method: 'POST',
          data: { type, quantity },
          header: { 'Authorization': `Bearer ${token}`, '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
          // 页面需要自己渲染二维码（依赖 uqrcode）
          pollPayResult(res.data.outTradeNo)
        } else if (!res.statusCode || res.statusCode === 0) {
          payError.value = '网络连接失败，请检查网络后重试'
          uni.showToast({ title: '网络连接失败', icon: 'none' })
        } else {
          payError.value = res.data?.message || '购买失败'
          uni.showToast({ title: res.data?.message || '购买失败', icon: 'none' })
        }
      } catch (e) {
        payLoading.value = false
        payError.value = '网络错误，请重试'
        uni.showToast({ title: '网络错误', icon: 'none' })
      }
    }
  }

  const pollPayResult = async (outTradeNo: string) => {
    if (!outTradeNo) return
    const maxAttempts = 30
    let attempts = 0
    const token = uni.getStorageSync('token') || ''

    const poll = async () => {
      attempts++
      try {
        const res = await uni.request({
          url: api(`/payment/check/${outTradeNo}`), method: 'GET',
          header: { 'Authorization': `Bearer ${token}` },
        })
        if (res.statusCode >= 200 && res.statusCode < 300 && res.data?.status === 'success') {
          paySuccess.value = true
          showPayModal.value = false
          uni.showToast({ title: '充值成功！', icon: 'success' })
          onPaymentSuccess?.()
          return
        }
      } catch (e) { /* ignore */ }

      if (attempts < maxAttempts) {
        setTimeout(poll, 2000)
      } else {
        payError.value = '支付结果查询超时，请联系客服'
        uni.showToast({ title: '支付查询超时', icon: 'none' })
      }
    }
    setTimeout(poll, 2000)
  }

  return {
    showQuantityModal, buyQuantity, products, buyProductType,
    unitPrice, totalPrice, buyGravityPerUnit,
    payLoading, payError, showPayModal, payCodeUrl, paySuccess,
    isMp,
    changeQty, clampQty, loadProducts, openGravityPurchase,
    confirmProductBuy, cancelPay,
  }
}
