import { useQuery, keepPreviousData } from '@tanstack/react-query'
import api from '@/lib/api'
import { FilterableTable } from '@/components/FilterableTable'
import { LoadingSpinner } from '@/components/LoadingSpinner'
import { CollapsibleSection } from '@/components/CollapsibleSection'
import { MetricCard } from '@/components/MetricCard'
import { formatCurrency, formatNumber, formatPercent } from '@/lib/utils'
import { useState, useEffect } from 'react'
import { BarChart, Bar, XAxis, YAxis, CartesianGrid, Tooltip, ResponsiveContainer } from 'recharts'
import { MonthPicker } from '@/components/MonthPicker'

const ANOMALY_PAGE_SIZE = 20

function SectionLoading({ text }: { text: string }) {
  return (
    <div className="flex items-center justify-center py-12 text-sm text-muted-foreground">
      <div className="mr-2 h-4 w-4 animate-spin rounded-full border-2 border-muted border-t-primary" />
      {text}
    </div>
  )
}

export function RiskPage() {
  const [riskTab, setRiskTab] = useState<'anomaly' | 'zero' | 'cashier'>('anomaly')
  const [month, setMonth] = useState('2026-04')
  const [anomalyPage, setAnomalyPage] = useState(1)
  const [anomalyStore, setAnomalyStore] = useState('')
  const [anomalyReason, setAnomalyReason] = useState('')
  const [anomalyCashier, setAnomalyCashier] = useState('')
  const [debouncedCashier, setDebouncedCashier] = useState('')

  useEffect(() => {
    const t = setTimeout(() => setDebouncedCashier(anomalyCashier), 400)
    return () => clearTimeout(t)
  }, [anomalyCashier])

  const { data: anomalyData, isLoading: anomalyLoading, isFetching: anomalyFetching } = useQuery({
    queryKey: ['risk/anomaly', month, anomalyPage, anomalyStore, anomalyReason, debouncedCashier],
    queryFn: () => api.get('/risk/anomaly', { params: { month, page: anomalyPage, page_size: ANOMALY_PAGE_SIZE, ...(anomalyStore ? { store: anomalyStore } : {}), ...(anomalyReason ? { reason: anomalyReason } : {}), ...(debouncedCashier ? { cashier: debouncedCashier } : {}) } }),
    placeholderData: keepPreviousData,
  })

  const { data: zeroData, isLoading: zeroLoading, isFetching: zeroFetching } = useQuery({
    queryKey: ['risk/zero-received', month],
    queryFn: () => api.get('/risk/zero-received', { params: { month } }),
    staleTime: 5 * 60 * 1000,
    placeholderData: keepPreviousData,
  })

  const { data: cashierData, isLoading: cashierLoading, isFetching: cashierFetching } = useQuery({
    queryKey: ['risk/cashier', month],
    queryFn: () => api.get('/risk/cashier', { params: { month } }),
    staleTime: 5 * 60 * 1000,
    placeholderData: keepPreviousData,
  })

  const anomalyRows = (anomalyData as any)?.data || []
  const anomalyMeta = (anomalyData as any)?.meta || { total: 0 }
  const zeroRows = (zeroData as any)?.data || []
  const cashierRows = (cashierData as any)?.data || []
  const storeNames: string[] = Array.from(new Set<string>(cashierRows.map((r: any) => r.store_name as string).filter(Boolean))).sort()

  const initialLoading = !anomalyData && !zeroData && !cashierData

  const totalAnomaly = anomalyMeta.total || anomalyRows.length
  const totalZero = zeroRows.length
  const highRiskCashiers = cashierRows.filter((r: any) => Number(r.anomaly_rate_pct || 0) >= 10).length
  const avgAnomalyRate = cashierRows.length > 0
    ? cashierRows.reduce((s: number, r: any) => s + Number(r.anomaly_rate_pct || 0), 0) / cashierRows.length
    : 0

  const cashierChartData = [...cashierRows].sort((a: any, b: any) => Number(b.anomaly_bills || 0) - Number(a.anomaly_bills || 0)).slice(0, 15).map((r: any) => ({ ...r, anomaly_bills: Number(r.anomaly_bills || 0) }))

  if (initialLoading) {
    return <LoadingSpinner text="加载风险数据..." />
  }

  return (
    <div className="space-y-4">
      <div className="flex items-center justify-between">
        <div>
          <h1 className="text-xl font-bold">风险与内控管理</h1>
          <p className="mt-0.5 text-xs text-muted-foreground">异常账单 · 零实收 · 收银风险</p>
        </div>
        <MonthPicker month={month} onChange={setMonth} />
      </div>

      {/* 概览指标 */}
      <CollapsibleSection title="风险概览" subtitle="异常账单与收银操作风险汇总">
        <div className="grid grid-cols-2 gap-3 md:grid-cols-4">
          <MetricCard title="异常账单数" value={totalAnomaly} format="number" description="触发异常规则的账单数量，需逐单核查" />
          <MetricCard title="零实收账单" value={totalZero} format="number" description="实收为0的账单，可能为全额优惠或操作异常" />
          <MetricCard title="高风险收银员(≥10%)" value={highRiskCashiers} format="number" description="异常操作率≥10%的收银员数量" />
          <MetricCard title="平均异常率" value={avgAnomalyRate} format="percent" description="所有收银员的平均异常操作率" />
        </div>
      </CollapsibleSection>

      {/* 收银员风险图 */}
      <CollapsibleSection title="收银员异常账单数TOP15" subtitle="异常账单数最多的收银员（双击下方表格行可查看明细）">
        {cashierFetching ? (
          <SectionLoading text="加载图表数据..." />
        ) : (
        <ResponsiveContainer width="100%" height={400}>
          <BarChart data={cashierChartData} layout="vertical" margin={{ left: 100, right: 40 }}>
            <CartesianGrid strokeDasharray="3 3" />
            <XAxis type="number" tick={{ fontSize: 10 }} domain={[0, 'dataMax']} />
            <YAxis type="category" dataKey="cashier" tick={{ fontSize: 11 }} width={90} />
            <Tooltip formatter={(v: any) => formatNumber(Number(v))} />
            <Bar dataKey="anomaly_bills" fill="#ef4444" name="异常账单数" />
          </BarChart>
        </ResponsiveContainer>
        )}
      </CollapsibleSection>

      {/* 风险明细表 — Tab切换 */}
      <CollapsibleSection title="风险明细" subtitle="异常账单 / 零实收 / 收银员风险">
        <div className="mb-3 flex gap-2">
          <button onClick={() => setRiskTab('anomaly')} className={`rounded-md border px-3 py-1.5 text-sm ${riskTab === 'anomaly' ? 'border-primary bg-primary text-primary-foreground' : ''}`}>
            异常账单 ({totalAnomaly})
          </button>
          <button onClick={() => setRiskTab('zero')} className={`rounded-md border px-3 py-1.5 text-sm ${riskTab === 'zero' ? 'border-primary bg-primary text-primary-foreground' : ''}`}>
            零实收 ({totalZero})
          </button>
          <button onClick={() => setRiskTab('cashier')} className={`rounded-md border px-3 py-1.5 text-sm ${riskTab === 'cashier' ? 'border-primary bg-primary text-primary-foreground' : ''}`}>
            收银员风险 ({cashierRows.length})
          </button>
        </div>

        {riskTab === 'anomaly' && (
          anomalyFetching ? <SectionLoading text="加载异常账单..." /> :
          <>
          <div className="mb-2 flex gap-4 rounded-md bg-muted/50 px-3 py-2 text-xs">
            <span className="text-muted-foreground">筛选合计：</span>
            <span>消费额 <b className="text-foreground">{formatCurrency(anomalyMeta.sum_consumption)}</b></span>
            <span>优惠 <b className="text-foreground">{formatCurrency(anomalyMeta.sum_discount)}</b></span>
            <span>应收 <b className="text-foreground">{formatCurrency(Number(anomalyMeta.sum_consumption || 0) - Number(anomalyMeta.sum_discount || 0))}</b></span>
            <span>实收 <b className="text-foreground">{formatCurrency(anomalyMeta.sum_received)}</b></span>
            <span className="text-muted-foreground">| 共 {totalAnomaly} 条</span>
          </div>
          <FilterableTable
            data={anomalyRows}
            serverSide
            page={anomalyPage}
            onPageChange={setAnomalyPage}
            pageSize={ANOMALY_PAGE_SIZE}
            total={anomalyMeta.total}
            filter={anomalyStore}
            onFilterChange={(v) => { setAnomalyStore(v); setAnomalyPage(1) }}
            filterKey="store_name"
            filterLabel="全部门店"
            filterOptions={storeNames}
            statusFilterKey="anomaly_reason"
            statusFilterLabel="全部异常原因"
            statusOptions={[
              { value: '有消费无实收', label: '有消费无实收' },
              { value: '优惠大于消费', label: '优惠大于消费' },
              { value: '消费-优惠与实收不平', label: '消费-优惠与实收不平' },
            ]}
            statusFilterValue={anomalyReason}
            onStatusFilterChange={(v) => { setAnomalyReason(v); setAnomalyPage(1) }}
            searchPlaceholder="搜索收银员..."
            serverSearchValue={anomalyCashier}
            onServerSearchChange={(v) => { setAnomalyCashier(v); setAnomalyPage(1) }}
            sortOptions={[
              { key: 'consumption', label: '消费额' },
              { key: 'discount_total', label: '优惠' },
              { key: 'received_total', label: '实收' },
            ]}
            defaultSort="consumption"
            defaultOrder="desc"
            columns={[
              { key: 'store_name', label: '门店' },
              { key: 'bill_no', label: '账单号' },
              { key: 'meal_period', label: '餐段' },
              { key: 'consumption', label: '消费额', align: 'right', render: (r) => formatCurrency(r.consumption) },
              { key: 'discount_total', label: '优惠', align: 'right', render: (r) => formatCurrency(r.discount_total) },
              { key: 'received_total', label: '实收', align: 'right', render: (r) => formatCurrency(r.received_total) },
              { key: 'anomaly_reason', label: '异常原因' },
              { key: 'cashier', label: '收银员' },
              { key: 'closed_at', label: '结账时间', render: (r) => r.closed_at?.substring(0, 16) },
            ]}
          />
          </>
        )}

        {riskTab === 'zero' && (
          zeroFetching ? <SectionLoading text="加载零实收数据..." /> :
          <FilterableTable
            data={zeroRows}
            sortOptions={[
              { key: 'consumption', label: '消费额' },
              { key: 'discount_total', label: '优惠' },
              { key: 'store_name', label: '门店' },
            ]}
            defaultSort="consumption"
            defaultOrder="desc"
            filterKey="store_name"
            filterLabel="全部门店"
            columns={[
              { key: 'store_name', label: '门店' },
              { key: 'bill_no', label: '账单号' },
              { key: 'meal_period', label: '餐段' },
              { key: 'consumption', label: '消费额', align: 'right', render: (r) => formatCurrency(r.consumption) },
              { key: 'discount_total', label: '优惠', align: 'right', render: (r) => formatCurrency(r.discount_total) },
              { key: 'zero_received_type', label: '零实收类型' },
              { key: 'cashier', label: '收银员' },
              { key: 'closed_at', label: '结账时间', render: (r) => r.closed_at?.substring(0, 16) },
            ]}
          />
        )}

        {riskTab === 'cashier' && (
          cashierFetching ? <SectionLoading text="加载收银员风险..." /> :
          <FilterableTable
            data={cashierRows}
            onRowDoubleClick={(r: any) => {
              setAnomalyCashier(r.cashier)
              setDebouncedCashier(r.cashier)
              setAnomalyPage(1)
              setRiskTab('anomaly')
            }}
            sortOptions={[
              { key: 'anomaly_rate_pct', label: '异常率' },
              { key: 'bill_count', label: '账单数' },
              { key: 'received', label: '实收' },
              { key: 'anomaly_bills', label: '异常账单数' },
              { key: 'cashier', label: '收银员' },
            ]}
            defaultSort="anomaly_bills"
            defaultOrder="desc"
            columns={[
              { key: 'cashier', label: '收银员' },
              { key: 'bill_count', label: '账单数', align: 'right', render: (r) => formatNumber(r.bill_count) },
              { key: 'received', label: '实收', align: 'right', render: (r) => formatCurrency(r.received) },
              { key: 'anomaly_bills', label: '异常账单数', align: 'right', render: (r) => formatNumber(r.anomaly_bills) },
              { key: 'anomaly_rate_pct', label: '异常率', align: 'right', render: (r) => {
                const v = Number(r.anomaly_rate_pct || 0)
                return <span className={v >= 10 ? 'font-medium text-red-600' : v >= 5 ? 'text-yellow-600' : 'text-green-600'}>{v.toFixed(2)}%</span>
              }},
              { key: 'anomaly_consumption', label: '异常消费额', align: 'right', render: (r) => formatCurrency(r.anomaly_consumption) },
            ]}
          />
        )}
      </CollapsibleSection>
    </div>
  )
}
