"use client";

import { useCallback, useEffect, useMemo, useState } from "react";
import { fetchAPI } from "@/lib/api";
import type { LeadingStock, ResearchReport, SectorData, ThemeChainItem } from "@/lib/api";
import { formatNumber } from "@/lib/utils";
import { ErrorBoundary } from "@/components/error-boundary";
import { useWebSocket } from "@/hooks/use-websocket";
import Link from "next/link";

function getThemeAliasLine(sector: SectorData) {
  const aliases = (sector.theme_aliases ?? []).filter((alias) => alias && alias !== sector.sector_name).slice(0, 4);
  if (!aliases.length) return "主题归类待补充";
  return `包含：${aliases.join(" / ")}`;
}

function getStageInfo(stage: string) {
  switch (stage) {
    case "early":
      return { label: "启动期", color: "text-emerald-400", bg: "bg-emerald-500/10 border-emerald-500/15" };
    case "mid":
      return { label: "发展期", color: "text-amber-400", bg: "bg-amber-500/10 border-amber-500/15" };
    case "late":
      return { label: "后期", color: "text-orange-400", bg: "bg-orange-500/10 border-orange-500/15" };
    case "end":
      return { label: "尾声", color: "text-red-400", bg: "bg-red-500/10 border-red-500/15" };
    default:
      return { label: "未分层", color: "text-text-muted", bg: "bg-surface-2 border-border-subtle" };
  }
}

function getActionPlan(sector: SectorData) {
  const stage = sector.stage ?? "";
  const pct = sector.realtime_pct_change ?? sector.pct_change;
  const mainForce = sector.main_force_ratio ?? 0;

  if (pct <= 0) {
    return {
      label: "抗跌观察",
      description: "等待止跌转强。",
      risk: "继续走弱或前排补跌。",
    };
  }

  if (stage === "early") {
    return {
      label: "优先盯",
      description: "龙头和分歧回流。",
      risk: "无扩散、无回流、无承接。",
    };
  }

  if (stage === "mid" && pct > 0 && mainForce > 20) {
    return {
      label: "跟回流",
      description: "等待确认。",
      risk: "内部掉队。",
    };
  }

  return {
    label: "只观察",
    description: "保留跟踪。",
    risk: "退潮加速。",
  };
}

function getLeaders(sector: SectorData): LeadingStock[] {
  return sector.is_realtime
    ? (sector.leading_stocks_realtime?.length ? sector.leading_stocks_realtime : sector.leading_stocks) ?? []
    : sector.leading_stocks ?? [];
}

function getCatalystLabel(sector: SectorData) {
  const score = sector.catalyst_score ?? 0;
  if (score >= 70) return { label: `强催化 ${score.toFixed(0)}`, className: "border-red-500/15 bg-red-500/10 text-red-300" };
  if (score >= 45) return { label: `有催化 ${score.toFixed(0)}`, className: "border-amber-500/15 bg-amber-500/10 text-amber-300" };
  if ((sector.catalyst_count ?? 0) > 0) return { label: `催化 ${score.toFixed(0)}`, className: "border-border-subtle bg-surface-2 text-text-secondary" };
  return null;
}

function getHeadline(sectors: SectorData[]) {
  const primary = sectors[0];
  const secondary = sectors[1];
  const watch = sectors.find((sector) => ["late", "end"].includes(sector.stage ?? ""));

  if (!primary) {
    return {
      title: "暂无主线数据",
      detail: "等待新的主线结论后再判断。",
      canDo: ["等待主线结论更新。"],
      avoid: ["不做情绪追涨。"],
    };
  }

  const primaryPlan = getActionPlan(primary);
  const secondaryName = secondary ? secondary.sector_name : "暂无";
  const watchName = watch ? watch.sector_name : "暂无";
  const primaryPct = primary.realtime_pct_change ?? primary.pct_change;
  const hasPositiveLeader = primaryPct > 0;

  return {
    title: hasPositiveLeader ? `优先盯 ${primary.sector_name}` : `${primary.sector_name} 相对抗跌`,
    detail: hasPositiveLeader
      ? `次主线 ${secondaryName}，观察线 ${watchName}。`
      : `${primary.sector_name}、${secondaryName} 暂按抗跌观察。`,
    canDo: hasPositiveLeader
      ? [
          `${primary.sector_name}：${primaryPlan.description}`,
          secondary ? `${secondary.sector_name}：次主线观察。` : "暂无次主线。",
          "看前排、广度、回流。",
        ]
      : [
          `看 ${primary.sector_name} 是否止跌转强。`,
          secondary ? `${secondary.sector_name}：备选抗跌。` : "暂无次主线。",
          "确认翻红、扩散、承接。",
        ],
    avoid: hasPositiveLeader
      ? [
          "不把后排补涨当主线。",
          "不只看涨幅。",
          watch ? `${watch.sector_name}：观察线。` : "后期板块只观察。",
        ]
      : [
          "不把负涨幅当主线。",
          "不因抗跌重仓进攻。",
          "不只盯排名第一。",
        ],
  };
}

