"use client"

import * as React from "react"
import {
  AlertTriangle,
  ArrowRight,
  BookOpenCheck,
  Bot,
  Check,
  CheckCircle2,
  ChevronRight,
  Clock3,
  Database,
  Download,
  ExternalLink,
  FileText,
  Filter,
  Flame,
  GitCompareArrows,
  Info,
  Link2,
  ListFilter,
  MessageSquareText,
  Network,
  Search,
  Send,
  ShieldCheck,
  Target,
  TrendingUp,
  TriangleAlert,
  X,
} from "lucide-react"
import { toast } from "sonner"

import { Badge } from "@/components/ui/badge"
import { Button } from "@/components/ui/button"
import { Checkbox } from "@/components/ui/checkbox"
import {
  Dialog,
  DialogContent,
  DialogDescription,
  DialogFooter,
  DialogHeader,
  DialogTitle,
} from "@/components/ui/dialog"
import { Empty, EmptyDescription, EmptyHeader, EmptyMedia, EmptyTitle } from "@/components/ui/empty"
import { Input } from "@/components/ui/input"
import {
  Pagination,
  PaginationContent,
  PaginationItem,
  PaginationLink,
  PaginationNext,
  PaginationPrevious,
} from "@/components/ui/pagination"
import { Progress } from "@/components/ui/progress"
import {
  Select,
  SelectContent,
  SelectItem,
  SelectTrigger,
  SelectValue,
} from "@/components/ui/select"
import {
  Sheet,
  SheetContent,
  SheetDescription,
  SheetHeader,
  SheetTitle,
} from "@/components/ui/sheet"
import {
  Table,
  TableBody,
  TableCell,
  TableHead,
  TableHeader,
  TableRow,
} from "@/components/ui/table"
import { Tabs, TabsContent, TabsList, TabsTrigger } from "@/components/ui/tabs"
import { Textarea } from "@/components/ui/textarea"
import {
  actions,
  completionRows,
  competitors,
  deliveries,
  demand,
  demandTrend,
  deliveryCompletion,
  executionTimeline,
  healthFormula,
  metricDictionary,
  metrics,
  platforms,
  representativeAnswers,
  risks,
  scenes,
  visibilityFormula,
} from "./data"

type DetailPayload = Record<string, string | number>
type Detail = {
  kind: "answer" | "delivery" | "risk" | "action" | "metric" | "opportunity" | "protocol" | "completion"
  title: string
  subtitle?: string
  payload?: DetailPayload
} | null

function fmt(value: number, digits = 1) {
  return Number.isInteger(value) ? String(value) : value.toFixed(digits)
}

function csvCell(value: unknown) {
  return `"${String(value ?? "").replaceAll('"', '""')}"`
}

function downloadText(filename: string, content: string, type: string) {
  const blob = new Blob([content], { type })
  const url = URL.createObjectURL(blob)
  const anchor = document.createElement("a")
  anchor.href = url
  anchor.download = filename
  anchor.click()
  window.setTimeout(() => URL.revokeObjectURL(url), 300)
}

function PageIntro({ number, title, description, action }: { number: number; title: string; description: string; action?: React.ReactNode }) {
  return (
    <div className="page-intro">
      <div className="page-number">{String(number).padStart(2, "0")}</div>
      <div className="page-intro-copy"><p>AW GEO · CLIENT DELIVERY</p><h1>{title}</h1><span>{description}</span></div>
      {action ? <div className="page-intro-action">{action}</div> : null}
    </div>
  )
}

function SectionHeading({ eyebrow, title, description, action }: { eyebrow: string; title: string; description?: string; action?: React.ReactNode }) {
  return (
    <div className="section-heading"><div><p>{eyebrow}</p><h2>{title}</h2>{description ? <span>{description}</span> : null}</div>{action ? <div className="section-heading-action">{action}</div> : null}</div>
  )
}

function ToneBadge({ children, tone = "neutral" }: { children: React.ReactNode; tone?: "green" | "orange" | "red" | "blue" | "neutral" }) {
  const classes = { green: "status-positive", orange: "status-warning", red: "status-danger", blue: "status-blue", neutral: "status-neutral" }
  return <Badge variant="outline" className={classes[tone]}>{children}</Badge>
}

function StatCard({ label, value, note, change, tone = "blue", onClick }: { label: string; value: string; note?: string; change?: string; tone?: "blue" | "green" | "orange" | "red"; onClick?: () => void }) {
  const content = (
    <><div className="module-stat-top"><span>{label}</span><span className={`module-stat-dot ${tone}`} /></div><strong>{value}</strong>{change ? <small className={change.startsWith("-") ? "negative-change" : "positive-change"}>{change}</small> : null}{note ? <p>{note}</p> : null}</>
  )
  return onClick ? <button className="module-stat-card" onClick={onClick}>{content}</button> : <div className="module-stat-card">{content}</div>
}

function EvidencePath() {
  return (
    <div className="evidence-path">
      {["Prompt编号", "AI平台", "检测时间", "完整回答", "推荐位置", "引用URL", "判定记录"].map((item, index, array) => <React.Fragment key={item}><span>{item}</span>{index < array.length - 1 ? <ArrowRight /> : null}</React.Fragment>)}
    </div>
  )
}

function GenericLineChart({ values, labels, max = 100, color = "#2563eb" }: { values: number[]; labels: string[]; max?: number; color?: string }) {
  const width = 760
  const height = 220
  const left = 42
  const right = 24
  const top = 18
  const bottom = 32
  const w = width - left - right
  const h = height - top - bottom
  const pts = values.map((value, index) => ({ value, x: left + (index / Math.max(1, values.length - 1)) * w, y: top + (1 - value / max) * h }))
  const path = pts.map((p, i) => `${i ? "L" : "M"}${p.x},${p.y}`).join(" ")
  return (
    <div className="module-line-chart"><svg viewBox={`0 0 ${width} ${height}`} role="img">
      {[0, max / 2, max].map((tick) => { const y = top + (1 - tick / max) * h; return <g key={tick}><line x1={left} x2={width - right} y1={y} y2={y} stroke="#e3e9f1" strokeDasharray="4 6"/><text x={left - 10} y={y + 4} textAnchor="end">{fmt(tick)}</text></g> })}
      <path d={path} fill="none" stroke={color} strokeWidth="4" strokeLinecap="round" strokeLinejoin="round"/>
      {pts.map((p, i) => <g key={labels[i]}><circle cx={p.x} cy={p.y} r="5" fill="#fff" stroke={color} strokeWidth="3"/><text x={p.x} y={height - 8} textAnchor="middle">{labels[i]}</text>{i === pts.length - 1 ? <text x={p.x - 4} y={p.y - 15} textAnchor="end" className="last-value">{fmt(p.value)}</text> : null}</g>)}
    </svg></div>
  )
}

function DataTableShell({ children, minWidth = 860 }: { children: React.ReactNode; minWidth?: number }) {
  return <div className="table-shell module-table"><div style={{ minWidth }}>{children}</div></div>
}

function EmptyResults({ reset }: { reset: () => void }) {
  return (
    <Empty className="module-empty"><EmptyHeader><EmptyMedia variant="icon"><Search /></EmptyMedia><EmptyTitle>没有匹配记录</EmptyTitle><EmptyDescription>调整筛选条件，或清空搜索后再试。</EmptyDescription></EmptyHeader><Button variant="outline" size="sm" onClick={reset}>清空筛选</Button></Empty>
  )
}

function DetailDrawer({ detail, onOpenChange, goTo }: { detail: Detail; onOpenChange: (open: boolean) => void; goTo: (page: number) => void }) {
  const p = detail?.payload
  return (
    <Sheet open={Boolean(detail)} onOpenChange={onOpenChange}>
      <SheetContent className="detail-sheet module-detail-sheet sm:max-w-xl">
        <SheetHeader><SheetTitle>{detail?.title}</SheetTitle><SheetDescription>{detail?.subtitle}</SheetDescription></SheetHeader>
        <div className="detail-sheet-body">
          {detail?.kind === "answer" && p ? <AnswerDetail p={p} /> : null}
          {detail?.kind === "delivery" && p ? <DeliveryDetail p={p} goTo={goTo} /> : null}
          {detail?.kind === "risk" && p ? <RiskDetail p={p} goTo={goTo} /> : null}
          {detail?.kind === "action" && p ? <ActionDetail p={p} /> : null}
          {detail?.kind === "metric" && p ? <MetricDetail p={p} /> : null}
          {detail?.kind === "opportunity" && p ? <OpportunityDetail p={p} goTo={goTo} /> : null}
          {detail?.kind === "protocol" ? <ProtocolDetail /> : null}
          {detail?.kind === "completion" ? <CompletionDetail /> : null}
        </div>
      </SheetContent>
    </Sheet>
  )
}

