'use client'

import { useEffect, useMemo, useState } from 'react'
import { CheckCircle2, ClipboardCheck, QrCode, RefreshCw, Search, UserPlus } from 'lucide-react'
import { AdminMetricPanel } from '@/components/admin/AdminMetrics'
import { AdminShell, hasAdminPermission } from '@/components/admin/AdminShell'
import {
  backend,
  type BackendCourseProduct,
  type BackendCourseRegistration,
  type BackendEventProduct,
  type BackendEventRegistration,
  type StaffAccount,
} from '@/lib/backend'

type ProjectKind = 'event' | 'course'
type CheckinProject = { kind: 'event'; item: BackendEventProduct } | { kind: 'course'; item: BackendCourseProduct }
type RegistrationRow = { kind: 'event'; item: BackendEventRegistration } | { kind: 'course'; item: BackendCourseRegistration }
type RegistrationStatus = 'all' | BackendEventRegistration['status']

const statusOptions: { label: string; value: RegistrationStatus }[] = [
  { label: '全部', value: 'all' },
  { label: '待支付', value: 'pending_payment' },
  { label: '未核销', value: 'registered' },
  { label: '候补', value: 'waitlisted' },
  { label: '已核销', value: 'checked_in' },
  { label: '已取消', value: 'cancelled' },
  { label: '未到场', value: 'no_show' },
]

function statusLabel(status: BackendEventRegistration['status']) {
  if (status === 'pending_payment') return '待支付'
  if (status === 'checked_in') return '已核销'
  if (status === 'waitlisted') return '候补'
  if (status === 'cancel_requested') return '取消申请'
  if (status === 'cancelled') return '已取消'
  if (status === 'no_show') return '未到场'
  if (status === 'refunded') return '已处理'
  return '未核销'
}

function projectId(project: CheckinProject) {
  return project.item.productId || project.item.id
}

function projectStartsAt(project: CheckinProject) {
  return project.item.startsAt
}

function projectLocation(project: CheckinProject) {
  if (project.kind === 'event') return project.item.isOnline ? '线上活动' : project.item.location || '-'
  return project.item.location || '-'
}

function formatTime(value: string | null | undefined) {
  if (!value) return '未设时间'
  const date = new Date(value)
  if (Number.isNaN(date.getTime())) return '未设时间'
  return `${date.getMonth() + 1}月${date.getDate()}日 ${String(date.getHours()).padStart(2, '0')}:${String(date.getMinutes()).padStart(2, '0')}`
}

function rowText(row: RegistrationRow) {
  const item = row.item
  return [item.userName, item.userPhone, item.userOrganization, item.registrationNo, item.orderNo, item.checkinCode].join(' ')
}

function normalizePassport(value: string) {
  const raw = value.trim().toUpperCase()
  const match = raw.match(/[A-Z]{5}-?\d{5}/)
  if (!match) return raw
  const compact = match[0].replace('-', '')
  return compact.length === 10 ? `${compact.slice(0, 5)}-${compact.slice(5)}` : match[0]
}

