import { useState, useMemo } from 'react'
import { useQuery } from '@tanstack/react-query'
import { useNavigate } from 'react-router-dom'
import { BarChart, Bar, LineChart, Line, XAxis, YAxis, CartesianGrid, Tooltip, ResponsiveContainer, ScatterChart, Scatter, ZAxis, Legend, Cell, RadarChart, Radar, PolarGrid, PolarAngleAxis, PolarRadiusAxis } from 'recharts'
import api from '@/lib/api'
import { CollapsibleSection } from '@/components/CollapsibleSection'
import { Pagination } from '@/components/Pagination'
import { FilterableTable } from '@/components/FilterableTable'
import { LoadingSpinner } from '@/components/LoadingSpinner'
import { Badge } from '@/components/Badge'
import { formatCurrency, cn } from '@/lib/utils'
import { Activity, AlertTriangle, Link2, TrendingUp } from 'lucide-react'
import { MonthPicker } from '@/components/MonthPicker'
import { SearchSelect } from '@/components/SearchSelect'

const PAGE_SIZE = 20

// ============ 可复用分页筛选排序表格 ============

const TABS = [
  { key: 'health', label: '健康度评分', icon: Activity },
  { key: 'alerts', label: '预警中心', icon: AlertTriangle },
  { key: 'correlation', label: '关联分析', icon: Link2 },
  { key: 'forecast', label: '趋势预测', icon: TrendingUp },
]

const ALERT_LEVEL_STYLE: Record<string, string> = {
  red: 'border-red-300 bg-red-50',
  orange: 'border-orange-300 bg-orange-50',
  yellow: 'border-yellow-300 bg-yellow-50',
}
const ALERT_LEVEL_TEXT: Record<string, string> = {
  red: 'text-red-700',
  orange: 'text-orange-700',
  yellow: 'text-yellow-700',
}
const ALERT_LEVEL_LABEL: Record<string, string> = {
  red: '红色',
  orange: '橙色',
  yellow: '黄色',
}
const ALERT_TYPE_LABEL: Record<string, string> = {
  revenue: '营收异动',
  cost: '成本异动',
  hr: '人力异动',
  platform: '平台依赖',
  task: '任务逾期',
}

export function SituationalAwarenessPage() {
  const [tab, setTab] = useState('health')
  const [month, setMonth] = useState('2026-04')
  const navigate = useNavigate()

  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">门店健康度 · 自动化预警 · 跨模块关联 · 趋势预测 · {month}</p>
        </div>
        <MonthPicker month={month} onChange={setMonth} />
      </div>

      {/* Tab 切换 */}
      <div className="flex gap-1 border-b">
        {TABS.map((t) => {
          const Icon = t.icon
          const active = tab === t.key
          return (
            <button
              key={t.key}
              onClick={() => setTab(t.key)}
              className={cn(
                'flex items-center gap-1.5 border-b-2 px-4 py-2 text-sm font-medium transition-colors',
                active ? 'border-primary text-primary' : 'border-transparent text-muted-foreground hover:text-foreground'
              )}
            >
              <Icon size={16} />
              {t.label}
            </button>
          )
        })}
      </div>

      {tab === 'health' && <HealthScoreTab navigate={navigate} month={month} />}
      {tab === 'alerts' && <AlertsTab month={month} />}
      {tab === 'correlation' && <CorrelationTab navigate={navigate} month={month} />}
      {tab === 'forecast' && <ForecastTab month={month} />}
    </div>
  )
}

// ============ Tab 1: 门店健康度综合评分 ============