function LeadingStockPill({ stock }: { stock: LeadingStock }) {
  return (
    <a
      href={`/stock/${stock.ts_code}`}
      className="inline-flex items-center gap-1.5 rounded-lg border border-border-subtle bg-surface-2 px-2 py-1 text-[11px] transition-colors hover:border-amber-500/20"
    >
      <span className="text-text-secondary font-medium">{stock.name}</span>
      <span className={`font-mono tabular-nums ${stock.pct_chg >= 0 ? "text-red-400/80" : "text-emerald-400/80"}`}>
        {stock.pct_chg > 0 ? "+" : ""}{stock.pct_chg.toFixed(2)}%
      </span>
    </a>
  );
}

function DecisionList({
  title,
  items,
  tone,
}: {
  title: string;
  items: string[];
  tone: "positive" | "risk";
}) {
  const dotClass = tone === "positive" ? "bg-emerald-400" : "bg-amber-400";

  return (
    <div className="rounded-2xl border border-border-subtle bg-surface-1/70 p-3">
      <div className="text-[11px] font-semibold text-text-secondary">{title}</div>
      <div className="mt-2 space-y-2">
        {items.map((item, index) => (
          <div key={`${title}-${index}`} className="flex items-start gap-2 text-sm text-text-secondary">
            <span className={`mt-1.5 h-1.5 w-1.5 shrink-0 rounded-full ${dotClass}`} />
            <span className="leading-6">{item}</span>
          </div>
        ))}
      </div>
    </div>
  );
}

function LaneCard({
  title,
  description,
  sectors,
  tone,
}: {
  title: string;
  description: string;
  sectors: SectorData[];
  tone: "red" | "amber" | "slate";
}) {
  const toneClass =
    tone === "red"
      ? "border-red-500/15 bg-red-500/[0.04] text-red-400"
      : tone === "amber"
        ? "border-amber-500/15 bg-amber-500/[0.04] text-amber-400"
        : "border-border-subtle bg-surface-2 text-text-secondary";

  return (
    <div className="rounded-2xl border border-border-subtle bg-surface-1/70 p-4">
      <div className="flex items-center justify-between gap-3">
        <div>
          <h3 className="text-sm font-bold tracking-tight text-text-primary">{title}</h3>
          <p className="mt-1 text-[11px] text-text-muted">{description}</p>
        </div>
        <span className={`rounded-lg border px-2 py-1 text-xs font-mono tabular-nums ${toneClass}`}>
          {sectors.length}
        </span>
      </div>

      <div className="mt-3 space-y-2.5">
        {sectors.length ? sectors.map((sector, index) => <LaneRow key={sector.sector_code} sector={sector} rank={index + 1} />) : (
          <div className="text-xs text-text-muted">暂无数据</div>
        )}
      </div>
    </div>
  );
}