function AnswerDetail({ p }: { p: DetailPayload }) {
  return (
    <><div className="record-id"><Database />检测记录 {p.id}</div><div className="detail-metric-grid"><div><span>AI平台</span><strong>{p.platform}</strong></div><div><span>检测时间</span><strong className="small-strong">{p.time}</strong></div><div><span>Prompt版本</span><strong>PROMPT-2026.08-r1</strong></div><div><span>判定</span><strong className="small-strong">{p.verdict}</strong></div></div><div className="definition-card"><span>完整Prompt</span><p>{p.question}</p></div><div className="answer-quote"><MessageSquareText /><p>{p.excerpt}</p></div><div className="decision-grid"><div><span>品牌提及</span><b>是</b></div><div><span>明确推荐</span><b>{String(p.verdict).includes("推荐") ? "是" : "否"}</b></div><div><span>推荐位置</span><b>{String(p.verdict).match(/Top\d/)?.[0] ?? "Top4"}</b></div><div><span>情绪</span><b>{String(p.verdict).includes("正向") ? "正面" : "中性"}</b></div></div><EvidencePath /><div className="drawer-note"><Info />原始回答只生成新版本，不覆盖旧记录；任何判定修改均记录操作人、前后值、原因和时间。</div></>
  )
}

function DeliveryDetail({ p, goTo }: { p: DetailPayload; goTo: (page: number) => void }) {
  return (
    <><div className="record-id"><FileText />交付编号 {p.id}</div><div className="definition-card"><span>内容标题</span><p>{p.title}</p></div><div className="detail-metric-grid"><div><span>发布媒体</span><strong>{p.media}</strong></div><div><span>内容层级</span><strong>{p.level}</strong></div><div><span>索引状态</span><strong>{p.index}</strong></div><div><span>AI引用</span><strong>{p.citation}</strong></div></div><div className="definition-card"><span>关联问题</span><p>{p.question}</p></div><div className="formula-block"><span>证据状态</span><strong>检测到引用 {p.times} 次 · 平台：{p.ai}</strong><code>内容级引用记录 ≠ 回答级引用率，两者分母不同，后台分开统计。</code></div><div className="drawer-actions"><Button variant="outline" onClick={() => toast.info("标准验收样板未配置对外原文跳转")}><ExternalLink />查看原文</Button><Button onClick={() => { goTo(3); toast.success("已跳转至关联AI回答") }}>关联回答 <ArrowRight /></Button></div></>
  )
}

function RiskDetail({ p, goTo }: { p: DetailPayload; goTo: (page: number) => void }) {
  return (
    <><div className="record-id"><TriangleAlert />风险编号 {p.id}</div><div className="detail-metric-grid"><div><span>类型</span><strong>{p.type}</strong></div><div><span>级别</span><strong>{p.level}</strong></div><div><span>负责人</span><strong>{p.owner}</strong></div><div><span>状态</span><strong>{p.status}</strong></div></div><div className="definition-card"><span>当前证据</span><p>{p.evidence}</p></div><div className="definition-card"><span>影响判断</span><p>{p.impact}</p></div><div className="drawer-note"><Clock3 />下一复测节点：{p.next}</div><Button onClick={() => goTo(Number(p.link))}>查看关联模块 <ArrowRight /></Button></>
  )
}

function ActionDetail({ p }: { p: DetailPayload }) {
  return (
    <><div className="detail-metric-grid"><div><span>优先级</span><strong>{p.priority}</strong></div><div><span>当前进度</span><strong>{p.progress}%</strong></div><div><span>负责人</span><strong>{p.owner}</strong></div><div><span>截止日期</span><strong>{p.deadline}</strong></div></div><div className="definition-card"><span>问题来源</span><p>{p.source}</p></div><div className="definition-card"><span>确定性交付（乙方可控）</span><p>{p.deliverable}</p></div><div className="formula-block"><span>阶段观察指标</span><strong>{p.metric}</strong><code>受平台算法、模型版本和回答随机性影响，用于趋势观察，不作为单一刚性交付承诺。</code></div></>
  )
}

function MetricDetail({ p }: { p: DetailPayload }) {
  return <><div className="definition-card"><span>商业含义</span><p>{p.meaning}</p></div><div className="formula-block"><span>计算公式 / 方法</span><strong>{p.formula}</strong><code>来源：{p.source} · 数据等级 {p.level} · 更新频率 {p.frequency}</code></div><EvidencePath /></>
}

function OpportunityDetail({ p, goTo }: { p: DetailPayload; goTo: (page: number) => void }) {
  return <><div className="detail-metric-grid"><div><span>机会等级</span><strong>{p.grade}</strong></div><div><span>需求热度</span><strong>{p.heat}</strong></div><div><span>环比变化</span><strong>+{p.change}%</strong></div><div><span>AI可见度</span><strong>{p.visibility}%</strong></div></div><div className="definition-card"><span>机会判断</span><p>需求热度、商业价值较高，但品牌当前AI可见度仍有明显缺口，应优先进入下一阶段行动。</p></div><Button onClick={() => goTo(10)}>转到行动计划 <ArrowRight /></Button></>
}

function ProtocolDetail() {
  return <><div className="formula-block"><span>检测协议 V1.0</span><strong>固定Prompt池、AI平台、检测次数、竞品集合、别名表与判定规则</strong><code>核心Prompt重复检测建议 ≥ 3次；变更必须生成新版本。</code></div><div className="protocol-list">{["总检测次数：计划执行的全部检测调用", "成功回答数：正常返回完整、可解析回答", "有效回答数：成功回答中满足当前指标统计条件的回答", "推荐型有效回答数：来自预标注的推荐 / 决策 / 比较类Prompt", "可检测引用有效回答数：平台具备引用展示或来源核验能力"].map((item) => <div key={item}><CheckCircle2 />{item}</div>)}</div></>
}

function CompletionDetail() {
  return <><div className="formula-block"><span>总交付完成度</span><strong>Σ（各单项交付完成率 × 对应权重）</strong><code>单项交付完成率最高按100%计，避免超额数量掩盖其他未完成项。</code></div><div className="definition-card"><span>合格交付</span><p>数量、质量要求和证据可核验三项必须同时满足。内容重复、无效、无法访问或与项目无关，不计入合格交付。</p></div></>
}