function HealthScoreTab({ navigate, month }: { navigate: (path: string) => void; month: string }) {
  const [selectedStore, setSelectedStore] = useState<any>(null)
  const { data, isLoading } = useQuery({
    queryKey: ['sa-health-score', month],
    queryFn: () => api.get('/situational-awareness/health-score', { params: { month } }),
    staleTime: 5 * 60 * 1000,
  })

  if (isLoading) return <LoadingSpinner text="加载健康度评分..." />

  const rows = (data as any)?.data || []

  const statusCount = rows.reduce((acc: any, r: any) => {
    acc[r.health_status] = (acc[r.health_status] || 0) + 1
    return acc
  }, {})

  const scoreBuckets = [
    { range: '75-100', label: '健康', count: 0, color: '#22c55e' },
    { range: '55-74', label: '亚健康', count: 0, color: '#eab308' },
    { range: '0-54', label: '需干预', count: 0, color: '#ef4444' },
  ]
  rows.forEach((r: any) => {
    const s = Number(r.health_score)
    if (s >= 75) scoreBuckets[0].count++
    else if (s >= 55) scoreBuckets[1].count++
    else scoreBuckets[2].count++
  })

  const healthStatusColor: Record<string, string> = {
    '健康': 'bg-green-100 text-green-700 border-green-300',
    '亚健康': 'bg-yellow-100 text-yellow-700 border-yellow-300',
    '需干预': 'bg-red-100 text-red-700 border-red-300',
  }

  return (
    <div className="space-y-4">
      {/* 概览卡片 */}
      <div className="grid grid-cols-3 gap-3">
        {scoreBuckets.map((b) => (
          <div key={b.range} className="rounded-lg border bg-card p-4 shadow-sm">
            <div className="flex items-center justify-between">
              <p className="text-sm text-muted-foreground">{b.label}</p>
              <span className="h-3 w-3 rounded-full" style={{ backgroundColor: b.color }} />
            </div>
            <p className="mt-2 text-2xl font-bold" style={{ color: b.color }}>{b.count}</p>
            <p className="mt-0.5 text-xs text-muted-foreground">评分 {b.range}</p>
          </div>
        ))}
      </div>

      {/* 评分分布柱状图 */}
      <CollapsibleSection title="健康度评分分布" subtitle="按评分区间统计门店数量">
        <ResponsiveContainer width="100%" height={200}>
          <BarChart data={scoreBuckets}>
            <CartesianGrid strokeDasharray="3 3" />
            <XAxis dataKey="label" tick={{ fontSize: 12 }} />
            <YAxis tick={{ fontSize: 10 }} />
            <Tooltip formatter={(v: any) => [v, '门店数']} />
            <Bar dataKey="count" name="门店数" radius={[4, 4, 0, 0]}>
              {scoreBuckets.map((b, i) => <Cell key={i} fill={b.color} />)}
            </Bar>
          </BarChart>
        </ResponsiveContainer>
      </CollapsibleSection>

      {/* 门店评分明细表 */}
      <CollapsibleSection title={`门店健康度明细 (${rows.length})`} subtitle="综合营收规模、成本控制、风险等级、会员复购、任务执行、会员占比六维度评分">
        <FilterableTable
          data={rows}
          filterKey="store_name"
          filterLabel="全部门店"
          sortOptions={[
            { key: 'health_score', label: '健康分' },
            { key: 'received', label: '实收' },
            { key: 'avg_margin', label: '毛利率' },
            { key: 'avg_cost_variance_pct', label: '成本差异率' },
            { key: 'repeat_rate_pct', label: '复购率' },
            { key: 'task_completion_rate', label: '完成率' },
          ]}
          statusFilterKey="health_status"
          statusFilterLabel="全部状态"
          statusOptions={[
            { value: '健康', label: '健康' },
            { value: '亚健康', label: '亚健康' },
            { value: '需干预', label: '需干预' },
          ]}
          onRowClick={(r) => setSelectedStore(r)}
          columns={[
            { key: 'store_name', label: '门店' },
            { key: 'health_score', label: '健康分', align: 'center', render: (r) => (
              <span className={cn('font-bold', Number(r.health_score) >= 75 ? 'text-green-600' : Number(r.health_score) >= 55 ? 'text-yellow-600' : 'text-red-600')}>
                {r.health_score}
              </span>
            )},
            { key: 'health_status', label: '状态', align: 'center', render: (r) => (
              <span className={cn('inline-flex items-center rounded-md border px-2 py-0.5 text-xs font-medium', healthStatusColor[r.health_status] || 'bg-gray-100 text-gray-700 border-gray-300')}>
                {r.health_status}
              </span>
            )},
            { key: 'risk_level', label: '风险', align: 'center', render: (r) => r.risk_level ? <Badge type="risk" text={r.risk_level} /> : '-' },
            { key: 'received', label: '实收', align: 'right', render: (r) => formatCurrency(r.received) },
            { key: 'avg_bill_value', label: '客单价', align: 'right', render: (r) => formatCurrency(r.avg_bill_value) },
            { key: 'avg_margin', label: '毛利率', align: 'right', render: (r) => `${r.avg_margin}%` },
            { key: 'avg_cost_variance_pct', label: '成本差异率', align: 'right', render: (r) => `${r.avg_cost_variance_pct}%` },
            { key: 'repeat_rate_pct', label: '复购率', align: 'right', render: (r) => `${r.repeat_rate_pct}%` },
            { key: 'task_completion_rate', label: '任务完成率', align: 'right', render: (r) => `${r.task_completion_rate}%` },
          ]}
        />
      </CollapsibleSection>

      {selectedStore && <HealthScoreDetail store={selectedStore} onClose={() => setSelectedStore(null)} navigate={navigate} />}
    </div>
  )
}

// ============ 健康度评分明细弹窗 ============

const SCORE_DIMENSIONS = [
  { key: 'score_revenue', label: '营收规模', max: 20, desc: '日均实收' },
  { key: 'score_cost', label: '成本控制', max: 20, desc: '成本差异率' },
  { key: 'score_margin', label: '毛利率', max: 15, desc: '理论毛利率' },
  { key: 'score_risk', label: '风险等级', max: 10, desc: '风险评级' },
  { key: 'score_repeat', label: '复购率', max: 10, desc: '会员复购率' },
  { key: 'score_member', label: '会员占比', max: 10, desc: '会员账单占比' },
  { key: 'score_task', label: '任务完成', max: 10, desc: '任务完成率' },
  { key: 'score_bill', label: '客单价', max: 5, desc: '平均客单价' },
]