export default function AdminEventCheckinPage() {
  const [account, setAccount] = useState<StaffAccount | null>(null)
  const [kind, setKind] = useState<ProjectKind>('event')
  const [events, setEvents] = useState<BackendEventProduct[]>([])
  const [courses, setCourses] = useState<BackendCourseProduct[]>([])
  const [selectedKey, setSelectedKey] = useState('')
  const [rows, setRows] = useState<RegistrationRow[]>([])
  const [status, setStatus] = useState<RegistrationStatus>('all')
  const [keyword, setKeyword] = useState('')
  const [checkinCode, setCheckinCode] = useState('')
  const [passportInput, setPassportInput] = useState('')
  const [note, setNote] = useState('')
  const [immediateCheckin, setImmediateCheckin] = useState(true)
  const [loading, setLoading] = useState(false)
  const [saving, setSaving] = useState(false)
  const [message, setMessage] = useState('')
  const [error, setError] = useState('')

  const canWriteCheckin = hasAdminPermission(account, ['event_checkin:update', 'course_checkin:update', 'event:checkin'])
  const projects = useMemo<CheckinProject[]>(() => (
    kind === 'event'
      ? events.map((item) => ({ kind: 'event', item }))
      : courses.map((item) => ({ kind: 'course', item }))
  ), [courses, events, kind])
  const selectedProject = useMemo(() => projects.find((project) => `${project.kind}:${projectId(project)}` === selectedKey) || projects[0] || null, [projects, selectedKey])
  const counts = useMemo(() => ({
    total: rows.length,
    checked: rows.filter((row) => row.item.status === 'checked_in').length,
    pending: rows.filter((row) => row.item.status === 'registered').length,
    waitingPayment: rows.filter((row) => row.item.status === 'pending_payment').length,
  }), [rows])
  const visibleRows = useMemo(() => {
    const word = keyword.trim().toLowerCase()
    return word ? rows.filter((row) => rowText(row).toLowerCase().includes(word)) : rows
  }, [keyword, rows])

  async function loadProjects() {
    setLoading(true)
    try {
      const [currentAccount, projectResult] = await Promise.all([
        account ? Promise.resolve(account) : backend.staffMe(),
        backend.staffCheckinProjects({ kind: 'all', range: 'all' }),
      ])
      const eventItems = projectResult.items.filter((item) => item.kind === 'event') as BackendEventProduct[]
      const courseItems = projectResult.items.filter((item) => item.kind === 'course') as BackendCourseProduct[]
      setAccount(currentAccount)
      setEvents(eventItems)
      setCourses(courseItems)
      setSelectedKey((current) => current || (eventItems[0] ? `event:${eventItems[0].productId || eventItems[0].id}` : ''))
      setError('')
    } catch (err) {
      setError(err instanceof Error ? err.message : '核销项目加载失败')
    } finally {
      setLoading(false)
    }
  }

  async function fetchRows(project: CheckinProject, nextStatus = status) {
    const statusParam = nextStatus === 'all' ? '' : nextStatus
    const result = await backend.staffCheckinRegistrations({
      kind: project.kind,
      productId: projectId(project),
      status: statusParam,
      keyword,
      pageSize: '100',
    })
    return project.kind === 'event'
      ? result.items.map((item) => ({ kind: 'event' as const, item: item as BackendEventRegistration }))
      : result.items.map((item) => ({ kind: 'course' as const, item: item as BackendCourseRegistration }))
  }

  async function loadRows(project = selectedProject, nextStatus = status) {
    if (!project) {
      setRows([])
      return
    }
    setLoading(true)
    try {
      setRows(await fetchRows(project, nextStatus))
      setError('')
    } catch (err) {
      setError(err instanceof Error ? err.message : '报名名单加载失败')
    } finally {
      setLoading(false)
    }
  }

  useEffect(() => {
    void loadProjects()
    // eslint-disable-next-line react-hooks/exhaustive-deps
  }, [])

  useEffect(() => {
    void loadRows()
    // eslint-disable-next-line react-hooks/exhaustive-deps
  }, [selectedKey, status])

  async function scanCheckin() {
    if (!selectedProject || !checkinCode.trim()) return
    if (!canWriteCheckin) {
      setError('当前账号没有现场核销权限')
      return
    }
    setSaving(true)
    try {
      const result = await backend.staffCheckinScan({ kind: selectedProject.kind, productId: projectId(selectedProject), checkinCode, source: 'admin_scan', note })
      setMessage('核销成功')
      if (result.alreadyCheckedIn) setMessage('该报名已核销过')
      setCheckinCode('')
      await loadRows()
    } catch (err) {
      setError(err instanceof Error ? err.message : '核销失败')
    } finally {
      setSaving(false)
    }
  }

  async function manualCheckin(row: RegistrationRow) {
    if (!selectedProject || !canWriteCheckin) return
    setSaving(true)
    try {
      const result = await backend.staffCheckinManual({ kind: row.kind, productId: projectId(selectedProject), registrationId: row.item.id, source: 'admin_manual', note })
      setMessage('已核销报名')
      if (result.alreadyCheckedIn) setMessage('该报名已核销过')
      await loadRows()
    } catch (err) {
      setError(err instanceof Error ? err.message : '手动核销失败')
    } finally {
      setSaving(false)
    }
  }

  async function addByPassport() {
    if (!selectedProject || !passportInput.trim()) return
    if (!canWriteCheckin) {
      setError('当前账号没有现场核销权限')
      return
    }
    setSaving(true)
    try {
      const payload = { passportNo: normalizePassport(passportInput), note, checkIn: immediateCheckin, source: 'admin_passport' }
      await backend.staffCheckinPassportRegistration({ kind: selectedProject.kind, productId: projectId(selectedProject), ...payload })
      setMessage(immediateCheckin ? '已加入名单并核销' : '已加入名单')
      setPassportInput('')
      await loadRows()
    } catch (err) {
      setError(err instanceof Error ? err.message : '通行证补录失败')
    } finally {
      setSaving(false)
    }
  }

  return (
    <AdminShell title="现场核销工作台" description="按活动或线下课程查看报名名单，支持核销码核销和现场补录。">
      <div className="flex h-[calc(100vh-88px)] flex-col gap-2 overflow-hidden">
        {(message || error) && (
          <div className={`shrink-0 rounded-[4px] px-3 py-2 text-xs font-bold ${error ? 'bg-red-50 text-red-700' : 'bg-green-50 text-green'}`}>{error || message}</div>
        )}
        <AdminMetricPanel items={[
          { label: '报名', value: counts.total },
          { label: '未核销', value: counts.pending },
          { label: '已核销', value: counts.checked },
          { label: '待支付', value: counts.waitingPayment },
        ]} />

        <section className="grid shrink-0 gap-2 border border-line bg-white p-2 xl:grid-cols-[120px_minmax(220px,1fr)_130px_minmax(180px,1fr)_auto]">
          <select value={kind} onChange={(event) => { setKind(event.target.value as ProjectKind); setSelectedKey('') }} className="h-9 border border-line px-2 text-xs font-bold outline-none focus:border-brand">
            <option value="event">活动</option>
            <option value="course">课程</option>
          </select>
          <select value={selectedKey} onChange={(event) => setSelectedKey(event.target.value)} className="h-9 border border-line px-2 text-xs font-bold outline-none focus:border-brand">
            {projects.map((project) => (
              <option key={`${project.kind}:${projectId(project)}`} value={`${project.kind}:${projectId(project)}`}>{project.item.title}</option>
            ))}
          </select>
          <select value={status} onChange={(event) => setStatus(event.target.value as RegistrationStatus)} className="h-9 border border-line px-2 text-xs font-bold outline-none focus:border-brand">
            {statusOptions.map((item) => <option key={item.value} value={item.value}>{item.label}</option>)}
          </select>
          <div className="flex h-9 min-w-0 items-center border border-line px-2.5 focus-within:border-brand">
            <Search className="h-3.5 w-3.5 shrink-0 text-soft" />
            <input value={keyword} onChange={(event) => setKeyword(event.target.value)} placeholder="搜索姓名、手机号、订单、核销码" className="min-w-0 flex-1 px-2 text-xs font-bold outline-none" />
          </div>
          <button type="button" onClick={() => void loadRows()} disabled={loading} className="inline-flex h-9 items-center justify-center gap-1.5 rounded-[4px] bg-ink px-3 text-xs font-extrabold text-white disabled:bg-line-dark">
            <RefreshCw className="h-3.5 w-3.5" />
            刷新
          </button>
        </section>

        <div className="grid min-h-0 flex-1 gap-2 xl:grid-cols-[minmax(0,1fr)_340px]">
          <section className="min-h-0 overflow-hidden border border-line bg-white">
            <div className="flex h-10 items-center justify-between border-b border-line px-3">
              <div className="min-w-0 truncate text-sm font-extrabold text-ink">{selectedProject?.item.title || '暂无核销项目'}</div>
              <div className="text-xs font-bold text-muted">{selectedProject ? `${formatTime(projectStartsAt(selectedProject))} · ${projectLocation(selectedProject)}` : '-'}</div>
            </div>
            <div className="h-[calc(100%-40px)] divide-y divide-line overflow-y-auto">
              {visibleRows.map((row) => (
                <div key={`${row.kind}:${row.item.id}`} className="grid gap-3 px-3 py-3 lg:grid-cols-[1fr_110px_100px] lg:items-center">
                  <div className="min-w-0">
                    <div className="truncate text-sm font-extrabold text-ink">{row.item.userName || row.item.userPhone || row.item.registrationNo}</div>
                    <div className="mt-1 truncate text-xs font-bold text-muted">{row.item.registrationNo || '-'} · {row.item.userPhone || '-'} · {row.item.checkinCode}</div>
                  </div>
                  <div className="text-xs font-extrabold text-muted">{statusLabel(row.item.status)}</div>
                  {canWriteCheckin && row.item.status === 'registered' ? (
                    <button type="button" disabled={saving} onClick={() => void manualCheckin(row)} className="h-8 rounded-[4px] bg-brand px-3 text-xs font-extrabold text-white disabled:bg-line-dark">手动核销</button>
                  ) : (
                    <div className="text-xs font-bold text-soft lg:text-right">{row.item.checkedInAt ? formatTime(row.item.checkedInAt) : '-'}</div>
                  )}
                </div>
              ))}
              {!loading && visibleRows.length === 0 && <div className="px-4 py-10 text-center text-sm font-bold text-muted">暂无报名记录</div>}
              {loading && <div className="px-4 py-10 text-center text-sm font-bold text-muted">正在加载...</div>}
            </div>
          </section>

          <aside className="min-h-0 overflow-y-auto border border-line bg-white p-3">
            {!canWriteCheckin && <div className="mb-3 rounded-[4px] bg-bg px-3 py-2 text-xs font-bold leading-5 text-muted">当前账号仅可查看报名名单，不能补录或核销。</div>}
            <section className="border border-line p-3">
              <div className="mb-2 flex items-center gap-2 text-sm font-extrabold text-ink">
                <QrCode className="h-4 w-4 text-brand" />
                核销码核销
              </div>
              <input value={checkinCode} onChange={(event) => setCheckinCode(event.target.value)} placeholder="输入或扫码核销码" className="h-9 w-full border border-line px-3 text-sm font-bold outline-none focus:border-brand" />
              <textarea value={note} onChange={(event) => setNote(event.target.value)} rows={2} placeholder="核销备注" className="mt-2 w-full border border-line px-3 py-2 text-xs font-bold outline-none focus:border-brand" />
              {canWriteCheckin && <button type="button" disabled={saving || !checkinCode.trim()} onClick={() => void scanCheckin()} className="mt-2 inline-flex h-9 w-full items-center justify-center gap-1.5 rounded-[4px] bg-ink px-3 text-xs font-extrabold text-white disabled:bg-line-dark"><CheckCircle2 className="h-4 w-4" />查询</button>}
            </section>

            <section className="mt-3 border border-line p-3">
              <div className="mb-2 flex items-center gap-2 text-sm font-extrabold text-ink">
                <UserPlus className="h-4 w-4 text-brand" />
                通行证补录
              </div>
              <input value={passportInput} onChange={(event) => setPassportInput(event.target.value)} placeholder="输入通行证或手机号" className="h-9 w-full border border-line px-3 text-sm font-bold outline-none focus:border-brand" />
              <label className="mt-2 flex items-center gap-2 text-xs font-bold text-muted">
                <input type="checkbox" checked={immediateCheckin} onChange={(event) => setImmediateCheckin(event.target.checked)} />
                加入名单后立即核销
              </label>
              {canWriteCheckin && <button type="button" disabled={saving || !passportInput.trim()} onClick={() => void addByPassport()} className="mt-2 inline-flex h-9 w-full items-center justify-center gap-1.5 rounded-[4px] bg-brand px-3 text-xs font-extrabold text-white disabled:bg-line-dark"><ClipboardCheck className="h-4 w-4" />{immediateCheckin ? '加入并核销' : '加入名单'}</button>}
            </section>
          </aside>
        </div>
      </div>
    </AdminShell>
  )
}