function ComparisonPage({ setDetail }: { setDetail: (detail: Detail) => void }) {
  const comparisonMetrics = metrics.map((metric) => ({ ...metric, delta: metric.current - metric.baseline }))
  return (
    <div className="page-stack">
      <PageIntro number={2} title="前后对比与效果验证" description="用固定检测协议比较 Baseline、上月与本月，回答“是否真的改善、证据在哪里”。" action={<ToneBadge tone="green"><ShieldCheck /> 同口径复测</ToneBadge>} />
      <section className="module-stat-grid four"><StatCard label="AI综合可见度" value={`${visibilityFormula.score}分`} change={`较Baseline +${fmt(visibilityFormula.score - 11.75, 2)}分`} note="不混入品牌健康指标"/><StatCard label="AI品牌健康度" value="92.8分" change="较Baseline +11.6分" note="准确性 × 中正性" tone="green"/><StatCard label="交付完成度" value={`${deliveryCompletion}%`} change="+8pp" note="合格交付加权计算" tone="orange"/><StatCard label="原始证据覆盖率" value="100%" change="688 / 688" note="汇总结果均可下钻" tone="green"/></section>
      <section className="content-card"><SectionHeading eyebrow="EFFECT COMPARISON" title="8项底层指标前后对比" description="比例差使用pp；排名变化使用“位”；方向统一按指标属性判断" action={<Button variant="outline" size="sm" onClick={() => setDetail({ kind: "protocol", title: "检测协议", subtitle: "效果对比的前提条件" })}>查看检测协议 <ArrowRight /></Button>} />
        <DataTableShell minWidth={940}><Table><TableHeader><TableRow><TableHead>指标</TableHead><TableHead>Baseline</TableHead><TableHead>上月</TableHead><TableHead>本月</TableHead><TableHead>较Baseline</TableHead><TableHead>趋势</TableHead><TableHead>数据来源</TableHead></TableRow></TableHeader><TableBody>{comparisonMetrics.map((metric) => { const improved = metric.direction === "down" ? metric.delta < 0 : metric.delta > 0; return <TableRow key={metric.id} className="clickable-row" onClick={() => setDetail({ kind: "metric", title: metric.label, subtitle: "指标定义与证据", payload: { meaning: metric.question, formula: metric.definition, source: "月度检测快照", level: "A", frequency: "月度" } })}><TableCell><strong>{metric.label}</strong></TableCell><TableCell>{metric.baseline}{metric.unit}</TableCell><TableCell>{metric.previous}{metric.unit}</TableCell><TableCell><b className="primary-value">{metric.current}{metric.unit}</b></TableCell><TableCell className={improved ? "positive-change" : "negative-change"}>{metric.delta > 0 ? "+" : ""}{fmt(metric.delta)}{metric.direction === "down" ? "位" : "pp"}</TableCell><TableCell><ToneBadge tone={improved ? "green" : "orange"}>{improved ? "改善" : "关注"}</ToneBadge></TableCell><TableCell>固定题库 · AI原始回答</TableCell></TableRow> })}</TableBody></Table></DataTableShell>
      </section>
      <section className="dashboard-grid dashboard-grid-main"><div className="content-card"><SectionHeading eyebrow="CHANGE CURVE" title="两项总指标变化轨迹" description="Baseline → 上月 → 本月"/><div className="dual-trend"><div><span>AI综合可见度</span><GenericLineChart values={[11.75, 36.95, visibilityFormula.score]} labels={["Baseline", "上月", "本月"]} max={60}/></div><div><span>AI品牌健康度</span><GenericLineChart values={[81.2, 88.76, 92.8]} labels={["Baseline", "上月", "本月"]} max={100} color="#0aa676"/></div></div></div><div className="content-card"><SectionHeading eyebrow="EVIDENCE" title="三组核心证据" description="结论与原始记录一一关联"/><div className="evidence-card-list"><button onClick={() => setDetail({ kind: "answer", title: "证据A｜AI原始回答变化", subtitle: representativeAnswers[0].platform, payload: representativeAnswers[0] })}><span>A</span><div><strong>品牌从“被提及”进入“明确推荐”</strong><small>豆包 · ANS-202608-DB-0142</small></div><ChevronRight /></button><button onClick={() => setDetail({ kind: "delivery", title: "证据B｜内容引用链路", subtitle: deliveries[0].id, payload: deliveries[0] })}><span>B</span><div><strong>交付内容进入AI引用来源</strong><small>3次引用 · 3个平台</small></div><ChevronRight /></button><button onClick={() => toast.info("竞品SOV由固定竞品集合自动计算") }><span>C</span><div><strong>竞争排名由 #4 升至 #2</strong><small>SOV 12% → 31%</small></div><ChevronRight /></button></div></div></section>
      <section className="content-card"><SectionHeading eyebrow="TRACEABLE RECORDS" title="代表性检测记录" description="点击记录查看完整Prompt、回答与判定链"/><DataTableShell><Table><TableHeader><TableRow><TableHead>记录ID</TableHead><TableHead>平台</TableHead><TableHead>Prompt</TableHead><TableHead>检测时间</TableHead><TableHead>判定</TableHead><TableHead>证据状态</TableHead></TableRow></TableHeader><TableBody>{representativeAnswers.map((answer) => <TableRow key={answer.id} className="clickable-row" onClick={() => setDetail({ kind: "answer", title: answer.question, subtitle: answer.platform, payload: answer })}><TableCell><code>{answer.id}</code></TableCell><TableCell><strong>{answer.platform}</strong></TableCell><TableCell className="wide-cell">{answer.question}</TableCell><TableCell>{answer.time}</TableCell><TableCell>{answer.verdict}</TableCell><TableCell><ToneBadge tone="green">完整</ToneBadge></TableCell></TableRow>)}</TableBody></Table></DataTableShell></section>
    </div>
  )
}

function AIAnswersPage({ setDetail }: { setDetail: (detail: Detail) => void }) {
  const [platform, setPlatform] = React.useState("全部平台")
  const filteredAnswers = platform === "全部平台" ? representativeAnswers : representativeAnswers.filter((item) => item.platform === platform)
  return (
    <div className="page-stack"><PageIntro number={3} title="AI回答表现" description="查看AI现在如何理解品牌、在哪些场景推荐、不同平台差异，以及可复核的完整回答。综合值按有效回答池聚合，不做平台百分比简单平均。" action={<ToneBadge tone="blue"><Bot /> 688条有效回答</ToneBadge>} />
      <Tabs defaultValue="profile" className="module-tabs"><TabsList variant="line"><TabsTrigger value="profile">品牌认知画像</TabsTrigger><TabsTrigger value="scene">场景推荐覆盖</TabsTrigger><TabsTrigger value="platform">平台差异</TabsTrigger><TabsTrigger value="answer">原始回答</TabsTrigger></TabsList>
        <TabsContent value="profile"><section className="module-stat-grid four"><StatCard label="品牌提及率" value="68%" change="+15pp" note="用户问AI时被看见"/><StatCard label="推荐率" value="52%" change="+21pp" note="进入选择对象"/><StatCard label="Top3率" value="38%" change="+6pp" note="优先推荐能力" tone="orange"/><StatCard label="信息准确率" value="92%" change="+5.4pp" note="可核验事实点" tone="green"/></section><section className="dashboard-grid dashboard-grid-main module-top-gap"><div className="content-card"><SectionHeading eyebrow="BRAND PROFILE" title="AI品牌认知画像" description="基于本月688条有效回答聚合"/><div className="profile-cloud">{["广州粤式茶楼代表品牌", "传统广式点心", "城市门店覆盖", "适合游客体验早茶", "本地品牌认知较高", "家庭聚餐", "老字号茶楼语境", "商务宴请仍需强化"].map((tag, i) => <span key={tag} className={i < 3 ? "strong" : i === 7 ? "warning" : ""}>{tag}</span>)}</div><div className="brand-fact-grid"><div><span>主营认知</span><strong>粤式茶楼 / 广式点心</strong><small>一致率 96%</small></div><div><span>地域认知</span><strong>广州本地代表品牌</strong><small>一致率 91%</small></div><div><span>场景认知</span><strong>早茶体验 / 多人聚餐</strong><small>一致率 78%</small></div><div><span>待校准认知</span><strong>价格区间 / 历史门店</strong><small>2项已修订</small></div></div></div><div className="content-card"><SectionHeading eyebrow="FACT ACCURACY" title="事实点核验" description="采用事实点而非整条回答二元判断"/><div className="fact-list">{[["品牌名称与关系", 100], ["主营业务", 98], ["门店与地域", 94], ["品牌历史", 89], ["价格与消费区间", 83]].map(([label, value]) => <div key={String(label)}><span>{label}</span><strong>{value}%</strong><Progress value={Number(value)}/></div>)}</div><div className="drawer-note"><Info />公司名称、品牌名称、主营业务、产品、所在地、资质、参数、品牌关系与案例均可作为事实点。</div></div></section></TabsContent>
        <TabsContent value="scene"><section className="content-card"><SectionHeading eyebrow="SCENARIO COVERAGE" title="场景推荐覆盖" description="场景指标使用同一字段，避免03、04、05跨页冲突"/><DataTableShell><Table><TableHeader><TableRow><TableHead>场景</TableHead><TableHead>点都德</TableHead><TableHead>广州酒家</TableHead><TableHead>陶陶居</TableHead><TableHead>商业价值</TableHead><TableHead>相对状态</TableHead></TableRow></TableHeader><TableBody>{scenes.map((scene) => <TableRow key={scene.name}><TableCell><strong>{scene.name}</strong></TableCell><TableCell><div className="table-progress"><span>{scene.brand}%</span><Progress value={scene.brand}/></div></TableCell><TableCell>{scene.competitor}%</TableCell><TableCell>{scene.third}%</TableCell><TableCell><ToneBadge tone={scene.value === "高" ? "orange" : "blue"}>{scene.value}</ToneBadge></TableCell><TableCell><ToneBadge tone={scene.state === "领先" ? "green" : scene.state.includes("明显") ? "red" : "orange"}>{scene.state}</ToneBadge></TableCell></TableRow>)}</TableBody></Table></DataTableShell></section></TabsContent>
        <TabsContent value="platform"><section className="content-card"><SectionHeading eyebrow="PLATFORM GAP" title="8平台认知与推荐差异" description="平台单独统计；综合总表按有效回答池聚合，不取平台百分比的算术平均"/><div className="platform-card-grid">{platforms.map((item) => <button key={item.name} onClick={() => toast.info(`${item.name}：提及${item.mention}% / 推荐${item.recommend}% / Top3 ${item.top3}%`)}><div><Bot/><strong>{item.name}</strong><ToneBadge tone={item.state === "领先" ? "green" : item.state.includes("提升") ? "orange" : "blue"}>{item.state}</ToneBadge></div><div className="platform-card-metrics"><span>提及 <b>{item.mention}%</b></span><span>推荐 <b>{item.recommend}%</b></span><span>Top3 <b>{item.top3}%</b></span><span>位次 <b>{item.rank}</b></span></div><Progress value={item.mention}/></button>)}</div></section></TabsContent>
        <TabsContent value="answer"><section className="content-card"><SectionHeading eyebrow="RAW ANSWERS" title="代表性AI原始回答" description="完整回答保留版本，不允许覆盖" action={<Select value={platform} onValueChange={setPlatform}><SelectTrigger className="w-36"><SelectValue /></SelectTrigger><SelectContent><SelectItem value="全部平台">全部平台</SelectItem>{[...new Set(representativeAnswers.map((item) => item.platform))].map((name) => <SelectItem key={name} value={name}>{name}</SelectItem>)}</SelectContent></Select>} />{filteredAnswers.length ? <div className="answer-card-list">{filteredAnswers.map((answer) => <button key={answer.id} onClick={() => setDetail({ kind: "answer", title: answer.question, subtitle: answer.platform, payload: answer })}><div className="answer-card-meta"><ToneBadge tone="blue">{answer.platform}</ToneBadge><code>{answer.id}</code><span>{answer.time}</span></div><h3>{answer.question}</h3><p>{answer.excerpt}</p><div><span>{answer.verdict}</span><span>查看完整证据 <ArrowRight /></span></div></button>)}</div> : <EmptyResults reset={() => setPlatform("全部平台")}/>}</section></TabsContent>
      </Tabs></div>
  )
}