function LaneRow({ sector, rank }: { sector: SectorData; rank: number }) {
  const displayPct = sector.realtime_pct_change ?? sector.pct_change;
  const stage = getStageInfo(sector.stage ?? "");
  const action = getActionPlan(sector);
  const leaders = getLeaders(sector).slice(0, 2);
  const catalyst = getCatalystLabel(sector);

  return (
    <Link href={`/sectors/${encodeURIComponent(sector.sector_name)}`} className="block rounded-xl border border-border-subtle bg-surface-2/70 px-3 py-3 transition-colors hover:border-amber-500/20 hover:bg-surface-3">
      <div className="flex items-start justify-between gap-3">
        <div className="min-w-0 flex gap-3">
          <div className="flex h-7 w-7 shrink-0 items-center justify-center rounded-lg bg-surface-1 font-mono text-xs text-text-muted">
            {rank}
          </div>
          <div className="min-w-0">
            <div className="flex items-center gap-2 flex-wrap">
              <span className="text-sm font-semibold text-text-primary">{sector.sector_name}</span>
              {sector.board_type === "theme" ? (
                <span className="rounded-md border border-sky-500/15 bg-sky-500/10 px-1.5 py-0.5 text-[10px] text-sky-300">
                  主题
                </span>
              ) : null}
              <span className={`rounded-md border px-1.5 py-0.5 text-[10px] ${stage.bg} ${stage.color}`}>
                {stage.label}
              </span>
              {catalyst ? (
                <span className={`rounded-md border px-1.5 py-0.5 text-[10px] ${catalyst.className}`}>
                  {catalyst.label}
                </span>
              ) : null}
            </div>
            <div className="mt-1 text-[11px] text-text-muted">
              {getThemeAliasLine(sector)}
            </div>
            <div className="mt-1 text-[11px] text-text-muted">
              代表股：{leaders.length ? leaders.map((item) => item.name).join(" / ") : "暂无"}
            </div>
          </div>
        </div>
        <div className="text-right shrink-0">
          <div className={`text-sm font-bold font-mono tabular-nums ${displayPct >= 0 ? "text-red-400" : "text-emerald-400"}`}>
            {displayPct > 0 ? "+" : ""}{displayPct.toFixed(2)}%
          </div>
          <div className="mt-1 text-[10px] text-text-muted">{action.label}</div>
        </div>
      </div>
      <div className="mt-2 grid grid-cols-2 gap-2 text-[11px]">
        <div className="rounded-lg bg-surface-1 px-2 py-1.5 text-text-secondary">
          跟踪方式：{action.description}
        </div>
        <div className="rounded-lg bg-surface-1 px-2 py-1.5 text-text-secondary">
          失效信号：{action.risk}
        </div>
      </div>
    </Link>
  );
}