function HealthScoreDetail({ store, onClose, navigate }: { store: any; onClose: () => void; navigate: (path: string) => void }) {
  const radarData = SCORE_DIMENSIONS.map(d => ({
    dimension: d.label,
    score: Math.round(Number(store[d.key] || 0) / d.max * 100),
    fullMark: 100,
  }))

  const healthColor = Number(store.health_score) >= 75 ? '#22c55e' : Number(store.health_score) >= 55 ? '#eab308' : '#ef4444'

  return (
    <div className="fixed inset-0 z-50 flex items-center justify-center bg-black/50" onClick={onClose}>
      <div className="max-h-[90vh] w-full max-w-2xl overflow-y-auto rounded-lg border bg-card p-6 shadow-lg" onClick={(e) => e.stopPropagation()}>
        <div className="flex items-start justify-between">
          <div className="flex items-center gap-3">
            <h2 className="text-lg font-bold">{store.store_name}</h2>
            <span className="text-2xl font-bold" style={{ color: healthColor }}>{store.health_score}</span>
            <span className={cn('inline-flex items-center rounded-md border px-2 py-0.5 text-xs font-medium',
              store.health_status === '健康' ? 'bg-green-100 text-green-700 border-green-300' :
              store.health_status === '亚健康' ? 'bg-yellow-100 text-yellow-700 border-yellow-300' :
              'bg-red-100 text-red-700 border-red-300')
            }>{store.health_status}</span>
            {store.risk_level && <Badge type="risk" text={store.risk_level} />}
          </div>
          <button onClick={onClose} className="text-muted-foreground hover:text-foreground text-xl">✕</button>
        </div>

        <div className="mt-4 grid gap-4 md:grid-cols-2">
          {/* 雷达图 */}
          <div>
            <ResponsiveContainer width="100%" height={250}>
              <RadarChart data={radarData}>
                <PolarGrid />
                <PolarAngleAxis dataKey="dimension" tick={{ fontSize: 10 }} />
                <PolarRadiusAxis angle={90} domain={[0, 100]} tick={{ fontSize: 8 }} />
                <Radar dataKey="score" name="得分" stroke={healthColor} fill={healthColor} fillOpacity={0.3} />
                <Tooltip formatter={(v: any) => [v, '得分']} />
              </RadarChart>
            </ResponsiveContainer>
          </div>

          {/* 各维度得分 */}
          <div className="space-y-2">
            {SCORE_DIMENSIONS.map(d => {
              const score = Number(store[d.key] || 0)
              const pct = (score / d.max) * 100
              const color = pct >= 75 ? '#22c55e' : pct >= 50 ? '#eab308' : '#ef4444'
              return (
                <div key={d.key}>
                  <div className="flex items-center justify-between text-xs">
                    <span className="font-medium">{d.label}</span>
                    <span className="text-muted-foreground">{score.toFixed(1)} / {d.max}</span>
                  </div>
                  <div className="mt-0.5 h-2 overflow-hidden rounded-full bg-muted">
                    <div className="h-full rounded-full" style={{ width: `${pct}%`, backgroundColor: color }} />
                  </div>
                </div>
              )
            })}
          </div>
        </div>

        {/* 原始指标 */}
        <div className="mt-4 grid grid-cols-2 gap-2 md:grid-cols-4">
          <div className="rounded border p-2 text-center">
            <p className="text-xs text-muted-foreground">日均实收</p>
            <p className="text-sm font-bold">{formatCurrency(store.avg_daily_received)}</p>
          </div>
          <div className="rounded border p-2 text-center">
            <p className="text-xs text-muted-foreground">毛利率</p>
            <p className="text-sm font-bold">{store.avg_margin}%</p>
          </div>
          <div className="rounded border p-2 text-center">
            <p className="text-xs text-muted-foreground">成本差异率</p>
            <p className="text-sm font-bold">{store.avg_cost_variance_pct}%</p>
          </div>
          <div className="rounded border p-2 text-center">
            <p className="text-xs text-muted-foreground">复购率</p>
            <p className="text-sm font-bold">{store.repeat_rate_pct}%</p>
          </div>
          <div className="rounded border p-2 text-center">
            <p className="text-xs text-muted-foreground">会员占比</p>
            <p className="text-sm font-bold">{store.member_share_pct}%</p>
          </div>
          <div className="rounded border p-2 text-center">
            <p className="text-xs text-muted-foreground">客单价</p>
            <p className="text-sm font-bold">{formatCurrency(store.avg_bill_value)}</p>
          </div>
          <div className="rounded border p-2 text-center">
            <p className="text-xs text-muted-foreground">任务完成率</p>
            <p className="text-sm font-bold">{store.task_completion_rate}%</p>
          </div>
          <div className="rounded border p-2 text-center">
            <p className="text-xs text-muted-foreground">月实收</p>
            <p className="text-sm font-bold">{formatCurrency(store.received)}</p>
          </div>
        </div>

        <div className="mt-4 flex justify-end">
          <button onClick={() => navigate(`/stores/${store.store_code}`)} className="rounded-md bg-primary px-4 py-2 text-sm font-medium text-primary-foreground hover:bg-primary/90">查看门店详情</button>
        </div>
      </div>
    </div>
  )
}

// ============ Tab 2: 预警中心 ============