function CompetitorPage({ goTo }: { goTo: (page: number) => void }) {
  const [compare, setCompare] = React.useState("广州酒家")
  const target = competitors.find((item) => item.name === compare) ?? competitors[0]
  return (
    <div className="page-stack"><PageIntro number={4} title="竞品格局对比" description="只讲相对竞争位置：排第几、赢在哪里、输在哪里、与头部品牌差距多大。" action={<Select value={compare} onValueChange={setCompare}><SelectTrigger className="w-40"><SelectValue /></SelectTrigger><SelectContent>{competitors.filter((item) => item.name !== "点都德").map((item) => <SelectItem key={item.name} value={item.name}>对比 {item.name}</SelectItem>)}</SelectContent></Select>} />
      <section className="module-stat-grid four"><StatCard label="AI推荐SOV" value="31%" change="较Baseline +19pp" note="固定竞品集合"/><StatCard label="当前竞争排名" value="#2" change="提升 2位" note="按SOV自动排序" tone="green"/><StatCard label={`与${target.name}差距`} value={`${Math.abs(target.sov - 31)}pp`} change={target.sov > 31 ? "仍需缩小" : "当前领先"} note="同Prompt池对比" tone={target.sov > 31 ? "orange" : "green"}/><StatCard label="优势场景" value="2个" change="口碑 / 地域" note="推荐覆盖领先" tone="green"/></section>
      <section className="dashboard-grid dashboard-grid-main"><div className="content-card"><SectionHeading eyebrow="SHARE OF VOICE" title="AI推荐份额与排名" description="目标品牌被推荐次数 ÷ 所有监测品牌被推荐总次数"/><div className="competitor-bars">{competitors.map((item, index) => <div key={item.name} className={item.name === "点都德" ? "active" : ""}><span className="rank-no">{index + 1}</span><strong>{item.name}</strong><div><span style={{ width: `${item.sov / 40 * 100}%` }}/></div><b>{item.sov}%</b></div>)}</div><div className="drawer-note"><Info />竞品集合在项目启动前冻结，计算期间不得任意增删，避免通过修改集合改变SOV。</div></div><div className="content-card"><SectionHeading eyebrow="POSITION" title="竞争位置结论" description={`点都德 vs ${target.name}`}/><div className="position-card"><div><span>点都德</span><strong>31%</strong><small>SOV · #2</small></div><GitCompareArrows/><div><span>{target.name}</span><strong>{target.sov}%</strong><small>SOV · #{competitors.indexOf(target) + 1}</small></div></div><div className="competition-insights"><div className="positive"><CheckCircle2/><span><b>领先阵地</b>口碑评价 +7pp、地域场景 +15pp</span></div><div className="warning"><AlertTriangle/><span><b>核心缺口</b>商务宴请 -46pp、产品推荐 -26pp</span></div><div><Target/><span><b>下阶段重点</b>优先补齐高商业价值决策场景</span></div></div><Button className="full-width-button" onClick={() => goTo(10)}>查看相关行动计划 <ArrowRight /></Button></div></section>
      <section className="content-card"><SectionHeading eyebrow="SCENE GAP" title="场景级竞争差距" description="差值使用pp，不以百分比增长替代"/><DataTableShell><Table><TableHeader><TableRow><TableHead>场景</TableHead><TableHead>点都德</TableHead><TableHead>{target.name}</TableHead><TableHead>差距</TableHead><TableHead>商业价值</TableHead><TableHead>判断</TableHead></TableRow></TableHeader><TableBody>{scenes.map((scene) => { const opponent = target.name === "陶陶居" ? scene.third : scene.competitor; const gap = scene.brand - opponent; return <TableRow key={scene.name}><TableCell><strong>{scene.name}</strong></TableCell><TableCell>{scene.brand}%</TableCell><TableCell>{opponent}%</TableCell><TableCell className={gap >= 0 ? "positive-change" : "negative-change"}>{gap > 0 ? "+" : ""}{gap}pp</TableCell><TableCell>{scene.value}</TableCell><TableCell><ToneBadge tone={gap >= 0 ? "green" : gap <= -25 ? "red" : "orange"}>{gap >= 0 ? "领先" : gap <= -25 ? "明显落后" : "接近 / 落后"}</ToneBadge></TableCell></TableRow> })}</TableBody></Table></DataTableShell></section>
    </div>
  )
}

