import React, { useEffect, useMemo, useRef, useState } from 'react'
import { View, Text } from '@tarojs/components'
import Taro, { useDidShow, useRouter } from '@tarojs/taro'
import { Button, Card, ConfigProvider } from '@nutui/nutui-react-taro'
import { Scan, Success, Failure, Tips } from '@nutui/icons-react-taro'

import { decryptQrData } from '@/api/shop/shopGift'
import { getGltUserTicket, updateGltUserTicket } from '@/api/glt/gltUserTicket'
import type { GltUserTicket } from '@/api/glt/gltUserTicket/model'
import { isValidJSON } from '@/utils/jsonUtils'
import { useUser } from '@/hooks/useUser'

type TicketPayload = {
  userTicketId: number
  qty?: number
  userId?: number
  t?: number
}

type VerifyRecord = {
  id: number
  time: string
  success: boolean
  message: string
  ticketName?: string
  userInfo?: string
  qty?: number
}

const RiderTicketVerificationPage: React.FC = () => {
  const { hasRole, isAdmin } = useUser()
  const router = useRouter()
  const [loading, setLoading] = useState(false)
  const [lastTicket, setLastTicket] = useState<GltUserTicket | null>(null)
  const [lastQty, setLastQty] = useState<number>(1)
  const [records, setRecords] = useState<VerifyRecord[]>([])

  const autoScanOnceRef = useRef(false)

  const canVerify = useMemo(() => {
    return (
      hasRole('rider') ||
      hasRole('store') ||
      hasRole('staff') ||
      hasRole('admin') ||
      isAdmin()
    )
  }, [hasRole, isAdmin])

  const autoScanEnabled = useMemo(() => {
    const p: any = router?.params || {}
    return p.auto === '1' || p.auto === 'true'
  }, [router])

  const addRecord = (rec: Omit<VerifyRecord, 'id' | 'time'>) => {
    const item: VerifyRecord = {
      id: Date.now(),
      time: new Date().toLocaleString(),
      ...rec
    }
    setRecords(prev => [item, ...prev].slice(0, 10))
  }

  const parsePayload = (raw: string): TicketPayload => {
    const trimmed = raw.trim()
    if (!isValidJSON(trimmed)) throw new Error('无效的水票核销信息')
    const payload = JSON.parse(trimmed) as TicketPayload
    const userTicketId = Number(payload.userTicketId)
    const qty = Math.max(1, Number(payload.qty || 1))
    if (!Number.isFinite(userTicketId) || userTicketId <= 0) {
      throw new Error('水票核销信息无效')
    }
    return { ...payload, userTicketId, qty }
  }

  const extractPayloadFromScanResult = async (scanResult: string): Promise<TicketPayload> => {
    const trimmed = scanResult.trim()

    // 1) 加密二维码：{ businessType, token, data }
    if (isValidJSON(trimmed)) {
      const json = JSON.parse(trimmed) as any
      if (json?.businessType && json?.token && json?.data) {
        if (json.businessType !== 'ticket') {
          throw new Error('请扫描水票核销码')
        }
        const decrypted = await decryptQrData({
          token: String(json.token),
          encryptedData: String(json.data)
        })
        return parsePayload(String(decrypted || ''))
      }

      // 2) 明文 payload（内部调试/非加密二维码）
      if (json?.userTicketId) {
        return parsePayload(trimmed)
      }
    }

    throw new Error('无效的水票核销码')
  }

  const verifyTicket = async (payload: TicketPayload) => {
    const userTicketId = Number(payload.userTicketId)
    const qty = Math.max(1, Number(payload.qty || 1))

    const ticket = await getGltUserTicket(userTicketId)
    if (!ticket) throw new Error('水票不存在')
    if (ticket.status === 1) throw new Error('该水票已冻结')
    const available = Number(ticket.availableQty || 0)
    const used = Number(ticket.usedQty || 0)
    if (available < qty) throw new Error('水票可用次数不足')

    const lines: string[] = []
    lines.push(`水票：${ticket.templateName || '水票'}`)
    lines.push(`本次核销：${qty} 次`)
    lines.push(`剩余可用：${available - qty} 次`)
    if (ticket.phone) lines.push(`用户手机号：${ticket.phone}`)
    if (ticket.nickname) lines.push(`用户昵称：${ticket.nickname}`)

    const modalRes = await Taro.showModal({
      title: '确认核销',
      content: lines.join('\n')
    })
    if (!modalRes.confirm) return

    await updateGltUserTicket({
      ...ticket,
      availableQty: available - qty,
      usedQty: used + qty
    })

    setLastTicket({
      ...ticket,
      availableQty: available - qty,
      usedQty: used + qty
    })
    setLastQty(qty)

    addRecord({
      success: true,
      message: `核销成功（${qty}次）`,
      ticketName: ticket.templateName || '水票',
      userInfo: [ticket.nickname, ticket.phone].filter(Boolean).join(' / ') || undefined,
      qty
    })
    Taro.showToast({ title: '核销成功', icon: 'success' })
  }

  const handleScan = async () => {
    if (loading) return
    if (!canVerify) {
      Taro.showToast({ title: '您没有核销权限', icon: 'none' })
      return
    }

    try {
      setLoading(true)
      const res = await Taro.scanCode({})
      const scanResult = res?.result
      if (!scanResult) throw new Error('未识别到二维码内容')

      const payload = await extractPayloadFromScanResult(scanResult)
      await verifyTicket(payload)
    } catch (e: any) {
      const msg = e?.message || '核销失败'
      addRecord({ success: false, message: msg })
      Taro.showToast({ title: msg, icon: 'none' })
    } finally {
      setLoading(false)
    }
  }

  // If navigated in "auto" mode, open scan on first show when user has permission.
  useDidShow(() => {
    // Reset the flag when user manually re-enters the page via navigation again.
    // (This runs on every show; only the first show with auto enabled will trigger scan.)
    if (!autoScanEnabled) autoScanOnceRef.current = false
  })

  useEffect(() => {
    if (!autoScanEnabled) return
    if (autoScanOnceRef.current) return
    if (!canVerify) return
    autoScanOnceRef.current = true
    // Defer to ensure page is fully mounted before opening camera.
    setTimeout(() => {
      handleScan().catch(() => {})
    }, 80)
    // eslint-disable-next-line react-hooks/exhaustive-deps
  }, [autoScanEnabled, canVerify])

  return (
    <ConfigProvider>
      <View className="min-h-screen bg-gray-50 p-4">
        <Card>
          <View className="flex items-center justify-between">
            <View>
              <Text className="text-base font-bold text-gray-800">水票核销</Text>
              <View className="mt-1">
                <Text className="text-xs text-gray-500">
                  扫描用户出示的“水票核销码”完成核销
                </Text>
              </View>
            </View>
            <Tips className="text-gray-400" size="18" />
          </View>

          <View className="mt-4">
            <Button
              type="primary"
              block
              loading={loading}
              icon={<Scan />}
              onClick={handleScan}
            >
              扫码核销
            </Button>
          </View>

          {lastTicket && (
            <View className="mt-4 bg-gray-50 rounded-lg p-3">
              <View className="flex items-center justify-between">
                <Text className="text-sm text-gray-700">最近一次核销</Text>
                <Text className="text-xs text-gray-500">使用 {lastQty} 次</Text>
              </View>
              <View className="mt-2">
                <Text className="text-sm text-gray-900">
                  {lastTicket.templateName || '水票'}（剩余 {lastTicket.availableQty ?? 0} 次）
                </Text>
              </View>
            </View>
          )}
        </Card>

        <View className="mt-4">
          <View className="mb-2">
            <Text className="text-sm font-semibold text-gray-800">核销记录</Text>
            <Text className="text-xs text-gray-500 ml-2">仅保留最近10条</Text>
          </View>
          {records.length === 0 ? (
            <View className="bg-white rounded-lg p-4">
              <Text className="text-sm text-gray-500">暂无记录</Text>
            </View>
          ) : (
            <View className="space-y-2">
              {records.map(r => (
                <View key={r.id} className="bg-white rounded-lg p-3 flex items-start justify-between">
                  <View className="flex-1 pr-3">
                    <View className="flex items-center">
                      {r.success ? (
                        <Success className="text-green-500 mr-2" size="16" />
                      ) : (
                        <Failure className="text-red-500 mr-2" size="16" />
                      )}
                      <Text className="text-sm text-gray-900">{r.message}</Text>
                    </View>
                    <View className="mt-1">
                      <Text className="text-xs text-gray-500">
                        {r.time}
                        {r.ticketName ? ` · ${r.ticketName}` : ''}
                        {typeof r.qty === 'number' ? ` · ${r.qty}次` : ''}
                      </Text>
                    </View>
                    {r.userInfo && (
                      <View className="mt-1">
                        <Text className="text-xs text-gray-500">{r.userInfo}</Text>
                      </View>
                    )}
                  </View>
                </View>
              ))}
            </View>
          )}
        </View>
      </View>
    </ConfigProvider>
  )
}

export default RiderTicketVerificationPage