function AlertsTab({ month }: { month: string }) {
  const { data, isLoading } = useQuery({
    queryKey: ['sa-alerts', month],
    queryFn: () => api.get('/situational-awareness/alerts', { params: { month } }),
    staleTime: 5 * 60 * 1000,
  })

  if (isLoading) return <LoadingSpinner text="加载预警信息..." />

  const d = (data as any)?.data
  const alerts = d?.alerts || []

  // 按类型分组统计
  const typeCount = alerts.reduce((acc: any, a: any) => {
    acc[a.type] = (acc[a.type] || 0) + 1
    return acc
  }, {})

  return (
    <div className="space-y-4">
      {/* 预警概览 */}
      <div className="grid grid-cols-4 gap-3">
        <div className="rounded-lg border bg-card p-4 shadow-sm">
          <p className="text-sm text-muted-foreground">总预警</p>
          <p className="mt-2 text-2xl font-bold">{d?.total || 0}</p>
        </div>
        <div className="rounded-lg border border-red-200 bg-red-50/50 p-4 shadow-sm">
          <p className="text-sm text-red-700">红色预警</p>
          <p className="mt-2 text-2xl font-bold text-red-600">{d?.red || 0}</p>
        </div>
        <div className="rounded-lg border border-orange-200 bg-orange-50/50 p-4 shadow-sm">
          <p className="text-sm text-orange-700">橙色预警</p>
          <p className="mt-2 text-2xl font-bold text-orange-600">{d?.orange || 0}</p>
        </div>
        <div className="rounded-lg border bg-card p-4 shadow-sm">
          <p className="text-sm text-muted-foreground">预警类型</p>
          <p className="mt-2 text-2xl font-bold">{Object.keys(typeCount).length}</p>
        </div>
      </div>

      {/* 类型分布 */}
      <CollapsibleSection title="预警类型分布" subtitle="按预警类型统计数量">
        <div className="flex flex-wrap gap-2">
          {Object.entries(typeCount).map(([type, count]) => (
            <span key={type} className="inline-flex items-center gap-1.5 rounded-md border bg-muted/50 px-3 py-1.5 text-sm">
              <span className="font-medium">{ALERT_TYPE_LABEL[type] || type}</span>
              <span className="rounded-full bg-primary/10 px-2 py-0.5 text-xs font-bold text-primary">{count as number}</span>
            </span>
          ))}
        </div>
      </CollapsibleSection>

      {/* 预警列表 */}
      <CollapsibleSection title={`预警明细 (${alerts.length})`} subtitle="按严重程度排序">
        <AlertList alerts={alerts} />
      </CollapsibleSection>
    </div>
  )
}

function AlertList({ alerts }: { alerts: any[] }) {
  const [page, setPage] = useState(1)
  const [storeFilter, setStoreFilter] = useState('')
  const [typeFilter, setTypeFilter] = useState('')
  const [levelFilter, setLevelFilter] = useState('')

  const stores = useMemo(() => [...new Set(alerts.map((a: any) => a.store).filter(Boolean))].sort(), [alerts])
  const types = useMemo(() => [...new Set(alerts.map((a: any) => a.type).filter(Boolean))].sort(), [alerts])

  const filtered = useMemo(() => {
    let r = alerts
    if (storeFilter) r = r.filter((a: any) => a.store === storeFilter)
    if (typeFilter) r = r.filter((a: any) => a.type === typeFilter)
    if (levelFilter) r = r.filter((a: any) => a.level === levelFilter)
    const levelOrder: Record<string, number> = { red: 0, orange: 1, yellow: 2 }
    return [...r].sort((a: any, b: any) => (levelOrder[a.level] ?? 9) - (levelOrder[b.level] ?? 9))
  }, [alerts, storeFilter, typeFilter, levelFilter])

  const total = filtered.length
  const paged = filtered.slice((page - 1) * PAGE_SIZE, page * PAGE_SIZE)

  if (alerts.length === 0) return <p className="py-8 text-center text-muted-foreground">暂无预警</p>

  return (
    <>
      <div className="mb-3 flex flex-wrap gap-2">
        <SearchSelect
          value={storeFilter}
          onChange={(v) => { setStoreFilter(v); setPage(1) }}
          options={stores}
          emptyLabel="全部门店"
          className="min-w-[140px]"
        />
        <SearchSelect
          value={typeFilter}
          onChange={(v) => { setTypeFilter(v); setPage(1) }}
          options={types.map((t) => ({ value: t, label: ALERT_TYPE_LABEL[t] || t }))}
          emptyLabel="全部类型"
          className="min-w-[120px]"
        />
        <SearchSelect
          value={levelFilter}
          onChange={(v) => { setLevelFilter(v); setPage(1) }}
          options={[
            { value: 'red', label: '红色' },
            { value: 'orange', label: '橙色' },
            { value: 'yellow', label: '黄色' },
          ]}
          emptyLabel="全部等级"
          className="min-w-[100px]"
        />
      </div>
      <div className="space-y-2">
        {paged.map((a: any, i: number) => (
          <div key={i} className={cn('flex items-start gap-3 rounded-md border p-3', ALERT_LEVEL_STYLE[a.level] || 'border-gray-200 bg-gray-50')}>
            <span className={cn('mt-0.5 flex h-6 w-6 shrink-0 items-center justify-center rounded-full text-xs font-bold', ALERT_LEVEL_TEXT[a.level] || 'text-gray-600')}>
              {ALERT_LEVEL_LABEL[a.level] || a.level}
            </span>
            <div className="min-w-0 flex-1">
              <div className="flex items-center gap-2">
                <span className="text-sm font-medium">{a.title}</span>
                <span className="rounded bg-muted px-1.5 py-0.5 text-xs text-muted-foreground">{ALERT_TYPE_LABEL[a.type] || a.type}</span>
              </div>
              <p className="mt-0.5 text-xs text-muted-foreground">{a.detail}</p>
            </div>
            {a.store && a.store !== '全局' && (
              <span className="shrink-0 text-xs text-muted-foreground">{a.store}</span>
            )}
            {a.date && (
              <span className="shrink-0 text-xs text-muted-foreground">{a.date}</span>
            )}
          </div>
        ))}
      </div>
      <div className="mt-3">
        <Pagination page={page} pageSize={PAGE_SIZE} total={total} onPageChange={setPage} />
      </div>
    </>
  )
}

