/* Page — 產業熱力圖
 *  - 依觀察清單把個股分產業（台股 industry_category / 美股 Subsector）
 *  - 卡片網格：產業卡底色 = 該產業平均當日漲跌幅，卡內個股小色塊 = 個股漲跌幅
 *  - 台 / 美股 tab 切換；台股漲紅跌綠、美股漲綠跌紅（沿用 data-color-mode）
 *  - 資料複用 WatchlistEngine.resolveRows + Intraday 即時報價（同總覽頁）
 */
const { Icon, fmt } = window.UI;
const { MarketSummaryBar } = window.Shell;

const HEATMAP_DEFAULT_LISTS = [];

/* 漲跌幅 → 背景色。台股漲紅、美股漲綠；|pct| 越大越濃（clamp ±5%），近平盤給灰。 */
function heatColor(pct, market) {
  if (!Number.isFinite(pct) || Math.abs(pct) < 0.05) return "rgba(125,135,150,0.10)";
  const upRed = market === "TW";
  const mag = Math.max(0, Math.min(1, Math.abs(pct) / 5));
  const alpha = (0.14 + mag * 0.62).toFixed(3);
  const red = (pct >= 0) === upRed;
  return `rgba(${red ? "231,76,60" : "39,174,96"},${alpha})`;
}

const HeatmapPage = ({ goChart }) => {
  const [userLists] = window.useCloudState("watchlists", HEATMAP_DEFAULT_LISTS);
  const [market, setMarket] = React.useState("TW");

  const watchedSymsArr = React.useMemo(() => {
    const set = new Set();
    userLists.forEach((l) => (l.syms || []).forEach((s) => set.add(s)));
    return Array.from(set);
  }, [userLists]);
  const symsKey = watchedSymsArr.join(",");

  /* 日 K 衍生 rows（含 pct / market / name） */
  const [baseRows, setBaseRows] = React.useState(null);
  const [loadErr, setLoadErr] = React.useState(null);
  React.useEffect(() => {
    let cancelled = false;
    setBaseRows(null); setLoadErr(null);
    if (!window.WatchlistEngine || watchedSymsArr.length === 0) return;
    window.WatchlistEngine.resolveRows(watchedSymsArr)
      .then((rs) => { if (!cancelled) setBaseRows(rs); })
      .catch((e) => { if (!cancelled) setLoadErr(e.message); });
    return () => { cancelled = true; };
  }, [symsKey]);

  /* 即時報價覆蓋當日 pct */
  const [quotes, setQuotes] = React.useState(new Map());
  React.useEffect(() => {
    if (!window.Intraday || !window.Intraday.isEnabled() || watchedSymsArr.length === 0) return;
    const unsub = window.Intraday.subscribeMany(watchedSymsArr, (r) => setQuotes(r.quotes));
    return unsub;
  }, [symsKey]);

  /* 產業對應（FinMind，24h 快取） */
  const [industryMap, setIndustryMap] = React.useState(null);
  React.useEffect(() => {
    let cancelled = false;
    if (!window.FinMind || !window.FinMind.getIndustryMap || watchedSymsArr.length === 0) return;
    window.FinMind.getIndustryMap(watchedSymsArr)
      .then((m) => { if (!cancelled) setIndustryMap(m); })
      .catch(() => {});
    return () => { cancelled = true; };
  }, [symsKey]);

  const rows = React.useMemo(() => {
    const base = baseRows || [];
    return window.WatchlistEngine ? window.WatchlistEngine.mergeQuotes(base, quotes) : base;
  }, [baseRows, quotes]);

  const liveQuotes = quotes && quotes.size > 0;
  const dataReady = baseRows != null;
  const twCount = rows.filter((r) => r.market === "TW").length;
  const usCount = rows.filter((r) => r.market === "US").length;

  /* 依目前 tab 過濾 → 分產業 → 算平均漲跌幅，產業依平均漲幅由高到低排 */
  const groups = React.useMemo(() => {
    const mkt = rows.filter((r) => r.market === market);
    const byInd = new Map();
    mkt.forEach((r) => {
      const ind = (industryMap && industryMap.get(r.sym)) || "（待分類）";
      if (!byInd.has(ind)) byInd.set(ind, []);
      byInd.get(ind).push(r);
    });
    return Array.from(byInd.entries()).map(([name, stocks]) => {
      const valid = stocks.filter((s) => Number.isFinite(s.pct));
      const avg = valid.length ? valid.reduce((a, s) => a + s.pct, 0) / valid.length : 0;
      return { name, stocks: stocks.sort((a, b) => b.pct - a.pct), avg, count: stocks.length };
    }).sort((a, b) => b.avg - a.avg);
  }, [rows, industryMap, market]);

  return (
    <div className="page heatmap-page">
      <MarketSummaryBar/>
      <section className="heatmap-head-section">
        <div className="heatmap-head">
          <div className="heatmap-head-l">
            <h2 className="heatmap-title">產業熱力圖</h2>
            <span className="dim mono heatmap-sub">
              依觀察清單 · {market === "TW" ? `${twCount} 檔台股` : `${usCount} 檔美股`} · {groups.length} 個產業
            </span>
            {!dataReady && <span className="pill" style={{ fontSize: "var(--fs-xs)" }}>載入日 K…</span>}
            {dataReady && !industryMap && <span className="pill" style={{ fontSize: "var(--fs-xs)" }}>產業分類中…</span>}
            {loadErr && <span className="pill warn" style={{ fontSize: "var(--fs-xs)" }} title={loadErr}>載入失敗</span>}
            {liveQuotes && <span className="pill success dot" style={{ fontSize: "var(--fs-xs)" }}>即時報價</span>}
          </div>
          <div className="seg heatmap-tabs">
            <button className={market === "TW" ? "active" : ""} onClick={() => setMarket("TW")}>台股 {twCount}</button>
            <button className={market === "US" ? "active" : ""} onClick={() => setMarket("US")}>美股 {usCount}</button>
          </div>
        </div>
      </section>

      {groups.length === 0 ? (
        <div className="heatmap-empty surface">
          {dataReady ? `觀察清單目前沒有${market === "TW" ? "台股" : "美股"}` : "載入中…"}
        </div>
      ) : (
        <div className="heatmap-grid" data-color-mode={market === "US" ? "us" : "tw"}>
          {groups.map((g) => (
            <section className="heat-card surface" key={g.name}>
              <header className="heat-card-head" style={{ background: heatColor(g.avg, market) }}>
                <span className="heat-card-name">{g.name}</span>
                <span className="heat-card-count dim">{g.count}</span>
                <span className={"heat-card-avg num mono " + (g.avg >= 0 ? "up" : "down")}>
                  {g.avg >= 0 ? "+" : ""}{fmt(g.avg, 2)}%
                </span>
              </header>
              <div className="heat-card-body">
                {g.stocks.map((s) => (
                  <button className="heat-cell" key={s.sym}
                    onClick={() => goChart && goChart(s.sym)}
                    style={{ background: heatColor(s.pct, market) }}
                    title={`${s.sym}　${s.name || ""}　${s.pct >= 0 ? "+" : ""}${fmt(s.pct, 2)}%`}>
                    <span className="heat-cell-name">{s.name || s.sym.replace(".TW", "")}</span>
                    <span className="heat-cell-pct num mono">{s.pct >= 0 ? "+" : ""}{fmt(s.pct, 2)}%</span>
                  </button>
                ))}
              </div>
            </section>
          ))}
        </div>
      )}
    </div>
  );
};

window.HeatmapPage = HeatmapPage;