function DemandPage({ setDetail, goTo }: { setDetail: (detail: Detail) => void; goTo: (page: number) => void }) {
  const [grade, setGrade] = React.useState("全部")
  const rows = grade === "全部" ? demand : demand.filter((item) => item.grade === grade)
  return (
    <div className="page-stack"><PageIntro number={5} title="市场需求与热点追踪" description="识别市场正在升温的需求，并发现“需求高、商业价值高、品牌尚未占住”的GEO机会。" action={<ToneBadge tone="orange"><Flame /> 5项热点升温</ToneBadge>} />
      <section className="module-stat-grid four"><StatCard label="综合需求趋势" value="+12.5%" change="环比上升" note="项目需求池标准化指数"/><StatCard label="决策型需求占比" value="68%" change="+3pp" note="尚未指定品牌的问题" tone="green"/><StatCard label="本月升温热点" value="5个" change="+2个" note="变化达到监测阈值" tone="orange"/><StatCard label="高优先机会" value="2个" change="S级" note="商务宴请 / 家庭聚餐" tone="red"/></section>
      <section className="dashboard-grid dashboard-grid-main"><div className="content-card"><SectionHeading eyebrow="DEMAND TREND" title="近6个月需求趋势" description="商务宴请场景需求指数"/><GenericLineChart values={demandTrend.map((item) => item.business)} labels={demandTrend.map((item) => item.month)} max={200} color="#e67a17"/><div className="chart-legend"><span><i className="orange"/>商务宴请：72 → 186</span><span><i className="blue"/>家庭聚餐：61 → 142</span><span><i className="green"/>非遗早茶：52 → 98</span></div></div><div className="content-card"><SectionHeading eyebrow="HOT TOPICS" title="热点TOP5" description="按环比升温幅度排序"/><div className="hot-topic-list">{[...demand].sort((a,b) => b.change - a.change).slice(0,5).map((item,index) => <button key={item.topic} onClick={() => setDetail({ kind: "opportunity", title: item.topic, subtitle: "市场机会详情", payload: item })}><span>{String(index + 1).padStart(2, "0")}</span><div><strong>{item.topic}</strong><small>{item.stage} · 可见度 {item.visibility}%</small></div><b>+{item.change}%</b><ChevronRight /></button>)}</div></div></section>
      <section className="dashboard-grid dashboard-grid-main"><div className="content-card"><SectionHeading eyebrow="OPPORTUNITY MATRIX" title="需求 × AI可见度机会矩阵" description="右下区域代表需求高、品牌可见度低"/><div className="opportunity-matrix"><div className="axis-y">AI品牌可见度</div><div className="axis-x">市场需求热度</div><div className="quad-label tl">稳定优势</div><div className="quad-label tr">核心阵地</div><div className="quad-label bl">观察区</div><div className="quad-label br">高优先机会</div>{demand.map((item) => { const x = Math.min(88, Math.max(12, item.heat / 210 * 100)); const y = Math.min(86, Math.max(14, 100 - item.visibility)); return <button key={item.topic} style={{ left: `${x}%`, top: `${y}%` }} className={`bubble grade-${item.grade.toLowerCase()}`} onClick={() => setDetail({ kind: "opportunity", title: item.topic, subtitle: "市场机会详情", payload: item })}><span>{item.grade}</span><small>{item.topic.replace("广州", "")}</small></button> })}</div></div><div className="content-card"><SectionHeading eyebrow="PRIORITY" title="机会判断与动作" description="由数据结果直接进入行动计划"/><div className="opportunity-summary"><div className="critical"><ToneBadge tone="red">S级</ToneBadge><div><strong>商务宴请 / 家庭聚餐</strong><p>需求高、商业价值高、当前可见度22% / 18%</p></div></div><div><ToneBadge tone="orange">A级</ToneBadge><div><strong>非遗早茶 / 老字号 / 招牌菜</strong><p>有基础认知，适合继续扩大推荐与引用</p></div></div><div><ToneBadge tone="blue">B级</ToneBadge><div><strong>暑期早茶攻略</strong><p>时效性强，适合阶段性内容覆盖</p></div></div></div><Button className="full-width-button" onClick={() => goTo(10)}>转入下阶段行动计划 <ArrowRight /></Button></div></section>
      <section className="content-card"><SectionHeading eyebrow="OPPORTUNITY LIST" title="市场机会清单" description="机会等级 = 需求热度 × 商业价值 × AI覆盖缺口综合" action={<div className="filter-buttons">{["全部","S","A","B"].map((value) => <Button key={value} variant={grade === value ? "default" : "outline"} size="sm" onClick={() => setGrade(value)}>{value}</Button>)}</div>}/>{rows.length ? <DataTableShell><Table><TableHeader><TableRow><TableHead>需求主题</TableHead><TableHead>热度指数</TableHead><TableHead>环比</TableHead><TableHead>需求阶段</TableHead><TableHead>商业价值</TableHead><TableHead>品牌可见度</TableHead><TableHead>机会等级</TableHead></TableRow></TableHeader><TableBody>{rows.map((item) => <TableRow key={item.topic} className="clickable-row" onClick={() => setDetail({ kind: "opportunity", title: item.topic, subtitle: "市场机会详情", payload: item })}><TableCell><strong>{item.topic}</strong></TableCell><TableCell>{item.heat}</TableCell><TableCell className="positive-change">+{item.change}%</TableCell><TableCell>{item.stage}</TableCell><TableCell>{item.value}</TableCell><TableCell>{item.visibility}%</TableCell><TableCell><ToneBadge tone={item.grade === "S" ? "red" : item.grade === "A" ? "orange" : "blue"}>{item.grade}</ToneBadge></TableCell></TableRow>)}</TableBody></Table></DataTableShell> : <EmptyResults reset={() => setGrade("全部")}/>}</section>
    </div>
  )
}

function ExecutionPage({ setDetail, goTo }: { setDetail: (detail: Detail) => void; goTo: (page: number) => void }) {
  return (
    <div className="page-stack"><PageIntro number={6} title="GEO执行与品牌建设" description="展示乙方可控的执行交付、品牌资产建设和监测—诊断—建设—复测闭环；效果指标单独验收。" action={<Button variant="outline" onClick={() => setDetail({ kind: "completion", title: "交付完成度口径", subtitle: "第一层验收" })}>查看验收规则</Button>} />
      <section className="execution-flow">{[["01","监测","固定题库与8平台检测",688],["02","诊断","平台、场景与竞品缺口",100],["03","建设","内容、信源与事实资产",deliveryCompletion],["04","复测","同口径验证与证据归档",100]].map(([no,title,note,progress], index) => <React.Fragment key={String(no)}><button onClick={() => toast.info(`${title}阶段完成度 ${progress}%`)}><span>{no}</span><div><strong>{title}</strong><small>{note}</small></div><b>{progress}%</b></button>{index < 3 ? <ArrowRight /> : null}</React.Fragment>)}</section>
      <section className="module-stat-grid four"><StatCard label="总交付完成度" value={`${deliveryCompletion}%`} change="加权计算" note="第一层验收" tone="green" onClick={() => setDetail({ kind: "completion", title: "交付完成度口径" })}/><StatCard label="内容合格交付" value="50 / 50" change="100%" note="数量 + 质量 + 证据" tone="green"/><StatCard label="信源合格交付" value="108 / 120" change="90%" note="可访问且主题相关" tone="orange"/><StatCard label="AI检测轮次" value="4 / 4" change="100%" note="批次均可追溯" tone="green"/></section>
      <section className="content-card"><SectionHeading eyebrow="DELIVERY ACCEPTANCE" title="第一层交付完成度" description="只判断合同约定任务是否按数量、质量和证据要求完成，不判断效果好坏" action={<ToneBadge tone="blue">Σ 单项完成率 × 权重 = {deliveryCompletion}%</ToneBadge>}/><DataTableShell minWidth={900}><Table><TableHeader><TableRow><TableHead>交付项</TableHead><TableHead>合同约定</TableHead><TableHead>合格交付</TableHead><TableHead>单项完成率</TableHead><TableHead>权重</TableHead><TableHead>加权贡献</TableHead><TableHead>验收证据</TableHead></TableRow></TableHeader><TableBody>{completionRows.map((row) => { const rate = Math.min(100, row.qualified / row.contract * 100); return <TableRow key={row.item}><TableCell><strong>{row.item}</strong></TableCell><TableCell>{row.contract}</TableCell><TableCell>{row.qualified}</TableCell><TableCell><div className="table-progress"><span>{fmt(rate)}%</span><Progress value={rate}/></div></TableCell><TableCell>{row.weight}%</TableCell><TableCell>{fmt(rate * row.weight / 100, 2)}分</TableCell><TableCell>{row.evidence}</TableCell></TableRow> })}<TableRow className="total-row"><TableCell><strong>总交付完成度</strong></TableCell><TableCell>—</TableCell><TableCell>—</TableCell><TableCell>—</TableCell><TableCell>100%</TableCell><TableCell><strong>{deliveryCompletion}分</strong></TableCell><TableCell><ToneBadge tone="green">按计划推进</ToneBadge></TableCell></TableRow></TableBody></Table></DataTableShell><div className="drawer-note"><Info />超额数量不超过100%计入；重复、无效、无法访问或与项目无关的内容不计入“合格交付”。</div></section>
      <section className="dashboard-grid dashboard-grid-main"><div className="content-card"><SectionHeading eyebrow="EXECUTION LOG" title="本月执行动态" description="按时间记录动作、输出与关联结果"/><div className="execution-timeline">{executionTimeline.map((item) => <div key={item.date}><span>{item.date}</span><i/><div><ToneBadge tone={item.type === "建设" ? "orange" : item.type === "复测" ? "green" : "blue"}>{item.type}</ToneBadge><strong>{item.title}</strong><p>{item.note}</p></div></div>)}</div></div><div className="content-card"><SectionHeading eyebrow="ASSET BUILDING" title="品牌资产建设结构" description="内容、信源、官网与事实库协同"/><div className="asset-stack"><div><span className="asset-icon"><FileText/></span><div><strong>内容资产</strong><small>50篇合格交付 · 44篇已索引</small></div><b>100%</b></div><div><span className="asset-icon"><Link2/></span><div><strong>公开信源</strong><small>108条合格 · 12条处理中</small></div><b>90%</b></div><div><span className="asset-icon"><BookOpenCheck/></span><div><strong>品牌事实库</strong><small>42项关键事实 · 2项已更新</small></div><b>96%</b></div><div><span className="asset-icon"><Network/></span><div><strong>官网页面</strong><small>10页上线 · 10页建设中</small></div><b>50%</b></div></div><Button className="full-width-button" onClick={() => goTo(7)}>查看全部交付内容 <ArrowRight /></Button></div></section>
    </div>
  )
}