// ============ Tab 3: 跨模块关联分析 ============

function CorrelationTab({ navigate, month }: { navigate: (path: string) => void; month: string }) {
  const { data, isLoading } = useQuery({
    queryKey: ['sa-correlation', month],
    queryFn: () => api.get('/situational-awareness/correlation', { params: { month } }),
    staleTime: 5 * 60 * 1000,
  })

  if (isLoading) return <LoadingSpinner text="加载关联分析..." />

  const d = (data as any)?.data
  const costRiskRows = d?.cost_risk || []
  const channelRiskRows = d?.channel_risk || []
  const hrRevenueRows = d?.hr_revenue || []
  const staffingRows = d?.staffing_efficiency || []

  const correlationStatusColor: Record<string, string> = {
    '成本失控+高风险': 'bg-red-100 text-red-700 border-red-300',
    '高风险': 'bg-red-100 text-red-700 border-red-300',
    '成本偏高+中风险': 'bg-orange-100 text-orange-700 border-orange-300',
    '成本失控': 'bg-orange-100 text-orange-700 border-orange-300',
    '正常': 'bg-green-100 text-green-700 border-green-300',
  }
  const channelStatusColor: Record<string, string> = {
    '渠道依赖预警': 'bg-red-100 text-red-700 border-red-300',
    '渠道风险': 'bg-orange-100 text-orange-700 border-orange-300',
    '会员驱动型': 'bg-blue-100 text-blue-700 border-blue-300',
    '均衡型': 'bg-green-100 text-green-700 border-green-300',
  }
  const hrStatusColor: Record<string, string> = {
    '出勤低+有营收': 'bg-orange-100 text-orange-700 border-orange-300',
    '出勤低+营收低': 'bg-red-100 text-red-700 border-red-300',
    '旷工严重': 'bg-red-100 text-red-700 border-red-300',
    '正常': 'bg-green-100 text-green-700 border-green-300',
  }
  const matchStatusColor: Record<string, string> = {
    '高峰人手不足': 'bg-red-100 text-red-700 border-red-300',
    '低谷人员冗余': 'bg-orange-100 text-orange-700 border-orange-300',
    '无在岗数据': 'bg-gray-100 text-gray-600 border-gray-300',
    '配置合理': 'bg-green-100 text-green-700 border-green-300',
  }

  // 散点图数据：成本-风险
  const costRiskScatter = costRiskRows.map((r: any) => ({
    name: r.store_name,
    x: Number(r.avg_daily_received || 0),
    y: Number(r.avg_cost_variance_pct || 0),
    risk: r.risk_level,
    fill: r.risk_level === '红色' ? '#ef4444' : r.risk_level === '黄色' ? '#eab308' : '#22c55e',
  }))

  return (
    <div className="space-y-4">
      {/* 成本-风险散点图 */}
      <CollapsibleSection title="成本-风险关联分布" subtitle="日均实收 × 超耗率，颜色表示风险等级">
        <ResponsiveContainer width="100%" height={280}>
          <ScatterChart>
            <CartesianGrid strokeDasharray="3 3" />
            <XAxis type="number" dataKey="x" name="日均实收" tickFormatter={(v) => `${(v / 10000).toFixed(0)}万`} tick={{ fontSize: 10 }} />
            <YAxis type="number" dataKey="y" name="超耗率" unit="%" tick={{ fontSize: 10 }} />
            <ZAxis range={[40, 40]} />
            <Tooltip cursor={{ strokeDasharray: '3 3' }} formatter={(v: any, n: string) => n === '超耗率' ? `${Number(v).toFixed(1)}%` : n === '日均实收' ? `¥${Number(v).toFixed(0)}` : v} />
            <Scatter data={costRiskScatter} />
            <Legend wrapperStyle={{ fontSize: 10 }} />
          </ScatterChart>
        </ResponsiveContainer>
      </CollapsibleSection>

      {/* 成本-风险明细表 */}
      <CollapsibleSection title={`成本-风险关联 (${costRiskRows.length})`} subtitle="门店成本控制与风险等级的关联分析">
        <FilterableTable
          data={costRiskRows}
          filterKey="store_name"
          filterLabel="全部门店"
          sortOptions={[
            { key: 'received', label: '实收' },
            { key: 'avg_margin', label: '毛利率' },
            { key: 'avg_cost_variance_pct', label: '成本差异率' },
          ]}
          statusFilterKey="risk_level"
          statusFilterLabel="全部风险"
          statusOptions={[
            { value: '红色', label: '红色' },
            { value: '黄色', label: '黄色' },
            { value: '绿色', label: '绿色' },
          ]}
          onRowClick={(r) => navigate(`/stores/${r.store_code}`)}
          columns={[
            { key: 'store_name', label: '门店' },
            { key: 'risk_level', label: '风险', align: 'center', render: (r) => r.risk_level ? <Badge type="risk" text={r.risk_level} /> : '-' },
            { key: 'received', label: '实收', align: 'right', render: (r) => formatCurrency(r.received) },
            { key: 'avg_margin', label: '毛利率', align: 'right', render: (r) => `${r.avg_margin}%` },
            { key: 'avg_cost_variance_pct', label: '成本差异率', align: 'right', render: (r) => `${r.avg_cost_variance_pct}%` },
            { key: 'correlation_status', label: '关联状态', align: 'center', render: (r) => (
              <span className={cn('inline-flex items-center rounded-md border px-2 py-0.5 text-xs font-medium', correlationStatusColor[r.correlation_status] || 'bg-gray-100 text-gray-700 border-gray-300')}>
                {r.correlation_status}
              </span>
            )},
          ]}
        />
      </CollapsibleSection>

      {/* 渠道-会员关联 */}
      <CollapsibleSection title={`渠道-会员关联 (${channelRiskRows.length})`} subtitle="平台依赖度与会员占比的三角分析">
        <FilterableTable
          data={channelRiskRows}
          filterKey="store_name"
          filterLabel="全部门店"
          sortOptions={[
            { key: 'received', label: '实收' },
            { key: 'platform_share', label: '平台占比' },
            { key: 'member_share_pct', label: '会员占比' },
            { key: 'repeat_rate_pct', label: '复购率' },
          ]}
          statusFilterKey="channel_status"
          statusFilterLabel="全部状态"
          statusOptions={[
            { value: '渠道依赖预警', label: '渠道依赖预警' },
            { value: '渠道风险', label: '渠道风险' },
            { value: '会员驱动型', label: '会员驱动型' },
            { value: '均衡型', label: '均衡型' },
          ]}
          onRowClick={(r) => navigate(`/stores/${r.store_code}`)}
          columns={[
            { key: 'store_name', label: '门店' },
            { key: 'received', label: '实收', align: 'right', render: (r) => formatCurrency(r.received) },
            { key: 'platform_share', label: '平台占比', align: 'right', render: (r) => `${r.platform_share}%` },
            { key: 'member_share_pct', label: '会员占比', align: 'right', render: (r) => `${r.member_share_pct}%` },
            { key: 'repeat_rate_pct', label: '复购率', align: 'right', render: (r) => `${r.repeat_rate_pct}%` },
            { key: 'channel_status', label: '渠道状态', align: 'center', render: (r) => (
              <span className={cn('inline-flex items-center rounded-md border px-2 py-0.5 text-xs font-medium', channelStatusColor[r.channel_status] || 'bg-gray-100 text-gray-700 border-gray-300')}>
                {r.channel_status}
              </span>
            )},
          ]}
        />
      </CollapsibleSection>

      {/* 考勤-营收关联 */}
      <CollapsibleSection title={`考勤-营收关联 (${hrRevenueRows.length})`} subtitle="人员出勤与营收产出的关联分析">
        <FilterableTable
          data={hrRevenueRows}
          filterKey="store_name"
          filterLabel="全部门店"
          sortOptions={[
            { key: 'received', label: '实收' },
            { key: 'emp_count', label: '员工数' },
            { key: 'avg_attend', label: '平均出勤' },
            { key: 'total_absent', label: '旷工天数' },
            { key: 'revenue_per_emp', label: '人效' },
          ]}
          statusFilterKey="hr_status"
          statusFilterLabel="全部状态"
          statusOptions={[
            { value: '出勤低+有营收', label: '出勤低+有营收' },
            { value: '出勤低+营收低', label: '出勤低+营收低' },
            { value: '旷工严重', label: '旷工严重' },
            { value: '正常', label: '正常' },
          ]}
          columns={[
            { key: 'store_name', label: '门店' },
            { key: 'received', label: '实收', align: 'right', render: (r) => formatCurrency(r.received) },
            { key: 'emp_count', label: '员工数', align: 'center' },
            { key: 'avg_attend', label: '平均出勤', align: 'right', render: (r) => r.avg_attend },
            { key: 'total_absent', label: '旷工天数', align: 'center' },
            { key: 'low_attend_rate', label: '低出勤率', align: 'right', render: (r) => `${r.low_attend_rate}%` },
            { key: 'revenue_per_emp', label: '人效', align: 'right', render: (r) => formatCurrency(r.revenue_per_emp) },
            { key: 'hr_status', label: '状态', align: 'center', render: (r) => (
              <span className={cn('inline-flex items-center rounded-md border px-2 py-0.5 text-xs font-medium', hrStatusColor[r.hr_status] || 'bg-gray-100 text-gray-700 border-gray-300')}>
                {r.hr_status}
              </span>
            )},
          ]}
        />
      </CollapsibleSection>

      {/* 客流-人力匹配 */}
      <CollapsibleSection title={`客流-人力匹配 (${staffingRows.length})`} subtitle="每小时账单数与在岗人数的匹配度" defaultOpen={false}>
        <FilterableTable
          data={staffingRows}
          filterKey="store_name"
          filterLabel="全部门店"
          sortOptions={[
            { key: 'bills', label: '账单数' },
            { key: 'staff', label: '在岗人数' },
            { key: 'bills_per_staff', label: '人均产出' },
          ]}
          statusFilterKey="match_status"
          statusFilterLabel="全部状态"
          statusOptions={[
            { value: '高峰人手不足', label: '高峰人手不足' },
            { value: '低谷人员冗余', label: '低谷人员冗余' },
            { value: '配置合理', label: '配置合理' },
            { value: '无在岗数据', label: '无在岗数据' },
          ]}
          columns={[
            { key: 'store_name', label: '门店' },
            { key: 'hour', label: '时段', align: 'center', render: (r) => `${r.hour}:00` },
            { key: 'bills', label: '账单数', align: 'right' },
            { key: 'staff', label: '在岗人数', align: 'right' },
            { key: 'bills_per_staff', label: '人均产出', align: 'right' },
            { key: 'match_status', label: '匹配状态', align: 'center', render: (r) => (
              <span className={cn('inline-flex items-center rounded-md border px-2 py-0.5 text-xs font-medium', matchStatusColor[r.match_status] || 'bg-gray-100 text-gray-700 border-gray-300')}>
                {r.match_status}
              </span>
            )},
          ]}
        />
      </CollapsibleSection>
    </div>
  )
}