function SectorCard({ sector, index }: { sector: SectorData; index: number }) {
  const displayPct = sector.realtime_pct_change ?? sector.pct_change;
  const displayAmount = sector.realtime_amount ?? sector.capital_inflow;
  const displayLimitUp = sector.realtime_limit_up_count ?? sector.limit_up_count;
  const stage = getStageInfo(sector.stage ?? "");
  const leaders = getLeaders(sector).slice(0, 3);
  const action = getActionPlan(sector);
  const catalyst = getCatalystLabel(sector);
  const catalystReason = sector.catalyst_reasons?.[0];

  return (
    <div className="rounded-xl border border-border-subtle bg-surface-1/70 px-3 py-3 animate-fade-in-up transition-colors hover:border-amber-500/20 hover:bg-surface-2/70" style={{ animationDelay: `${index * 30}ms` }}>
        <div className="flex items-start justify-between gap-3">
          <div className="min-w-0">
            <div className="flex items-center gap-2 flex-wrap">
              <Link href={`/sectors/${encodeURIComponent(sector.sector_name)}`} className="text-sm font-semibold text-text-primary hover:text-amber-300">
                {sector.sector_name}
              </Link>
              {sector.board_type === "theme" ? (
                <span className="rounded-md border border-sky-500/15 bg-sky-500/10 px-1.5 py-0.5 text-[10px] text-sky-300">
                  主题
                </span>
              ) : null}
              <span className={`rounded-md border px-1.5 py-0.5 text-[10px] ${stage.bg} ${stage.color}`}>
                {stage.label}
              </span>
              {catalyst ? (
                <span className={`rounded-md border px-1.5 py-0.5 text-[10px] ${catalyst.className}`}>
                  {catalyst.label}
                </span>
              ) : null}
            </div>
            <div className="mt-1 text-[11px] text-text-muted">
              {action.label} · {action.description}
            </div>
          </div>
          <div className="text-right shrink-0">
            <div className={`text-base font-bold font-mono tabular-nums ${displayPct >= 0 ? "text-red-400" : "text-emerald-400"}`}>
              {displayPct > 0 ? "+" : ""}{displayPct.toFixed(2)}%
            </div>
            <div className="mt-1 text-[10px] text-text-muted">热度 {sector.heat_score.toFixed(0)}</div>
          </div>
        </div>

        <div className="mt-3 grid grid-cols-3 gap-2">
          <MetricBox label="资金">
            <span className={`font-mono tabular-nums ${displayAmount >= 0 ? "text-red-400" : "text-emerald-400"}`}>
              {displayAmount >= 0 ? "+" : ""}{formatNumber(displayAmount)}
            </span>
          </MetricBox>
          <MetricBox label="涨停">
            <span className="font-mono tabular-nums text-text-secondary">{displayLimitUp}只</span>
          </MetricBox>
          <MetricBox label="主力">
            <span className="font-mono tabular-nums text-text-secondary">{(sector.main_force_ratio ?? 0).toFixed(1)}%</span>
          </MetricBox>
        </div>

        {catalystReason ? (
          <div className="mt-3 rounded-xl border border-amber-500/15 bg-amber-500/[0.06] px-3 py-2">
            <div className="text-[10px] uppercase tracking-wider text-amber-300/80 font-semibold">新闻/政策催化</div>
            <div className="mt-1 text-[12px] leading-6 text-text-secondary">
              {catalystReason}
            </div>
          </div>
        ) : null}

        <div className="mt-3 rounded-xl bg-surface-2/70 px-3 py-2">
          <div className="text-[10px] uppercase tracking-wider text-text-muted font-semibold">失效信号</div>
          <div className="mt-1 text-[12px] leading-5 text-text-secondary">
            {action.risk}
          </div>
        </div>

        <Link href={`/sectors/${encodeURIComponent(sector.sector_name)}`} className="mt-3 inline-flex rounded-lg border border-amber-500/15 bg-amber-500/[0.05] px-3 py-1.5 text-xs font-medium text-amber-400 hover:bg-amber-500/[0.08]">
          查看成分候选
        </Link>

        {leaders.length ? (
          <div className="mt-3">
            <div className="text-[10px] uppercase tracking-wider text-text-muted font-semibold mb-2">代表股</div>
            <div className="flex flex-wrap gap-2">
              {leaders.map((stock) => <LeadingStockPill key={stock.ts_code} stock={stock} />)}
            </div>
          </div>
        ) : null}
    </div>
  );
}

function MetricBox({ label, children }: { label: string; children: React.ReactNode }) {
  return (
    <div className="rounded-lg bg-surface-1 px-2.5 py-2">
      <div className="text-[10px] text-text-muted/50 mb-0.5">{label}</div>
      <div className="text-xs font-semibold">{children}</div>
    </div>
  );
}

function IndustryChainMatrix({ themes }: { themes: ResearchReport["theme_views"] }) {
  const nodeCount = themes.reduce((sum, theme) => sum + normalizedChainItems(theme).length, 0);
  const mappedStockCount = themes.reduce(
    (sum, theme) => sum + normalizedChainItems(theme).reduce((nodeSum, node) => nodeSum + node.leader_stocks.length + node.related_stocks.length, 0),
    0
  );

  return (
    <section className="glass-card-static overflow-hidden animate-fade-in-up">
      <div className="flex flex-col gap-3 border-b border-border-subtle px-4 py-4 md:flex-row md:items-end md:justify-between md:px-5">
        <div>
          <div className="text-[10px] font-semibold uppercase tracking-[0.22em] text-amber-400">Industry Chain</div>
          <h3 className="mt-1 text-base font-bold text-text-primary">产业链扩散路径</h3>
          <p className="mt-1 text-xs leading-5 text-text-muted">从主题到环节，再到核心股和相关股。</p>
        </div>
        <div className="grid grid-cols-3 gap-2 text-right">
          <MatrixMetric label="主题" value={themes.length} />
          <MatrixMetric label="环节" value={nodeCount} />
          <MatrixMetric label="标的" value={mappedStockCount} />
        </div>
      </div>

      <div className="divide-y divide-border-subtle">
        {themes.map((theme) => (
          <ThemeChainRow key={`${theme.theme}-${theme.raw_sector}`} theme={theme} />
        ))}
      </div>
    </section>
  );
}

