"use client";

import { useEffect, useMemo, useState } from "react";
import Link from "next/link";
import { initialCnUniverse, type CnUniverseResponse } from "@/lib/cn-universe";

const stamp = (value: string | null) => value ? new Date(value).toLocaleString("zh-CN", { hour12: false, timeZone: "Asia/Shanghai" }) : "尚未完成";
const venueName = { SSE: "上海", SZSE: "深圳", BSE: "北京" } as const;
const kindName = { A_SHARE: "A股个股", LISTED_FUND: "场内基金", CONVERTIBLE_BOND: "可转债" } as const;

export function CnUniverseBrowser() {
  const [data, setData] = useState<CnUniverseResponse>(initialCnUniverse);
  const [query, setQuery] = useState("");
  const [venue, setVenue] = useState("ALL");
  const [kind, setKind] = useState("ALL");
  const [dayTrade, setDayTrade] = useState("ALL");
  const [listStatus, setListStatus] = useState("ALL");
  const [page, setPage] = useState(1);
  const [error, setError] = useState<string | null>(null);

  const requestQuery = useMemo(() => new URLSearchParams({ q: query, venue, kind, dayTrade, listStatus, page: String(page), pageSize: "40" }).toString(), [query, venue, kind, dayTrade, listStatus, page]);

  useEffect(() => {
    let disposed = false;
    let timer: number | null = null;
    const update = async () => {
      try {
        const response = await fetch(`/api/universe?${requestQuery}`, { cache: "no-store" });
        if (!response.ok) throw new Error(`HTTP ${response.status}`);
        const next = await response.json() as CnUniverseResponse;
        if (!disposed) { setData(next); setError(null); }
      } catch (reason) {
        if (!disposed) setError(reason instanceof Error ? reason.message : "标的目录连接失败");
      }
      if (!disposed) timer = window.setTimeout(update, data.meta.status === "syncing" ? 5_000 : 60_000);
    };
    const debounce = window.setTimeout(update, 250);
    return () => { disposed = true; window.clearTimeout(debounce); if (timer !== null) window.clearTimeout(timer); };
  }, [requestQuery, data.meta.status]);

  const totals = data.meta.totals;
  const sourceStates = Object.entries(data.meta.sourceProgress);
  const completedPages = sourceStates.reduce((sum, [, source]) => sum + Math.min(source.pageCount, Math.max(0, source.nextPage - 1)), 0);
  const allPages = sourceStates.reduce((sum, [, source]) => sum + source.pageCount, 0);

  const resetPage = (setter: (value: string) => void, value: string) => { setter(value); setPage(1); };

  return <div className="universe-browser">
    <section className="universe-hero">
      <div><span className="kicker">OFFICIAL CHINA SECURITIES UNIVERSE</span><h1>A股、日内基金与可转债全市场目录</h1><p>沪深北A股、沪深场内基金与沪深可转债持续更新；“在目录里”不等于“允许下单”。A股严格按T+1，已核验基金与可转债按T+0候选处理，并继续接受分钟行情、流动性、强赎/停牌和风险过滤。</p></div>
      <div className={`universe-sync-state ${data.meta.status}`}><span>目录状态</span><b>{data.meta.status === "ready" ? "全量同步完成" : data.meta.status === "degraded" ? "部分来源降级" : "官方目录同步中"}</b><small>{completedPages} / {allPages || "—"} 数据页 · 完成于 {stamp(data.meta.lastCompleteSyncAt)}</small></div>
    </section>

    <section className="universe-metrics">
      <article><span>已上市A股</span><b>{totals.listedAStocks.toLocaleString("zh-CN")}</b><small>沪 / 深 / 北</small></article>
      <article><span>场内基金</span><b>{totals.listedFunds.toLocaleString("zh-CN")}</b><small>全部研究目录</small></article>
      <article><span>已核验T+0基金</span><b>{totals.verifiedT0Funds.toLocaleString("zh-CN")}</b><small>仍需实时流动性过滤</small></article>
      <article><span>已上市可转债</span><b>{totals.listedConvertibleBonds.toLocaleString("zh-CN")}</b><small>沪 / 深 · T+0候选</small></article>
      <article><span>待上市 / 未来日期</span><b>{totals.upcoming.toLocaleString("zh-CN")}</b><small>研究观察，不可交易</small></article>
      <article><span>当前镜像激活</span><b>{data.activeMirrorSymbols.length}</b><small>{data.activeMirrorSymbols.join(" / ")}</small></article>
    </section>

    <section className="universe-disclosure">
      <b>双层标的池</b><p>{data.executionDisclosure}</p>
      <dl><div><dt>未来上市</dt><dd>{data.meta.coverage.futureListings}</dd></div><div><dt>T+0确认</dt><dd>{data.meta.coverage.t0Policy}</dd></div></dl>
    </section>

    <section className="universe-directory">
      <header><div><span>SEARCH / FILTER / READ ONLY</span><h2>完整官方目录</h2></div><Link href="/execution">返回实盘策略 →</Link></header>
      <div className="universe-filters">
        <label><span>代码或名称</span><input value={query} onChange={(event) => resetPage(setQuery, event.target.value)} placeholder="例如 510900 / 黄金" /></label>
        <label><span>交易所</span><select value={venue} onChange={(event) => resetPage(setVenue, event.target.value)}><option value="ALL">全部</option><option value="SSE">上海</option><option value="SZSE">深圳</option><option value="BSE">北京</option></select></label>
        <label><span>证券类别</span><select value={kind} onChange={(event) => resetPage(setKind, event.target.value)}><option value="ALL">全部</option><option value="A_SHARE">A股个股</option><option value="LISTED_FUND">场内基金</option><option value="CONVERTIBLE_BOND">可转债</option></select></label>
        <label><span>回转资格</span><select value={dayTrade} onChange={(event) => resetPage(setDayTrade, event.target.value)}><option value="ALL">全部</option><option value="VERIFIED_T0">已核验T+0</option><option value="T1_ONLY">仅T+1</option><option value="VERIFY_REQUIRED">待逐只核验</option></select></label>
        <label><span>上市状态</span><select value={listStatus} onChange={(event) => resetPage(setListStatus, event.target.value)}><option value="ALL">全部</option><option value="LISTED">已上市</option><option value="UPCOMING">待上市</option></select></label>
      </div>
      {error && <p className="universe-error">连接提示：{error}；保留上一次成功目录。</p>}
      <div className="responsive-table universe-table"><table><thead><tr><th>代码</th><th>证券</th><th>交易所</th><th>类别</th><th>上市状态</th><th>回转 / 结算</th><th>策略角色</th><th>执行判定</th><th>官方来源</th></tr></thead><tbody>{data.records.map((record) => <tr key={record.key}><td><b>{record.symbol}</b></td><td><strong>{record.name}</strong><small>{record.category}</small></td><td>{venueName[record.venue]}</td><td>{kindName[record.kind]}</td><td><span className={`universe-badge ${record.listStatus.toLowerCase()}`}>{record.listStatus === "LISTED" ? "已上市" : "待上市"}</span><small>{record.listingDate ?? "日期待定"}</small></td><td><span className={`universe-badge ${record.dayTradeEligibility.toLowerCase()}`}>{record.dayTradeEligibility === "VERIFIED_T0" ? "已核验 T+0" : record.dayTradeEligibility === "T1_ONLY" ? "仅 T+1" : "待逐只核验"}</span><small>{record.settlement}</small></td><td>{record.poolRole === "T0_EXECUTION_CANDIDATE" ? "基金T+0候选" : record.poolRole === "T0_CONVERTIBLE_BOND_CANDIDATE" ? "转债T+0候选" : record.poolRole === "T1_RESEARCH_ONLY" ? "T+1研究" : "观察/研究"}</td><td><span className={record.executionEligible ? "positive" : "muted"}>{record.executionEligible ? "可进入二次过滤" : "禁止自动下单"}</span><small>{record.executionReason}</small></td><td><a href={record.sourceUrl} target="_blank" rel="noreferrer">{record.source} ↗</a></td></tr>)}</tbody></table></div>
      {!data.records.length && <div className="execution-empty"><b>官方目录正在分批建立</b><p>为适配免费云服务请求额度，沪深北页面按批次持久化；同步期间不会把未知证券放入自动下单候选。</p></div>}
      <footer className="universe-pagination"><span>筛选结果 {data.pagination.total.toLocaleString("zh-CN")} 条 · 第 {data.pagination.page} / {data.pagination.pageCount} 页</span><div><button type="button" disabled={page <= 1} onClick={() => setPage((value) => Math.max(1, value - 1))}>上一页</button><button type="button" disabled={page >= data.pagination.pageCount} onClick={() => setPage((value) => Math.min(data.pagination.pageCount, value + 1))}>下一页</button></div></footer>
    </section>

    <section className="universe-sources"><header><span>OFFICIAL SOURCE HEALTH</span><h2>数据源同步状态</h2></header><div>{sourceStates.map(([key, source]) => <article key={key}><b>{key}</b><span>{Math.min(source.pageCount, Math.max(0, source.nextPage - 1))} / {source.pageCount} 页</span><small>{source.lastError ? `错误：${source.lastError}` : `官方数据日：${source.sourceDate ?? "待返回"}`}</small><a href={source.sourceUrl} target="_blank" rel="noreferrer">官方页面 ↗</a></article>)}</div></section>

    <p className="risk-note">目录自动更新不构成投资建议，也不能保证完整、实时或无误。正式真实交易前，必须以券商证券主数据、交易日历、停复牌、涨跌停、当日可卖数量和合规权限再次核验；任何来源异常默认拒绝开仓。</p>
  </div>;
}
