// 數據分析頁：營運總覽（方案一）/ 品類與供需 + 分眾名單（方案二）。
// 全部讀 /api/admin/analytics/*（純聚合現有資料表）。共用元件（StatTile/BarChart/Sparkline/Table…）來自 ui.jsx。
// ⚠ 勿在此頂層重新宣告 useState/useEffect/useMemo（ui.jsx 已全域宣告，重宣告會整包壞掉）——直接 bare 使用。
// ⚠ 整檔包在 IIFE 內：babel 把頂層 const 轉成全域 var，跨頁同名會被後載入的覆蓋（如 OverviewTab 與
//   orders.jsx 撞名）。包起來讓內部元件全為函式作用域、不外洩，只對外曝露 window.AnalyticsPage。
(() => {

const ANALYTICS_RANGES = [
  { value: "7d",  label: "近 7 天",  days: 7 },
  { value: "30d", label: "近 30 天", days: 30 },
  { value: "90d", label: "近 90 天", days: 90 },
  { value: "all", label: "全部",     days: null },
];
function analyticsRangeParams(value) {
  const ymd = (d) => `${d.getFullYear()}-${String(d.getMonth() + 1).padStart(2, "0")}-${String(d.getDate()).padStart(2, "0")}`;
  const to = new Date();
  if (value === "all") return { from: "2020-01-01", to: ymd(to) };
  const r = ANALYTICS_RANGES.find((x) => x.value === value) || ANALYTICS_RANGES[1];
  const from = new Date(); from.setDate(from.getDate() - (r.days - 1));
  return { from: ymd(from), to: ymd(to) };
}
const pct = (v) => `${(Number(v || 0) * 100).toFixed(1)}%`;

const AnalyticsPage = () => {
  const [tab, setTab] = useState("overview");
  const [range, setRange] = useState("30d");
  const [overview, setOverview] = useState(null);
  const [categories, setCategories] = useState(null);
  const [behavior, setBehavior] = useState(null);
  const [segments, setSegments] = useState(null);
  const [age, setAge] = useState(null);
  const [loading, setLoading] = useState(true);

  const params = useMemo(() => analyticsRangeParams(range), [range]);

  useEffect(() => {
    setLoading(true);
    const qs = `?from=${params.from}&to=${params.to}`;
    Promise.all([
      fetch(`/api/admin/analytics/overview${qs}`).then((r) => (r.ok ? r.json() : null)),
      fetch(`/api/admin/analytics/categories${qs}`).then((r) => (r.ok ? r.json() : null)),
      fetch(`/api/admin/analytics/behavior${qs}`).then((r) => (r.ok ? r.json() : null)),
      fetch(`/api/admin/analytics/age${qs}`).then((r) => (r.ok ? r.json() : null)),
    ])
      .then(([o, c, b, a]) => { setOverview(o); setCategories(c); setBehavior(b); setAge(a); })
      .catch(() => {})
      .finally(() => setLoading(false));
  }, [params.from, params.to]);

  useEffect(() => {
    fetch(`/api/admin/analytics/segments`).then((r) => (r.ok ? r.json() : null)).then(setSegments).catch(() => {});
  }, []);

  return (
    <div className="fade-in">
      <PageHeader
        title="數據分析"
        subtitle="經營總覽、品類供需、分眾名單 — 皆由平台實際資料聚合"
        actions={<Select value={range} onChange={setRange} icon="calendar" options={ANALYTICS_RANGES}/>}
      />

      <div style={{ marginBottom: 18 }}>
        <Tabs active={tab} onChange={setTab} tabs={[
          { value: "overview", label: "營運總覽" },
          { value: "categories", label: "品類與供需" },
          { value: "age", label: "年齡層消費" },
          { value: "behavior", label: "行為" },
          { value: "segments", label: "分眾名單" },
        ]}/>
      </div>

      {tab === "overview" && <OverviewTab data={overview} loading={loading}/>}
      {tab === "categories" && <CategoriesTab data={categories} loading={loading}/>}
      {tab === "age" && <AgeTab data={age} loading={loading}/>}
      {tab === "behavior" && <BehaviorTab data={behavior} loading={loading}/>}
      {tab === "segments" && <SegmentsTab data={segments}/>}
    </div>
  );
};

// ============== 營運總覽 ==============
const OverviewTab = ({ data, loading }) => {
  if (loading) return <Loading/>;
  if (!data) return <EmptyState/>;
  const k = data.kpi || {};
  const series = data.series || [];
  const funnel = data.funnel || [];
  const t = data.timing || {};
  const maxFunnel = Math.max(...funnel.map((f) => f.count), 1);

  return (
    <>
      <div style={{ display: "grid", gridTemplateColumns: "repeat(auto-fit, minmax(160px, 1fr))", gap: 12, marginBottom: 18 }}>
        <StatTile label="GMV（淨收）" value={`NT$ ${fmtNum(k.gmv || 0)}`} sub={`${fmtNum(k.completedCount || 0)} 筆完成`} tone="accent" icon="coin"/>
        <StatTile label="訂單數" value={fmtNum(k.orderCount || 0)} sub="已付款訂單" tone="info" icon="order"/>
        <StatTile label="客單價" value={`NT$ ${fmtNum(k.aov || 0)}`} sub="每完成訂單" tone="accent" icon="chart"/>
        <StatTile label="完成率" value={pct(k.completionRate)} sub="完成 / 已付款" tone="success" icon="check"/>
        <StatTile label="糾紛率" value={pct(k.disputeRate)} sub="曾進調解 / 訂單" tone="warn" icon="alert"/>
        <StatTile label="退款總額" value={`NT$ ${fmtNum(k.refundTotal || 0)}`} sub="期間退款" tone="danger" icon="minus"/>
      </div>

      <div style={{ display: "grid", gridTemplateColumns: "1fr 1fr", gap: 12, marginBottom: 12 }}>
        <Card padding={24}>
          <ChartHead title="每日 GMV" sub={`${data.range?.from} ~ ${data.range?.to}`}/>
          <BarChart data={series} value={(d) => d.gmv} label={(d) => d.date.slice(5)} color="var(--accent)" format={(v) => `NT$ ${fmtNum(v)}`}/>
        </Card>
        <Card padding={24}>
          <ChartHead title="每日訂單數" sub="已付款訂單"/>
          <BarChart data={series} value={(d) => d.orders} label={(d) => d.date.slice(5)} color="var(--info)" format={(v) => `${fmtNum(v)} 筆`}/>
        </Card>
      </div>

      <div style={{ display: "grid", gridTemplateColumns: "1.4fr 1fr", gap: 12 }}>
        <Card padding={24}>
          <ChartHead title="訂單狀態漏斗" sub="下單 → 付款 → 交付 → 完成"/>
          <div style={{ display: "flex", flexDirection: "column", gap: 10, marginTop: 6 }}>
            {funnel.map((f, i) => {
              const prev = i > 0 ? funnel[i - 1].count : null;
              const conv = prev ? (f.count / prev) : null;
              return (
                <div key={f.key}>
                  <div style={{ display: "flex", justifyContent: "space-between", fontSize: 12.5, marginBottom: 4 }}>
                    <span>{f.label}</span>
                    <span className="mono" style={{ color: "var(--ink-3)" }}>
                      {fmtNum(f.count)}{conv != null && <span style={{ color: "var(--ink-4)", marginLeft: 8 }}>轉換 {pct(conv)}</span>}
                    </span>
                  </div>
                  <div style={{ height: 10, borderRadius: 5, background: "var(--surface-2)", overflow: "hidden" }}>
                    <div style={{ height: "100%", width: `${Math.round((f.count / maxFunnel) * 100)}%`, background: "var(--accent)", borderRadius: 5 }}/>
                  </div>
                </div>
              );
            })}
          </div>
        </Card>
        <Card padding={24}>
          <ChartHead title="平均處理時長" sub="訂單推進速度"/>
          <div style={{ display: "flex", flexDirection: "column", gap: 16, marginTop: 12 }}>
            <TimingRow label="下單 → 付款" days={t.createdToPaid}/>
            <TimingRow label="付款 → 完成" days={t.paidToCompleted}/>
          </div>
        </Card>
      </div>
    </>
  );
};

const TimingRow = ({ label, days }) => (
  <div style={{ display: "flex", alignItems: "baseline", justifyContent: "space-between" }}>
    <span style={{ fontSize: 13, color: "var(--ink-2)" }}>{label}</span>
    <span className="serif" style={{ fontSize: 22 }}>{days == null ? "—" : <>{days} <span style={{ fontSize: 13, color: "var(--ink-3)" }}>天</span></>}</span>
  </div>
);

// ============== 品類與供需 ==============
const CategoriesTab = ({ data, loading }) => {
  if (loading) return <Loading/>;
  if (!data) return <EmptyState/>;
  return (
    <>
      <div style={{ display: "grid", gridTemplateColumns: "1fr 1fr", gap: 12, marginBottom: 12 }}>
        <Card padding={24}>
          <ChartHead title="品類 GMV 排行" sub="繪圖 / 文集 / 商品訂單"/>
          <BarChart data={data.categoryRanking || []} value={(d) => d.gmv} label={(d) => d.category} color="var(--accent)" height={140} format={(v) => `NT$ ${fmtNum(v)}`} emptyText="期間內無成交"/>
          <RankTable rows={data.categoryRanking || []} nameKey="category" cols={[["訂單數", "orders", (v) => fmtNum(v)], ["GMV", "gmv", (v) => `NT$ ${fmtNum(v)}`]]}/>
        </Card>
        <Card padding={24}>
          <ChartHead title="價格帶分布" sub="完成訂單淨收"/>
          <BarChart data={data.priceBands || []} value={(d) => d.orders} label={(d) => d.label} color="var(--info)" height={140} format={(v) => `${fmtNum(v)} 筆`} emptyText="期間內無成交"/>
          <RankTable rows={data.priceBands || []} nameKey="label" cols={[["訂單數", "orders", (v) => fmtNum(v)], ["金額", "gmv", (v) => `NT$ ${fmtNum(v)}`]]}/>
        </Card>
      </div>

      <div style={{ display: "grid", gridTemplateColumns: "1fr 1fr", gap: 12, marginBottom: 12 }}>
        <TagCard title="熱門商品標籤（供給）" sub="以銷量加權" rows={data.supplyTags || []}/>
        <TagCard title="熱門徵稿標籤（需求）" sub="委託人想要什麼" rows={data.demandTags || []}/>
      </div>

      <div style={{ display: "grid", gridTemplateColumns: "1fr 1fr", gap: 12 }}>
        <Card padding={24}>
          <ChartHead title="徵稿需求" sub="委託人主動貼的求稿"/>
          <Table
            columns={[
              { title: "類型", render: (r) => r.type },
              { title: "徵稿數", align: "right", render: (r) => <span className="mono">{fmtNum(r.count)}</span> },
              { title: "平均預算", align: "right", render: (r) => <span className="mono">NT$ {fmtNum(r.avgBudget)}</span> },
            ]}
            rows={data.solicitDemand || []}
          />
        </Card>
        <Card padding={24}>
          <ChartHead title="供需缺口" sub="期間徵稿(需求) vs 上架商品(供給)"/>
          <Table
            columns={[
              { title: "類型", render: (r) => r.type },
              { title: "需求(徵稿)", align: "right", render: (r) => <span className="mono" style={{ color: "var(--info)" }}>{fmtNum(r.demand)}</span> },
              { title: "供給(商品)", align: "right", render: (r) => <span className="mono" style={{ color: "var(--success)" }}>{fmtNum(r.supply)}</span> },
            ]}
            rows={data.supplyDemand || []}
          />
          <div style={{ marginTop: 12, padding: "8px 12px", background: "var(--surface-2)", borderRadius: 8, fontSize: 12.5 }}>
            徵稿媒合率 <b className="mono">{pct(data.solicitMatch?.matchRate)}</b>
            <span style={{ color: "var(--ink-4)", marginLeft: 8 }}>（{fmtNum(data.solicitMatch?.matched || 0)} / {fmtNum(data.solicitMatch?.total || 0)} 件申請媒合成功）</span>
          </div>
        </Card>
      </div>
    </>
  );
};

const TagCard = ({ title, sub, rows }) => {
  const max = Math.max(...rows.map((r) => r.value), 1);
  return (
    <Card padding={24}>
      <ChartHead title={title} sub={sub}/>
      {rows.length === 0 ? (
        <div style={{ padding: 20, textAlign: "center", color: "var(--ink-4)", fontSize: 13 }}>暫無資料</div>
      ) : (
        <div style={{ display: "flex", flexDirection: "column", gap: 7, marginTop: 4 }}>
          {rows.map((r) => (
            <div key={r.tag} style={{ display: "flex", alignItems: "center", gap: 10 }}>
              <span style={{ fontSize: 12.5, width: 84, flexShrink: 0, whiteSpace: "nowrap", overflow: "hidden", textOverflow: "ellipsis" }}>{r.tag}</span>
              <div style={{ flex: 1, height: 8, borderRadius: 4, background: "var(--surface-2)", overflow: "hidden" }}>
                <div style={{ height: "100%", width: `${Math.round((r.value / max) * 100)}%`, background: "var(--accent)", borderRadius: 4 }}/>
              </div>
              <span className="mono" style={{ fontSize: 11.5, color: "var(--ink-3)", width: 34, textAlign: "right" }}>{fmtNum(r.value)}</span>
            </div>
          ))}
        </div>
      )}
    </Card>
  );
};

const RankTable = ({ rows, nameKey, cols }) => (
  <div style={{ marginTop: 12 }}>
    {rows.map((r, i) => (
      <div key={i} style={{ display: "flex", alignItems: "center", justifyContent: "space-between", padding: "7px 0", borderTop: i ? "1px solid var(--border)" : "none", fontSize: 12.5 }}>
        <span style={{ fontWeight: 500 }}>{r[nameKey]}</span>
        <span style={{ display: "flex", gap: 16 }}>
          {cols.map(([label, key, fmt], j) => (
            <span key={j} className="mono" style={{ color: "var(--ink-3)" }}>{fmt(r[key])}</span>
          ))}
        </span>
      </div>
    ))}
  </div>
);

// ============== 年齡層消費 ==============
// 依委託人填寫的生日換算年齡分層，看各年齡層花多少、愛買什麼。未填生日者歸「未知」。
// 年齡層固定配色（圓餅圖切片 / 圖例共用）；「未知」永遠中性灰。
const BAND_COLORS = {
  "未滿18": "#6E9BC5",
  "18-24":  "#E85D3A",
  "25-34":  "#D9A441",
  "35-44":  "#5C8A6B",
  "45+":    "#A6597C",
  "未知":   "#C7C0B4",
};
const bandColor = (band) => BAND_COLORS[band] || "#C7C0B4";

const AgeTab = ({ data, loading }) => {
  if (loading) return <Loading/>;
  if (!data) return <EmptyState/>;
  const bands = data.ageBands || [];
  const cats = data.categories || [];
  const matrix = data.matrix || [];

  const buyerPie = bands.map((b) => ({ label: b.band, value: b.buyers, color: bandColor(b.band) }));
  const gmvPie = bands.map((b) => ({ label: b.band, value: b.gmv, color: bandColor(b.band) }));
  const totalBuyers = bands.reduce((s, b) => s + (b.buyers || 0), 0);
  const totalGmv = bands.reduce((s, b) => s + (b.gmv || 0), 0);

  const topCatOf = (band) => {
    const m = matrix.find((x) => x.band === band);
    return m && m.topCategory
      ? <span style={{ color: "var(--ink-2)" }}>{m.topCategory.category}</span>
      : <span style={{ color: "var(--ink-4)" }}>—</span>;
  };

  return (
    <>
      <div style={{ display: "grid", gridTemplateColumns: "repeat(auto-fit, minmax(160px, 1fr))", gap: 12, marginBottom: 18 }}>
        <StatTile label="消費最高年齡層" value={data.topSpendBand ? data.topSpendBand.band : "—"} sub={data.topSpendBand ? `NT$ ${fmtNum(data.topSpendBand.gmv)}` : "期間內無成交"} tone="accent" icon="coin"/>
        <StatTile label="客單價最高年齡層" value={data.topAvgBand ? data.topAvgBand.band : "—"} sub={data.topAvgBand ? `NT$ ${fmtNum(data.topAvgBand.avgPerBuyer)} / 人` : "—"} tone="info" icon="chart"/>
        <StatTile label="已填生日買家" value={fmtNum(data.buyersKnown || 0)} sub={`未知生日 ${fmtNum(data.buyersUnknown || 0)} 人`} tone="success" icon="check"/>
      </div>

      <div style={{ display: "grid", gridTemplateColumns: "1fr 1fr", gap: 12, marginBottom: 12 }}>
        <Card padding={24}>
          <ChartHead title="年齡層買家分佈" sub="各年齡層買家人數佔比"/>
          <PieChart data={buyerPie} centerLabel={fmtNum(totalBuyers)} centerSub="總買家" format={(v) => `${fmtNum(v)} 人`} emptyText="期間內無成交"/>
        </Card>
        <Card padding={24}>
          <ChartHead title="年齡層消費分佈" sub="各年齡層消費額佔比"/>
          <PieChart data={gmvPie} centerLabel={`NT$ ${fmtNum(totalGmv)}`} centerSub="總消費" format={(v) => `NT$ ${fmtNum(v)}`} emptyText="期間內無成交"/>
        </Card>
      </div>

      <div style={{ display: "grid", gridTemplateColumns: "1fr 1fr", gap: 12, marginBottom: 12 }}>
        <Card padding={24}>
          <ChartHead title="各年齡層消費額" sub={`${data.range?.from} ~ ${data.range?.to}`}/>
          <BarChart data={bands} value={(d) => d.gmv} label={(d) => d.band} color="var(--accent)" height={140} format={(v) => `NT$ ${fmtNum(v)}`} emptyText="期間內無成交"/>
        </Card>
        <Card padding={24}>
          <ChartHead title="各年齡層客單價" sub="消費額 / 買家數"/>
          <BarChart data={bands} value={(d) => d.avgPerBuyer} label={(d) => d.band} color="var(--info)" height={140} format={(v) => `NT$ ${fmtNum(v)}`} emptyText="期間內無成交"/>
        </Card>
      </div>

      <Card padding={24} style={{ marginBottom: 12 }}>
        <ChartHead title="年齡層總覽" sub="買家數 / 訂單 / 消費額 / 客單價 / 最愛品類"/>
        <Table
          columns={[
            { title: "年齡層", render: (r) => <b>{r.band}</b> },
            { title: "買家數", align: "right", render: (r) => <span className="mono">{fmtNum(r.buyers)}</span> },
            { title: "訂單數", align: "right", render: (r) => <span className="mono">{fmtNum(r.orders)}</span> },
            { title: "消費額", align: "right", render: (r) => <span className="mono">NT$ {fmtNum(r.gmv)}</span> },
            { title: "客單價", align: "right", render: (r) => <span className="mono">NT$ {fmtNum(r.avgPerBuyer)}</span> },
            { title: "最愛品類", align: "right", render: (r) => topCatOf(r.band) },
          ]}
          rows={bands}
          empty="期間內無成交"
        />
      </Card>

      <Card padding={24}>
        <ChartHead title="年齡層 × 品類（消費額）" sub="哪個年齡層愛買什麼"/>
        {bands.length === 0 ? (
          <div style={{ padding: 20, textAlign: "center", color: "var(--ink-4)", fontSize: 13 }}>期間內無成交</div>
        ) : (
          <Table
            columns={[
              { title: "年齡層", render: (r) => <b>{r.band}</b> },
              ...cats.map((cat) => ({
                title: cat,
                align: "right",
                render: (r) => {
                  const cell = (r.byCategory || []).find((x) => x.category === cat);
                  const v = cell ? cell.gmv : 0;
                  return <span className="mono" style={{ color: v ? "var(--ink-2)" : "var(--ink-4)" }}>{v ? `NT$ ${fmtNum(v)}` : "—"}</span>;
                },
              })),
            ]}
            rows={matrix}
          />
        )}
      </Card>
    </>
  );
};

// ============== 分眾名單 ==============
const SegmentsTab = ({ data }) => {
  const toast = useToast();
  if (!data) return <Loading/>;
  const segments = data.segments || [];

  const exportCsv = (seg) => {
    if (!seg.members?.length) { toast({ title: "此群無成員", icon: "alert" }); return; }
    const headers = ["名稱", "UID", seg.members[0]?.metricLabel || "指標"];
    const rows = seg.members.map((m) => [
      m.name,
      m.uid != null ? `="${String(m.uid).padStart(8, "0")}"` : "",
      m.metric,
    ]);
    const stamp = new Date().toLocaleDateString("en-CA", { timeZone: "Asia/Taipei" });
    csvDownload(`segment_${seg.key}_${stamp}.csv`, headers, rows);
    toast({ title: "CSV 已匯出", message: `${seg.label} · ${seg.members.length} 位`, icon: "download" });
  };

  return (
    <div style={{ display: "grid", gridTemplateColumns: "repeat(auto-fit, minmax(320px, 1fr))", gap: 12 }}>
      {segments.map((seg) => (
        <Card key={seg.key} padding={20}>
          <div style={{ display: "flex", alignItems: "flex-start", justifyContent: "space-between", marginBottom: 4 }}>
            <div>
              <div style={{ fontSize: 14, fontWeight: 600 }}>{seg.label}</div>
              <div style={{ fontSize: 11.5, color: "var(--ink-4)", marginTop: 2 }}>{seg.desc}</div>
            </div>
            <div className="serif" style={{ fontSize: 26, lineHeight: 1 }}>{fmtNum(seg.total ?? seg.count)}</div>
          </div>
          <div style={{ marginTop: 10, borderTop: "1px solid var(--border)", paddingTop: 8 }}>
            {(seg.members || []).slice(0, 5).map((m) => (
              <div key={m.id} style={{ display: "flex", justifyContent: "space-between", fontSize: 12.5, padding: "4px 0" }}>
                <span style={{ whiteSpace: "nowrap", overflow: "hidden", textOverflow: "ellipsis", maxWidth: 180 }}>
                  {m.name || "—"}{m.uid != null && <span className="mono" style={{ color: "var(--ink-4)", marginLeft: 6 }}>#{String(m.uid).padStart(8, "0")}</span>}
                </span>
                <span className="mono" style={{ color: "var(--ink-3)" }}>{m.metric >= 0 ? fmtNum(m.metric) : "—"}</span>
              </div>
            ))}
            {(seg.members || []).length === 0 && <div style={{ fontSize: 12.5, color: "var(--ink-4)", padding: "6px 0" }}>目前無符合成員</div>}
          </div>
          <Button variant="secondary" size="sm" icon="download" onClick={() => exportCsv(seg)} style={{ marginTop: 12, width: "100%" }}>
            匯出名單 CSV（{fmtNum(seg.members?.length || 0)}）
          </Button>
        </Card>
      ))}
    </div>
  );
};

// ============== 行為（前臺埋點）==============
const BehaviorTab = ({ data, loading }) => {
  if (loading) return <Loading/>;
  if (!data) return <EmptyState/>;
  const s = data.summary || {};
  const noData = (s.totalEvents || 0) === 0;
  return (
    <>
      {noData && (
        <div style={{ padding: "10px 16px", background: "var(--info-soft)", borderRadius: 10, marginBottom: 14, fontSize: 12.5, color: "var(--ink-2)", display: "flex", alignItems: "center", gap: 8 }}>
          <Icon name="info" size={14} style={{ color: "var(--info)", flexShrink: 0 }}/>
          行為埋點剛上線，前臺開始有人搜尋/瀏覽後，資料會逐步累積於此。
        </div>
      )}
      <div style={{ display: "grid", gridTemplateColumns: "repeat(auto-fit, minmax(160px, 1fr))", gap: 12, marginBottom: 18 }}>
        <StatTile label="搜尋次數" value={fmtNum(s.searchTotal || 0)} sub={`${fmtNum(s.searchSessions || 0)} 個工作階段`} tone="info" icon="search"/>
        <StatTile label="不重複關鍵字" value={fmtNum(s.uniqueKeywords || 0)} tone="accent" icon="chart"/>
        <StatTile label="零結果率" value={pct(s.zeroResultRate)} sub="搜不到東西的比例" tone="warn" icon="alert"/>
        <StatTile label="總事件數" value={fmtNum(s.totalEvents || 0)} sub="期間行為事件" tone="accent" icon="chart"/>
      </div>

      <Card padding={24} style={{ marginBottom: 12 }}>
        <ChartHead title="每日搜尋量" sub={`${data.range?.from} ~ ${data.range?.to}`}/>
        <BarChart data={data.searchTrend || []} value={(d) => d.count} label={(d) => d.date.slice(5)} color="var(--info)" format={(v) => `${fmtNum(v)} 次`}/>
      </Card>

      <div style={{ display: "grid", gridTemplateColumns: "1fr 1fr", gap: 12, marginBottom: 12 }}>
        <Card padding={24}>
          <ChartHead title="熱門搜尋詞" sub="用戶都在找什麼"/>
          <Table
            columns={[
              { title: "關鍵字", render: (r) => <span style={{ fontWeight: 500 }}>{r.query}</span> },
              { title: "搜尋次數", align: "right", render: (r) => <span className="mono">{fmtNum(r.searches)}</span> },
              { title: "最近結果", align: "right", render: (r) => <span className="mono" style={{ color: r.lastResult === 0 ? "var(--danger)" : "var(--ink-3)" }}>{r.lastResult == null ? "—" : fmtNum(r.lastResult)}</span> },
            ]}
            rows={data.topKeywords || []}
          />
        </Card>
        <Card padding={24}>
          <ChartHead title="零結果搜尋 · 未滿足需求" sub="搜了卻沒東西 → 該補的供給"/>
          {(data.zeroResult || []).length === 0 ? (
            <div style={{ padding: 20, textAlign: "center", color: "var(--ink-4)", fontSize: 13 }}>目前沒有零結果搜尋</div>
          ) : (
            <Table
              columns={[
                { title: "關鍵字", render: (r) => <span style={{ fontWeight: 500, color: "var(--danger)" }}>{r.query}</span> },
                { title: "零結果次數", align: "right", render: (r) => <span className="mono" style={{ color: "var(--danger)" }}>{fmtNum(r.zero)}</span> },
                { title: "總搜尋", align: "right", render: (r) => <span className="mono" style={{ color: "var(--ink-4)" }}>{fmtNum(r.searches)}</span> },
              ]}
              rows={data.zeroResult || []}
            />
          )}
        </Card>
      </div>

      <div style={{ display: "grid", gridTemplateColumns: "1fr 1fr", gap: 12 }}>
        <Card padding={24}>
          <ChartHead title="分頁點擊" sub="繪圖 / 文集 / 徵稿"/>
          <Table
            columns={[
              { title: "分頁", render: (r) => r.tab },
              { title: "切換次數", align: "right", render: (r) => <span className="mono">{fmtNum(r.count)}</span> },
            ]}
            rows={data.tabs || []}
          />
        </Card>
        <Card padding={24}>
          <ChartHead title="熱門標籤篩選" sub="用戶偏好的品類標籤"/>
          <Table
            columns={[
              { title: "標籤", render: (r) => r.value },
              { title: "使用次數", align: "right", render: (r) => <span className="mono">{fmtNum(r.count)}</span> },
            ]}
            rows={data.filters || []}
          />
        </Card>
      </div>
    </>
  );
};

// ============== 共用小件 ==============
const ChartHead = ({ title, sub }) => (
  <div style={{ marginBottom: 14 }}>
    <div style={{ fontSize: 13.5, fontWeight: 600 }}>{title}</div>
    {sub && <div style={{ fontSize: 12, color: "var(--ink-3)", marginTop: 2 }}>{sub}</div>}
  </div>
);
const Loading = () => <div style={{ padding: 48, textAlign: "center", color: "var(--ink-3)" }}>載入中…</div>;
const EmptyState = () => <Card padding={48} style={{ textAlign: "center", color: "var(--ink-4)" }}><Icon name="chart" size={26} style={{ marginBottom: 8 }}/><div>暫無資料</div></Card>;

window.AnalyticsPage = AnalyticsPage;

})();