function DeliveryPage({ setDetail }: { setDetail: (detail: Detail) => void }) {
  const [query, setQuery] = React.useState("")
  const [indexState, setIndexState] = React.useState("全部索引")
  const [citation, setCitation] = React.useState("全部引用")
  const [page, setPage] = React.useState(1)
  const [selected, setSelected] = React.useState<Set<string>>(new Set())
  const pageSize = 5
  const filtered = deliveries.filter((row) => (`${row.title}${row.media}${row.scene}${row.question}`.toLowerCase().includes(query.toLowerCase())) && (indexState === "全部索引" || row.index === indexState) && (citation === "全部引用" || row.citation === citation))
  const pageCount = Math.max(1, Math.ceil(filtered.length / pageSize))
  const currentPage = Math.min(page, pageCount)
  const visible = filtered.slice((currentPage - 1) * pageSize, currentPage * pageSize)
  const toggle = (id: string) => setSelected((old) => { const next = new Set(old); if (next.has(id)) next.delete(id); else next.add(id); return next })
  const exportRows = (rows = deliveries) => { const cols = ["id","title","scene","media","level","date","index","citation","times","ai","question"] as const; const csv = `\ufeff${cols.join(",")}\n${rows.map((row) => cols.map((col) => csvCell(row[col])).join(",")).join("\n")}`; downloadText("点都德_2026年8月_交付内容清单.csv", csv, "text/csv;charset=utf-8"); toast.success(`已导出 ${rows.length} 条记录`) }
  return (
    <div className="page-stack"><PageIntro number={7} title="交付内容与文章链接" description="逐条查看本月内容资产、发布状态、索引证据、AI引用证据和关联监测问题。" action={<Button onClick={() => exportRows()}><Download/>导出已载入明细</Button>} />
      <section className="module-stat-grid four"><StatCard label="已交付内容" value="50篇" note="本月实际交付完成"/><StatCard label="已索引 / 可检索" value="44篇" change="索引率 88%" note="持续回查" tone="green"/><StatCard label="检测到AI引用" value="17篇" change="内容级覆盖34%" note="不同于回答级引用率" tone="orange"/><StatCard label="关联推荐表现" value="9篇" change="9 / 17 = 52.9%" note="引用后出现品牌推荐" tone="green"/></section>
      <section className="content-card"><SectionHeading eyebrow="DELIVERY LEDGER" title="交付内容证据链" description="当前载入8条代表性明细；生产数据接入后承载完整50篇台账"/><div className="module-toolbar"><div className="toolbar-search"><Search/><Input value={query} onChange={(event) => { setQuery(event.target.value); setPage(1) }} placeholder="搜索标题、媒体、场景或关联问题"/></div><Select value={indexState} onValueChange={(value) => { setIndexState(value); setPage(1) }}><SelectTrigger><SelectValue/></SelectTrigger><SelectContent><SelectItem value="全部索引">全部索引</SelectItem><SelectItem value="已索引">已索引</SelectItem><SelectItem value="检测中">检测中</SelectItem></SelectContent></Select><Select value={citation} onValueChange={(value) => { setCitation(value); setPage(1) }}><SelectTrigger><SelectValue/></SelectTrigger><SelectContent><SelectItem value="全部引用">全部引用</SelectItem><SelectItem value="检测到引用">检测到引用</SelectItem><SelectItem value="暂未检测到">暂未检测到</SelectItem></SelectContent></Select><Button variant="outline" onClick={() => { setQuery(""); setIndexState("全部索引"); setCitation("全部引用"); setPage(1) }}><X/>清空</Button></div>
        {selected.size ? <div className="bulk-bar visible"><span>已选择 {selected.size} 条</span><Button size="sm" onClick={() => exportRows(deliveries.filter((row) => selected.has(row.id)))}><Download/>导出所选</Button><Button variant="ghost" size="sm" onClick={() => setSelected(new Set())}>取消选择</Button></div> : null}
        {visible.length ? <><DataTableShell minWidth={1080}><Table><TableHeader><TableRow><TableHead><Checkbox checked={visible.every((row) => selected.has(row.id))} onCheckedChange={(checked) => setSelected((old) => { const next = new Set(old); visible.forEach((row) => checked ? next.add(row.id) : next.delete(row.id)); return next })}/></TableHead><TableHead>编号 / 标题</TableHead><TableHead>场景</TableHead><TableHead>媒体 / 层级</TableHead><TableHead>发布日期</TableHead><TableHead>索引状态</TableHead><TableHead>AI引用</TableHead><TableHead>引用次数</TableHead><TableHead>关联平台</TableHead><TableHead>操作</TableHead></TableRow></TableHeader><TableBody>{visible.map((row) => <TableRow key={row.id}><TableCell><Checkbox checked={selected.has(row.id)} onCheckedChange={() => toggle(row.id)}/></TableCell><TableCell className="delivery-title"><code>{row.id}</code><button onClick={() => setDetail({ kind: "delivery", title: row.title, subtitle: row.id, payload: row })}>{row.title}</button></TableCell><TableCell>{row.scene}</TableCell><TableCell><strong>{row.media}</strong><small>{row.level}</small></TableCell><TableCell>{row.date}</TableCell><TableCell><ToneBadge tone={row.index === "已索引" ? "green" : "orange"}>{row.index}</ToneBadge></TableCell><TableCell><ToneBadge tone={row.citation === "检测到引用" ? "blue" : "neutral"}>{row.citation}</ToneBadge></TableCell><TableCell>{row.times}</TableCell><TableCell>{row.ai}</TableCell><TableCell><Button variant="ghost" size="sm" onClick={() => setDetail({ kind: "delivery", title: row.title, subtitle: row.id, payload: row })}>详情 <ChevronRight/></Button></TableCell></TableRow>)}</TableBody></Table></DataTableShell><Pagination className="module-pagination"><PaginationContent><PaginationItem><PaginationPrevious href="#" onClick={(event) => { event.preventDefault(); setPage(Math.max(1, currentPage - 1)) }}/></PaginationItem>{Array.from({ length: pageCount }, (_, i) => i + 1).map((value) => <PaginationItem key={value}><PaginationLink href="#" isActive={currentPage === value} onClick={(event) => { event.preventDefault(); setPage(value) }}>{value}</PaginationLink></PaginationItem>)}<PaginationItem><PaginationNext href="#" onClick={(event) => { event.preventDefault(); setPage(Math.min(pageCount, currentPage + 1)) }}/></PaginationItem></PaginationContent></Pagination></> : <EmptyResults reset={() => { setQuery(""); setIndexState("全部索引"); setCitation("全部引用") }}/>}<div className="drawer-note"><Info />“AI引用覆盖率34%”按交付文章数计算；“回答级引用率25%”按可检测引用的有效回答数计算，两者不得混用。</div></section>
    </div>
  )
}