function ThemeChainRow({ theme }: { theme: ResearchReport["theme_views"][number] }) {
  const chainItems = normalizedChainItems(theme);

  return (
    <article className="grid gap-4 px-4 py-4 md:px-5 xl:grid-cols-[230px_minmax(0,1fr)]">
      <div className="min-w-0">
        <div className="flex items-start justify-between gap-3 xl:block">
          <div className="min-w-0">
            <div className="truncate text-sm font-semibold text-text-primary">{theme.theme}</div>
            <div className="mt-1 text-[11px] text-text-muted">
              {theme.lifecycle_status || theme.stage} · {theme.raw_sector || theme.theme}
            </div>
          </div>
          <div className="font-mono text-base font-semibold tabular-nums text-amber-400 xl:mt-3">
            {Math.round(theme.heat_score)}
          </div>
        </div>
        <p className="mt-3 line-clamp-3 text-xs leading-5 text-text-secondary">{theme.logic}</p>
      </div>

      <div className="grid gap-2 md:grid-cols-2 2xl:grid-cols-3">
        {chainItems.slice(0, 9).map((item) => (
          <ChainNodeBlock key={`${theme.theme}-${item.chain_node}`} item={item} />
        ))}
      </div>
    </article>
  );
}

function ChainNodeBlock({ item }: { item: ThemeChainItem }) {
  const leaders = item.leader_stocks.slice(0, 4);
  const related = item.related_stocks.slice(0, 4);
  const hasStocks = leaders.length || related.length;

  return (
    <div className="rounded-xl border border-border-subtle bg-surface-1/60 px-3 py-3">
      <div className="flex items-center justify-between gap-2">
        <div className="truncate text-xs font-semibold text-text-primary">{item.chain_node}</div>
        {item.node_role ? (
          <span className="shrink-0 rounded-md border border-amber-500/15 bg-amber-500/[0.06] px-1.5 py-0.5 text-[10px] text-amber-300">
            {item.node_role}
          </span>
        ) : null}
      </div>
      {hasStocks ? (
        <div className="mt-3 space-y-2">
          {leaders.length ? <StockStrip label="核心" stocks={leaders} tone="core" /> : null}
          {related.length ? <StockStrip label="相关" stocks={related} tone="related" /> : null}
        </div>
      ) : (
        <div className="mt-3 rounded-lg bg-surface-2/45 px-2 py-2 text-[11px] text-text-muted">
          待维护标的
        </div>
      )}
    </div>
  );
}

function StockStrip({
  label,
  stocks,
  tone,
}: {
  label: string;
  stocks: ThemeChainItem["leader_stocks"];
  tone: "core" | "related";
}) {
  return (
    <div>
      <div className={`mb-1 text-[10px] font-semibold ${tone === "core" ? "text-red-300" : "text-text-muted"}`}>{label}</div>
      <div className="flex flex-wrap gap-1.5">
        {stocks.map((stock, index) => <StockTag key={`${stockLabel(stock)}-${index}`} stock={stock} tone={tone} />)}
      </div>
    </div>
  );
}

function StockTag({ stock, tone }: { stock: string | { name?: string; ts_code?: string }; tone: "core" | "related" }) {
  const label = stockLabel(stock);
  const code = typeof stock === "string" ? "" : stock.ts_code || "";
  const className = tone === "core"
    ? "border-red-500/15 bg-red-500/[0.06] text-red-200"
    : "border-border-subtle bg-surface-2/70 text-text-secondary";
  if (code) {
    return (
      <Link href={`/stock/${code}`} className={`rounded-lg border px-2 py-1 text-[10px] transition-colors hover:border-amber-500/20 hover:text-amber-300 ${className}`}>
        {label}
      </Link>
    );
  }
  return <span className={`rounded-lg border px-2 py-1 text-[10px] ${className}`}>{label}</span>;
}