// ============ Tab 4: 趋势预测 ============

function ForecastTab({ month }: { month: string }) {
  const { data, isLoading } = useQuery({
    queryKey: ['sa-forecast', month],
    queryFn: () => api.get('/situational-awareness/forecast', { params: { month } }),
    staleTime: 5 * 60 * 1000,
  })

  if (isLoading) return <LoadingSpinner text="加载趋势预测..." />

  const d = (data as any)?.data
  const trafficRows = d?.traffic_forecast || []
  const costTrendRows = d?.cost_trend || []
  const turnoverRows = d?.turnover_alert || []

  // 工作日/周末分开
  const weekdayData = trafficRows.filter((r: any) => r.day_type === '工作日')
  const weekendData = trafficRows.filter((r: any) => r.day_type === '周末')

  const stabilityColor: Record<string, string> = {
    '波动大': 'bg-red-100 text-red-700 border-red-300',
    '中等波动': 'bg-orange-100 text-orange-700 border-orange-300',
    '稳定': 'bg-green-100 text-green-700 border-green-300',
  }
  const trendStatusColor: Record<string, string> = {
    '恶化': 'bg-red-100 text-red-700 border-red-300',
    '关注': 'bg-orange-100 text-orange-700 border-orange-300',
    '正常': 'bg-green-100 text-green-700 border-green-300',
    '数据异常': 'bg-gray-100 text-gray-600 border-gray-300',
  }

  return (
    <div className="space-y-4">
      {/* 客流预测图 */}
      <CollapsibleSection title="客流预测（分时段）" subtitle="基于历史4周数据，按工作日/周末×小时维度P85分位预测">
        <ResponsiveContainer width="100%" height={300}>
          <LineChart data={weekdayData}>
            <CartesianGrid strokeDasharray="3 3" />
            <XAxis dataKey="hour" tickFormatter={(v) => `${v}:00`} tick={{ fontSize: 10 }} />
            <YAxis tick={{ fontSize: 10 }} />
            <Tooltip labelFormatter={(v) => `${v}:00`} />
            <Legend wrapperStyle={{ fontSize: 10 }} />
            <Line type="monotone" dataKey="avg_bills" name="工作日均值" stroke="#3b82f6" dot={false} strokeWidth={2} />
            <Line type="monotone" dataKey="p85_bills" name="工作日P85" stroke="#3b82f6" strokeDasharray="5 5" dot={false} />
            <Line type="monotone" dataKey="p50_bills" name="工作日P50" stroke="#93c5fd" dot={false} />
          </LineChart>
        </ResponsiveContainer>
        <div className="mt-3">
          <ResponsiveContainer width="100%" height={300}>
            <LineChart data={weekendData}>
              <CartesianGrid strokeDasharray="3 3" />
              <XAxis dataKey="hour" tickFormatter={(v) => `${v}:00`} tick={{ fontSize: 10 }} />
              <YAxis tick={{ fontSize: 10 }} />
              <Tooltip labelFormatter={(v) => `${v}:00`} />
              <Legend wrapperStyle={{ fontSize: 10 }} />
              <Line type="monotone" dataKey="avg_bills" name="周末均值" stroke="#f97316" dot={false} strokeWidth={2} />
              <Line type="monotone" dataKey="p85_bills" name="周末P85" stroke="#f97316" strokeDasharray="5 5" dot={false} />
            </LineChart>
          </ResponsiveContainer>
        </div>
      </CollapsibleSection>

      {/* 客流稳定性明细 */}
      <CollapsibleSection title={`客流稳定性明细 (${trafficRows.length})`} subtitle="各时段波动率与稳定性评估">
        <FilterableTable
          data={trafficRows}
          filterKey="day_type"
          filterLabel="全部类型"
          sortOptions={[
            { key: 'hour', label: '时段' },
            { key: 'avg_bills', label: '均值' },
            { key: 'p85_bills', label: 'P85' },
            { key: 'volatility', label: '波动率' },
          ]}
          statusFilterKey="stability"
          statusFilterLabel="全部稳定性"
          statusOptions={[
            { value: '稳定', label: '稳定' },
            { value: '中等波动', label: '中等波动' },
            { value: '波动大', label: '波动大' },
          ]}
          columns={[
            { key: 'day_type', label: '日类型', align: 'center' },
            { key: 'hour', label: '时段', align: 'center', render: (r) => `${r.hour}:00` },
            { key: 'avg_bills', label: '均值', align: 'right' },
            { key: 'p50_bills', label: 'P50', align: 'right' },
            { key: 'p85_bills', label: 'P85', align: 'right' },
            { key: 'volatility', label: '波动率', align: 'right', render: (r) => r.volatility },
            { key: 'stability', label: '稳定性', align: 'center', render: (r) => (
              <span className={cn('inline-flex items-center rounded-md border px-2 py-0.5 text-xs font-medium', stabilityColor[r.stability] || 'bg-gray-100 text-gray-700 border-gray-300')}>
                {r.stability}
              </span>
            )},
          ]}
        />
      </CollapsibleSection>

      {/* 成本趋势 */}
      <CollapsibleSection title={`成本趋势 TOP20 (${costTrendRows.length})`} subtitle="菜品成本差异恶化排名">
        <FilterableTable
          data={costTrendRows}
          filterKey="dish_name"
          filterLabel="全部菜品"
          sortOptions={[
            { key: 'sales_amount', label: '销售额' },
            { key: 'theo_margin', label: '理论毛利率' },
            { key: 'actual_margin', label: '实际毛利率' },
            { key: 'variance', label: '差异金额' },
          ]}
          statusFilterKey="trend_status"
          statusFilterLabel="全部趋势"
          statusOptions={[
            { value: '恶化', label: '恶化' },
            { value: '关注', label: '关注' },
            { value: '正常', label: '正常' },
            { value: '数据异常', label: '数据异常' },
          ]}
          columns={[
            { key: 'dish_name', label: '菜品' },
            { key: 'category_level1', label: '分类' },
            { key: 'sales_amount', label: '销售额', align: 'right', render: (r) => formatCurrency(r.sales_amount) },
            { key: 'theo_margin', label: '理论毛利率', align: 'right', render: (r) => `${r.theo_margin}%` },
            { key: 'actual_margin', label: '实际毛利率', align: 'right', render: (r) => `${r.actual_margin}%` },
            { key: 'variance', label: '差异金额', align: 'right', render: (r) => formatCurrency(r.variance) },
            { key: 'trend_status', label: '趋势', align: 'center', render: (r) => (
              <span className={cn('inline-flex items-center rounded-md border px-2 py-0.5 text-xs font-medium', trendStatusColor[r.trend_status] || 'bg-gray-100 text-gray-700 border-gray-300')}>
                {r.trend_status}
              </span>
            )},
          ]}
        />
      </CollapsibleSection>

      {/* 人员流失预警 */}
      <CollapsibleSection title={`人员流失预警 (${turnoverRows.length})`} subtitle="有离职人员的门店流失率排名">
        <FilterableTable
          data={turnoverRows}
          filterKey="store_name"
          filterLabel="全部门店"
          sortOptions={[
            { key: 'total_emp', label: '总人数' },
            { key: 'left_count', label: '离职人数' },
            { key: 'new_count', label: '新入职' },
            { key: 'turnover_rate', label: '流失率' },
          ]}
          columns={[
            { key: 'store_name', label: '门店' },
            { key: 'total_emp', label: '总人数', align: 'center' },
            { key: 'left_count', label: '离职人数', align: 'center' },
            { key: 'new_count', label: '新入职', align: 'center' },
            { key: 'turnover_rate', label: '流失率', align: 'right', render: (r) => (
              <span className={Number(r.turnover_rate) > 20 ? 'font-bold text-red-600' : Number(r.turnover_rate) > 10 ? 'text-orange-600' : ''}>
                {r.turnover_rate}%
              </span>
            )},
          ]}
        />
      </CollapsibleSection>
    </div>
  )
}