function MethodologyPage({ setDetail }: { setDetail: (detail: Detail) => void }) {
  const [group, setGroup] = React.useState("AI可见性")
  const [query, setQuery] = React.useState("")
  const [reviewOpen, setReviewOpen] = React.useState(false)
  const groups = [...new Set(metricDictionary.map((item) => item.group))]
  const rows = metricDictionary.filter((item) => item.group === group && item.name.includes(query))
  return (
    <div className="page-stack"><PageIntro number={8} title="数据公式与口径说明" description="每一个数字都能查定义、公式、分母、数据来源、更新频率与版本，确保可复核、可解释。" action={<div className="inline-actions"><ToneBadge tone="blue">口径版本 V1.0</ToneBadge><Button variant="outline" onClick={() => setReviewOpen(true)}>申请数据复核</Button></div>} />
      <section className="acceptance-system"><div><span>第一层</span><strong>交付完成度</strong><p>服务商有没有按约定完成工作</p><small>工作量 / 过程验收</small></div><ArrowRight/><div><span>第二层</span><strong>效果指标</strong><p>品牌在AI中的表现有没有改善</p><small>结果 / 效果验收</small></div><ArrowRight/><div><span>第三层</span><strong>原始数据证据</strong><p>凭什么证明效果发生变化</p><small>证据 / 可追溯验收</small></div></section>
      <section className="dashboard-grid dashboard-grid-equal"><div className="content-card score-formula-card"><SectionHeading eyebrow="MASTER SCORE 01" title="AI综合可见度" description="只衡量可见、推荐、排名、引用和竞争能力"/><div className="formula-score"><strong>{visibilityFormula.score}</strong><span>/ 100</span></div><div className="formula-block"><span>V1.0公式</span><strong>提及率×25% + 推荐率×25% + Top3率×15% + 推荐位次得分×10% + 引用率×10% + AI推荐SOV×15%</strong><code>68×25% + 52×25% + 38×15% + 82×10% + 25×10% + 31×15% = {visibilityFormula.score}</code><small className="formula-audit-note">系统自动复算；V1.0原文示例结果51.85存在0.80分算术偏差。</small></div></div><div className="content-card score-formula-card green"><SectionHeading eyebrow="MASTER SCORE 02" title="AI品牌健康度" description="单独衡量AI是否正确、健康地理解品牌"/><div className="formula-score"><strong>{healthFormula.score}</strong><span>/ 100</span></div><div className="formula-block"><span>V1.0公式</span><strong>品牌信息准确率×60% + 内容中正率×40%</strong><code>92×60% + 94×40% = 92.8</code></div></div></section>
      <section className="content-card"><SectionHeading eyebrow="METRIC DICTIONARY" title="指标口径中心" description="点击任一指标查看完整定义与证据路径" action={<div className="toolbar-search compact"><Search/><Input value={query} onChange={(event) => setQuery(event.target.value)} placeholder="搜索指标"/></div>}/><Tabs value={group} onValueChange={setGroup} className="dictionary-tabs"><TabsList>{groups.map((item) => <TabsTrigger key={item} value={item}>{item}</TabsTrigger>)}</TabsList>{groups.map((item) => <TabsContent key={item} value={item}>{rows.length ? <DataTableShell minWidth={900}><Table><TableHeader><TableRow><TableHead>指标</TableHead><TableHead>核心含义</TableHead><TableHead>计算公式 / 方法</TableHead><TableHead>数据来源</TableHead><TableHead>等级</TableHead><TableHead>更新频率</TableHead></TableRow></TableHeader><TableBody>{rows.map((row) => <TableRow key={row.name} className="clickable-row" onClick={() => setDetail({ kind: "metric", title: row.name, subtitle: row.group, payload: row })}><TableCell><strong>{row.name}</strong></TableCell><TableCell>{row.meaning}</TableCell><TableCell className="wide-cell">{row.formula}</TableCell><TableCell>{row.source}</TableCell><TableCell><ToneBadge tone="green">{row.level}</ToneBadge></TableCell><TableCell>{row.frequency}</TableCell></TableRow>)}</TableBody></Table></DataTableShell> : <EmptyResults reset={() => setQuery("")}/>}</TabsContent>)}</Tabs></section>
      <section className="dashboard-grid dashboard-grid-main"><div className="content-card"><SectionHeading eyebrow="JUDGEMENT RULES" title="AI判定标准" description="项目启动前固定，变更须生成新版本"/><div className="judgement-grid">{[["提及 Mention","出现完整品牌名、固定简称、英文名或唯一指向品牌的表达。"],["明确推荐 Recommend","AI把品牌作为推荐品牌、候选方案或可考虑对象；事实性提及不计。"],["Top3","仅对推荐 / 决策 / 比较类Prompt统计；目标品牌未出现仍计入分母。"],["信息准确 Accurate","以可核验事实点判断，不采用整条回答简单二元判断。"],["内容中正 Neutral+Positive","正面或中性回答；未提及品牌的回答不进入分母。"],["引用 Citation","仅统计支持引用展示或来源核验的平台 / 模式。"]].map(([title,note]) => <div key={title}><CheckCircle2/><strong>{title}</strong><p>{note}</p></div>)}</div></div><div className="content-card"><SectionHeading eyebrow="MEASUREMENT PROTOCOL" title="检测协议锁定项" description="公式有效的前提"/><div className="protocol-list">{[["核心Prompt池","固定编号 P001—P200"],["AI平台","合同约定平台，单独统计"],["重复检测次数","核心Prompt建议 ≥3次"],["竞品集合","项目启动前冻结"],["别名表","全称 / 简称 / 英文名"],["异常回答","失败、超时、无效单独记录"]].map(([label,value]) => <div key={label}><CheckCircle2/><span>{label}</span><strong>{value}</strong></div>)}</div><Button className="full-width-button" variant="outline" onClick={() => setDetail({ kind: "protocol", title: "完整检测协议", subtitle: "V1.0" })}>查看有效回答定义 <ArrowRight/></Button></div></section>
      <Dialog open={reviewOpen} onOpenChange={setReviewOpen}><DialogContent><DialogHeader><DialogTitle>申请数据复核</DialogTitle><DialogDescription>提交后将关联对应Prompt、平台、检测时间、完整回答和判定记录。</DialogDescription></DialogHeader><Select defaultValue="品牌提及率"><SelectTrigger className="w-full"><SelectValue/></SelectTrigger><SelectContent>{metricDictionary.map((item) => <SelectItem key={item.name} value={item.name}>{item.name}</SelectItem>)}</SelectContent></Select><Textarea placeholder="补充复核说明（可选）" className="min-h-28"/><DialogFooter><Button variant="outline" onClick={() => setReviewOpen(false)}>取消</Button><Button onClick={() => { setReviewOpen(false); toast.success("复核申请已记录：REV-202608-003") }}><Send/>提交复核</Button></DialogFooter></DialogContent></Dialog>
    </div>
  )
}

function RiskPage({ setDetail }: { setDetail: (detail: Detail) => void }) {
  const [level, setLevel] = React.useState("全部级别")
  const [type, setType] = React.useState("全部类型")
  const rows = risks.filter((item) => (level === "全部级别" || item.level === level) && (type === "全部类型" || item.type === type))
  return (
    <div className="page-stack"><PageIntro number={9} title="问题与风险" description="透明展示尚未解决的问题、影响、负责人、处理状态、复测节点与闭环证据。" action={<ToneBadge tone="green"><ShieldCheck/> 无重大阻断风险</ToneBadge>} />
      <section className="module-stat-grid five"><StatCard label="重大风险" value="0项" note="无阻断性风险" tone="green"/><StatCard label="重点关注" value="3项" note="本阶段重点处理" tone="orange"/><StatCard label="一般关注" value="2项" note="持续跟踪"/><StatCard label="本月已闭环" value="3项" note="完成复测确认" tone="green"/><StatCard label="当前待跟踪" value="5项" change="-1项" note="较上月下降"/></section>
      <section className="content-card"><SectionHeading eyebrow="RISK REGISTER" title="问题与风险台账" description="所有问题均有负责人和下一复测节点"/><div className="module-toolbar"><Select value={level} onValueChange={setLevel}><SelectTrigger><ListFilter/><SelectValue/></SelectTrigger><SelectContent><SelectItem value="全部级别">全部级别</SelectItem><SelectItem value="重点关注">重点关注</SelectItem><SelectItem value="一般关注">一般关注</SelectItem></SelectContent></Select><Select value={type} onValueChange={setType}><SelectTrigger><Filter/><SelectValue/></SelectTrigger><SelectContent><SelectItem value="全部类型">全部类型</SelectItem>{[...new Set(risks.map((item) => item.type))].map((item) => <SelectItem key={item} value={item}>{item}</SelectItem>)}</SelectContent></Select><Button variant="outline" onClick={() => { setLevel("全部级别"); setType("全部类型") }}><X/>清空</Button></div>{rows.length ? <DataTableShell minWidth={1120}><Table><TableHeader><TableRow><TableHead>编号</TableHead><TableHead>问题 / 风险</TableHead><TableHead>类型</TableHead><TableHead>当前证据</TableHead><TableHead>影响</TableHead><TableHead>级别</TableHead><TableHead>负责人</TableHead><TableHead>状态</TableHead><TableHead>下次复测</TableHead></TableRow></TableHeader><TableBody>{rows.map((row) => <TableRow key={row.id} className="clickable-row" onClick={() => setDetail({ kind: "risk", title: row.name, subtitle: row.id, payload: row })}><TableCell><code>{row.id}</code></TableCell><TableCell><strong>{row.name}</strong></TableCell><TableCell>{row.type}</TableCell><TableCell className="wide-cell">{row.evidence}</TableCell><TableCell className="wide-cell">{row.impact}</TableCell><TableCell><ToneBadge tone={row.level === "重点关注" ? "orange" : "blue"}>{row.level}</ToneBadge></TableCell><TableCell>{row.owner}</TableCell><TableCell>{row.status}</TableCell><TableCell>{row.next}</TableCell></TableRow>)}</TableBody></Table></DataTableShell> : <EmptyResults reset={() => { setLevel("全部级别"); setType("全部类型") }}/>}</section>
      <section className="dashboard-grid dashboard-grid-equal"><div className="content-card"><SectionHeading eyebrow="FOCUS" title="本期重点问题" description="需要在下一阶段继续推进"/><div className="focus-risk-list">{risks.filter((item) => item.level === "重点关注").map((item) => <button key={item.id} onClick={() => setDetail({ kind: "risk", title: item.name, subtitle: item.id, payload: item })}><span>{item.id}</span><div><strong>{item.name}</strong><p>{item.evidence}</p><small>{item.owner} · {item.next}</small></div><ChevronRight/></button>)}</div></div><div className="content-card"><SectionHeading eyebrow="CLOSED" title="本月已闭环问题" description="处理完成并经同口径复测确认"/><div className="closed-list">{[["门店营业时间信息不一致","统一更新官方信息源","08-12"],["价格区间存在历史版本","更新最新价格区间表达","08-10"],["3篇内容平台误判限制索引","申诉通过并重新提交","08-08"]].map(([issue,result,date]) => <button key={issue} onClick={() => toast.success(`${issue}：复测正常`)}><CheckCircle2/><div><strong>{issue}</strong><p>{result}</p></div><span>{date}</span></button>)}</div></div></section>
    </div>
  )
}