function MatrixMetric({ label, value }: { label: string; value: number }) {
  return (
    <div className="rounded-lg bg-surface-2/60 px-3 py-2">
      <div className="text-[10px] text-text-muted">{label}</div>
      <div className="mt-0.5 font-mono text-sm font-semibold tabular-nums text-text-primary">{value}</div>
    </div>
  );
}

function normalizedChainItems(theme: ResearchReport["theme_views"][number]): ThemeChainItem[] {
  const explicitItems = (theme.chain_items ?? []).filter((item) => item.chain_node);
  if (explicitItems.length) return explicitItems;
  return theme.chain_nodes.map((node) => ({
    chain_node: node,
    leader_stocks: [],
    related_stocks: [],
    node_role: "",
  }));
}

function stockLabel(stock: string | { name?: string; ts_code?: string }) {
  if (typeof stock === "string") return stock;
  return stock.name || stock.ts_code || "-";
}

export default function SectorsPage() {
  const [sectors, setSectors] = useState<SectorData[]>([]);
  const [research, setResearch] = useState<ResearchReport | null>(null);
  const [stageFilter, setStageFilter] = useState<string>("all");

  const loadData = useCallback(async () => {
    try {
      const [data, researchData] = await Promise.all([
        fetchAPI<SectorData[]>("/api/sectors/hot?limit=20"),
        fetchAPI<ResearchReport>("/api/research/today").catch(() => null),
      ]);
      setSectors(data);
      setResearch(researchData);
    } catch {
      // ignore
    }
  }, []);

  useEffect(() => {
    loadData();
  }, [loadData]);

  useWebSocket(
    useCallback(() => {
      loadData();
    }, [loadData])
  );

  const summary = getHeadline(sectors);
  const topPct = sectors[0] ? (sectors[0].realtime_pct_change ?? sectors[0].pct_change) : 0;
  const hasPositiveLeader = topPct > 0;

  const stageCounts = useMemo(() => {
    const counts = { all: sectors.length, early: 0, mid: 0, late_end: 0 };
    sectors.forEach((sector) => {
      if (sector.stage === "early") counts.early++;
      else if (sector.stage === "mid") counts.mid++;
      else if (sector.stage === "late" || sector.stage === "end") counts.late_end++;
    });
    return counts;
  }, [sectors]);

  const filteredSectors = useMemo(() => {
    if (stageFilter === "all") return sectors;
    if (stageFilter === "late_end") return sectors.filter((sector) => sector.stage === "late" || sector.stage === "end");
    return sectors.filter((sector) => sector.stage === stageFilter);
  }, [sectors, stageFilter]);

  const mainline = sectors.slice(0, 3);
  const secondary = sectors.slice(3, 6);
  const watchline = sectors.filter((sector) => ["late", "end"].includes(sector.stage ?? "")).slice(0, 4);

  return (
    <ErrorBoundary>
      <div className="max-w-7xl mx-auto px-4 md:px-8 pt-6 pb-20 md:pb-10 space-y-5">
        <div className="animate-fade-in-up">
          <h1 className="text-lg font-bold tracking-tight">主题图谱</h1>
          <p className="mt-1 text-xs text-text-muted">从板块强度升级到主题、产业链环节和前排公司。</p>
        </div>

        {!sectors.length ? (
          <div className="glass-card-static p-12 text-center animate-fade-in-up">
            <div className="text-sm text-text-muted">暂无主线结论</div>
            <div className="mt-1 text-xs text-text-muted/50">等下一次复盘后再看。</div>
          </div>
        ) : (
          <>
            <div className="glass-card-static p-4 md:p-5 animate-fade-in-up">
              <div className="grid grid-cols-1 xl:grid-cols-[minmax(0,1fr)_320px] gap-4">
                <div>
                  <div className="text-[10px] uppercase tracking-[0.22em] text-amber-400 font-semibold">今日主线结论</div>
                  <h2 className="mt-2 text-xl font-bold tracking-tight text-text-primary">{summary.title}</h2>
                  <p className="mt-2 max-w-3xl text-sm leading-6 text-text-secondary">{summary.detail}</p>
                  <div className="mt-4 grid grid-cols-1 md:grid-cols-2 gap-3">
                    <DecisionList title="动作" items={summary.canDo} tone="positive" />
                    <DecisionList title="边界" items={summary.avoid} tone="risk" />
                  </div>
                </div>

                <div className="grid grid-cols-2 gap-2 self-start">
                  <MetricBox label="主线数"><span className="font-mono tabular-nums text-text-primary">{mainline.length}</span></MetricBox>
                  <MetricBox label="次主线"><span className="font-mono tabular-nums text-text-primary">{secondary.length}</span></MetricBox>
                  <MetricBox label="观察线"><span className="font-mono tabular-nums text-text-primary">{watchline.length}</span></MetricBox>
                  <MetricBox label="强催化"><span className="font-mono tabular-nums text-amber-400">{sectors.filter((sector) => (sector.catalyst_score ?? 0) >= 70).length}</span></MetricBox>
                </div>
              </div>
            </div>

            {research?.theme_views?.length ? <IndustryChainMatrix themes={research.theme_views.slice(0, 6)} /> : null}

            <div className="grid grid-cols-1 xl:grid-cols-[1.15fr_0.95fr_0.8fr] gap-4 animate-fade-in-up">
              <LaneCard
                title={hasPositiveLeader ? "今日主线" : "相对抗跌"}
                description={hasPositiveLeader ? "优先方向" : "暂不进攻"}
                sectors={mainline}
                tone="red"
              />
              <LaneCard
                title={hasPositiveLeader ? "次主线" : "弱轮动观察"}
                description={hasPositiveLeader ? "轮动跟踪" : "转强观察"}
                sectors={secondary}
                tone="amber"
              />
              <LaneCard
                title="观察线"
                description="变化记录"
                sectors={watchline}
                tone="slate"
              />
            </div>

            <div className="grid grid-cols-1 xl:grid-cols-[minmax(0,1fr)_340px] gap-4 animate-fade-in-up">
              <div className="glass-card-static p-4 md:p-5">
                <div className="flex flex-wrap items-center justify-between gap-3">
                  <div>
                    <h2 className="text-sm font-semibold text-text-primary">方向清单</h2>
                  </div>
                  <div className="flex flex-wrap items-center gap-2">
                    {[
                      { key: "all", label: "全部", count: stageCounts.all },
                      { key: "early", label: "启动期", count: stageCounts.early },
                      { key: "mid", label: "发展期", count: stageCounts.mid },
                      { key: "late_end", label: "后期/尾声", count: stageCounts.late_end },
                    ].map((tab) => (
                      <button
                        key={tab.key}
                        onClick={() => setStageFilter(tab.key)}
                        className={`rounded-lg border px-3 py-1.5 text-xs font-medium transition-all ${
                          stageFilter === tab.key
                            ? "border-amber-500/20 bg-amber-500/[0.06] text-amber-400"
                            : "border-transparent bg-surface-2 text-text-muted hover:text-text-secondary"
                        }`}
                      >
                        {tab.label}
                        <span className="ml-1 text-[10px] text-text-muted/50">{tab.count}</span>
                      </button>
                    ))}
                  </div>
                </div>

                {!filteredSectors.length ? (
                  <div className="mt-4 rounded-2xl border border-border-subtle bg-surface-1/70 p-8 text-center text-sm text-text-muted">
                    当前筛选下无板块数据。
                  </div>
                ) : (
                  <div className="mt-4 grid grid-cols-1 md:grid-cols-2 gap-3">
                    {filteredSectors.map((sector, index) => (
                      <SectorCard key={sector.sector_code} sector={sector} index={index} />
                    ))}
                  </div>
                )}
              </div>

              <div className="glass-card-static p-4 self-start">
                <h2 className="text-sm font-semibold text-text-primary">怎么使用</h2>
                <div className="mt-3 space-y-2 text-sm leading-6 text-text-secondary">
                  <div>先看今日主线，再看前排代表股。</div>
                  <div>只在回流、扩散和承接同时出现时提高优先级。</div>
                  <div>后期和尾声方向只做观察，不当作新主线追。</div>
                </div>
              </div>
            </div>
          </>
        )}
      </div>
    </ErrorBoundary>
  );
}