function ActionPage({ setDetail }: { setDetail: (detail: Detail) => void }) {
  const [priority, setPriority] = React.useState("全部")
  const [status, setStatus] = React.useState("全部状态")
  const rows = actions.filter((item) => (priority === "全部" || item.priority === priority) && (status === "全部状态" || item.status === status))
  const exportActions = () => { const cols = ["priority","task","source","deliverable","metric","owner","deadline","status","progress"] as const; const csv = `\ufeff${cols.join(",")}\n${actions.map((row) => cols.map((col) => csvCell(row[col])).join(",")).join("\n")}`; downloadText("点都德_2026年9月_行动计划.csv", csv, "text/csv;charset=utf-8"); toast.success("行动计划已导出") }
  const weeks = [["W1","09.01—09.07","问题校准与规划",["完成品牌事实更新","明确DeepSeek问题池","确定商务宴请内容框架"]],["W2","09.08—09.14","内容建设与信源布局",["商务宴请3篇上线","家庭聚餐内容发布","重点信源同步完善"]],["W3","09.15—09.21","平台覆盖与渠道补齐",["DeepSeek问题池扩充","元宝 / 智谱内容补齐","持续索引与引用回查"]],["W4","09.22—09.30","复测验证与优化迭代",["8平台全面复测","问题闭环评估","形成9月效果报告"]]] as const
  return (
    <div className="page-stack"><PageIntro number={10} title="下阶段行动计划" description="基于2026年8月监测结果制定；明确问题来源、确定性交付、阶段观察指标、负责人和截止时间。" action={<Button onClick={exportActions}><Download/>导出行动计划</Button>} />
      <section className="goal-grid"><div><span>目标 01</span><Target/><strong>平台补短板</strong><p>重点提升DeepSeek推荐能力和Top3表现</p></div><div><span>目标 02</span><TrendingUp/><strong>高价值场景突破</strong><p>聚焦商务宴请与家庭聚餐两项S级机会</p></div><div><span>目标 03</span><ShieldCheck/><strong>品牌信息与交付稳定</strong><p>事实校准、有效索引与证据链持续完整</p></div></section>
      <section className="content-card"><SectionHeading eyebrow="ACTION REGISTER" title="行动任务清单" description="P0最高优先 · P1重点提升 · P2持续优化"/><div className="module-toolbar"><div className="filter-buttons">{["全部","P0","P1","P2"].map((value) => <Button key={value} variant={priority === value ? "default" : "outline"} size="sm" onClick={() => setPriority(value)}>{value}</Button>)}</div><Select value={status} onValueChange={setStatus}><SelectTrigger><SelectValue/></SelectTrigger><SelectContent><SelectItem value="全部状态">全部状态</SelectItem>{[...new Set(actions.map((item) => item.status))].map((item) => <SelectItem key={item} value={item}>{item}</SelectItem>)}</SelectContent></Select></div>{rows.length ? <DataTableShell minWidth={1200}><Table><TableHeader><TableRow><TableHead>优先级</TableHead><TableHead>重点任务</TableHead><TableHead>问题来源</TableHead><TableHead>确定性交付（乙方可控）</TableHead><TableHead>阶段观察指标</TableHead><TableHead>负责人</TableHead><TableHead>截止时间</TableHead><TableHead>进度</TableHead><TableHead>状态</TableHead></TableRow></TableHeader><TableBody>{rows.map((row) => <TableRow key={row.task} className="clickable-row" onClick={() => setDetail({ kind: "action", title: row.task, subtitle: row.priority, payload: row })}><TableCell><ToneBadge tone={row.priority === "P0" ? "red" : row.priority === "P1" ? "orange" : "blue"}>{row.priority}</ToneBadge></TableCell><TableCell><strong>{row.task}</strong></TableCell><TableCell>{row.source}</TableCell><TableCell className="wide-cell">{row.deliverable}</TableCell><TableCell className="wide-cell">{row.metric}</TableCell><TableCell>{row.owner}</TableCell><TableCell>{row.deadline}</TableCell><TableCell><div className="task-progress"><span>{row.progress}%</span><Progress value={row.progress}/></div></TableCell><TableCell>{row.status}</TableCell></TableRow>)}</TableBody></Table></DataTableShell> : <EmptyResults reset={() => { setPriority("全部"); setStatus("全部状态") }}/>}<div className="commitment-boundary"><ShieldCheck/><div><strong>交付与效果边界</strong><p>内容、信源、事实校准和复测任务属于乙方确定性交付；平台推荐率、Top3等受AI算法与随机性影响，作为阶段观察指标，不写成单一刚性承诺。</p></div></div></section>
      <section className="content-card"><SectionHeading eyebrow="30-DAY MILESTONE" title="未来30天执行里程碑" description="按周推进，月底完成同口径复测"/><div className="week-grid">{weeks.map(([week,date,title,items], index) => <div key={week} className={index === 0 ? "active" : ""}><div><span>{week}</span><small>{date}</small></div><strong>{title}</strong><ul>{items.map((item) => <li key={item}><Check/>{item}</li>)}</ul></div>)}</div></section>
    </div>
  )
}

export function DashboardModule({ page, goTo }: { page: number; goTo: (page: number) => void }) {
  const [detail, setDetail] = React.useState<Detail>(null)
  let content: React.ReactNode
  switch (page) {
    case 2: content = <ComparisonPage setDetail={setDetail}/>; break
    case 3: content = <AIAnswersPage setDetail={setDetail}/>; break
    case 4: content = <CompetitorPage goTo={goTo}/>; break
    case 5: content = <DemandPage setDetail={setDetail} goTo={goTo}/>; break
    case 6: content = <ExecutionPage setDetail={setDetail} goTo={goTo}/>; break
    case 7: content = <DeliveryPage setDetail={setDetail}/>; break
    case 8: content = <MethodologyPage setDetail={setDetail}/>; break
    case 9: content = <RiskPage setDetail={setDetail}/>; break
    case 10: content = <ActionPage setDetail={setDetail}/>; break
    default: content = null
  }
  return <>{content}<DetailDrawer detail={detail} onOpenChange={(open) => !open && setDetail(null)} goTo={goTo}/></>
}
