// Helm — 美股健檢。即時價量/估值/技術面 → GOOGLEFINANCE(後端 usStock);深度基本面 → SEC EDGAR 官方財報(本機預產 us-fundamentals.json)。
//   跟台股健檢同調:基本面為主、誠實紅黃綠燈、不可靠不給綠燈、講盲區、教材型非投資建議。刻意做成「不慫恿交易」的對照(vs 富途那種鼓勵下單的介面)。
(function () {
  const NS = window.HelmDesignSystem_9613a7;
  const { Input, Button } = NS;

  const DOT = { green: "var(--value-positive)", yellow: "var(--accent-brass)", red: "var(--value-negative)", gray: "var(--text-tertiary)" };
  const CAT_LABEL = { valuation: "貴不貴?", profit: "會賺嗎?", growth: "在長大嗎?", health: "會倒嗎?" };
  const CAT_SUB = { valuation: "估值", profit: "獲利", growth: "成長", health: "財務健康" };
  const SECTOR_ZH = {
    "Information Technology": "資訊科技", "Financials": "金融", "Health Care": "醫療保健",
    "Consumer Discretionary": "非必需消費", "Consumer Staples": "必需消費", "Communication Services": "通訊服務",
    "Industrials": "工業", "Energy": "能源", "Materials": "原物料", "Utilities": "公用事業", "Real Estate": "不動產",
  };
  function Dot({ light }) { return <span style={{ display: "inline-block", width: 11, height: 11, borderRadius: "50%", background: DOT[light] || DOT.gray, flexShrink: 0 }} />; }
  function capTxt(mc) {   // 市值白話:$X.XX 兆/十億
    if (mc == null) return "";
    if (mc >= 1e12) return "$" + (Math.round(mc / 1e11) / 10) + " 兆";
    if (mc >= 1e9) return "$" + (Math.round(mc / 1e8) / 10) + " 十億";
    if (mc >= 1e6) return "$" + (Math.round(mc / 1e5) / 10) + " 百萬";
    return "$" + Math.round(mc);
  }
  function aiParas(text) {
    return String(text || "").split(/\n+/).map(function (l) { return l.trim(); }).filter(Boolean).map(function (line, i) {
      var mm = line.match(/^【(.+?)】([\s\S]*)$/);
      if (mm) return <p key={i} className="stk-ai__sec"><b>{mm[1]}</b>{mm[2] ? " " + mm[2] : ""}</p>;
      return <p key={i} className="stk-ai__foot">{line}</p>;
    });
  }
  function estCost(u) {
    if (!u || u.in == null || u.out == null) return "";
    var nt = (u.in / 1e6 * 3 + u.out / 1e6 * 15) * 31.5;
    return nt < 0.1 ? "<NT$0.1" : "約 NT$" + (Math.round(nt * 10) / 10);
  }

  function PriceTrend({ trend }) {
    const ref = React.useRef(null);
    const chart = React.useRef(null);
    React.useEffect(function () {
      if (!ref.current || !window.Chart || !trend || trend.length < 2) return;
      const css = getComputedStyle(document.documentElement);
      const closes = trend.map(function (p) { return p.c; });
      const rising = closes[closes.length - 1] >= closes[0];
      const col = ((rising ? css.getPropertyValue("--value-negative") : css.getPropertyValue("--value-positive")) || (rising ? "#c1503b" : "#3a8a5f")).trim();
      const tert = (css.getPropertyValue("--text-tertiary") || "#9aa").trim();
      const grid = (css.getPropertyValue("--line-faint") || "rgba(0,0,0,.06)").trim();
      var crosshair = { id: "crosshair", afterDraw: function (c) {
        if (!(c.tooltip && c.tooltip._active && c.tooltip._active.length)) return;
        var x = c.tooltip._active[0].element.x, cx = c.ctx;
        cx.save(); cx.beginPath(); cx.moveTo(x, c.chartArea.top); cx.lineTo(x, c.chartArea.bottom);
        cx.lineWidth = 1; cx.strokeStyle = tert; cx.stroke(); cx.restore();
      } };
      if (chart.current) chart.current.destroy();
      chart.current = new window.Chart(ref.current, {
        type: "line", plugins: [crosshair],
        data: { labels: trend.map(function (p) { return p.d; }), datasets: [{ data: closes, borderColor: col, backgroundColor: col + "22", fill: true, tension: 0.2, pointRadius: 0, pointHoverRadius: 4, pointHoverBackgroundColor: col, borderWidth: 2 }] },
        options: {
          responsive: true, maintainAspectRatio: false,
          interaction: { mode: "index", intersect: false },
          plugins: { legend: { display: false }, tooltip: { displayColors: false, callbacks: { title: function (it) { return it && it.length ? it[0].label : ""; }, label: function (c) { return "收盤 $" + c.parsed.y; } } } },
          scales: { y: { ticks: { color: tert, maxTicksLimit: 5 }, grid: { color: grid } }, x: { ticks: { color: tert, maxTicksLimit: 5, maxRotation: 0 }, grid: { display: false } } },
        },
      });
      return function () { if (chart.current) { chart.current.destroy(); chart.current = null; } };
    }, [trend]);
    return <div className="stk-chart"><canvas ref={ref} /></div>;
  }

  function USStockScreen({ onClose, initialId }) {
    const [id, setId] = React.useState(initialId || "");
    const [busy, setBusy] = React.useState(false);
    const [res, setRes] = React.useState(null);
    const [openKey, setOpenKey] = React.useState(null);
    const [news, setNews] = React.useState(null);
    const [ai, setAi] = React.useState(null);
    const [aiBusy, setAiBusy] = React.useState(false);
    const [aiArm, setAiArm] = React.useState(false);
    const [aiErr, setAiErr] = React.useState(null);
    const scrollRef = React.useRef(null);

    function doLookup(code) {
      if (scrollRef.current) scrollRef.current.scrollTop = 0;
      setId(code); setBusy(true); setRes(null); setOpenKey(null);
      window.HelmStockData.buildUsMetrics(code).then(function (r) {
        if (!r.metrics) { setRes({ error: "查不到「" + code + "」——可能代號打錯,或它是 ETF/不在美股主板(本工具只健檢個股)。" }); }
        else { setRes({ score: window.HelmStockScore.scoreStock(r.metrics), m: r.metrics, code: code }); }
        setBusy(false);
      }).catch(function (e) {
        var msg = String((e && e.message) || e);
        if (/Failed to fetch|NetworkError|fetch/i.test(msg)) msg = "抓取資料失敗——可能網路不穩或後端忙線,請稍後再試。";
        setRes({ error: msg }); setBusy(false);
      });
    }

    function lookup(codeArg) {
      const raw = String(typeof codeArg === "string" ? codeArg : id).trim();
      if (!raw) { setRes({ error: "請輸入美股代號或名稱(例:AAPL 或 蘋果)" }); return; }
      if (scrollRef.current) scrollRef.current.scrollTop = 0;
      setBusy(true); setRes(null); setOpenKey(null);
      window.HelmStockData.usSearch(raw).then(function (matches) {
        if (!matches.length) { setBusy(false); setRes({ error: "找不到「" + raw + "」,試試美股代號(例:AAPL、MSFT)或英文名稱。" }); return; }
        if (matches.length === 1) { doLookup(matches[0].code); return; }
        setBusy(false); setRes({ choose: matches.slice(0, 8) });
      }).catch(function () { setBusy(false); doLookup(raw.toUpperCase()); });
    }

    React.useEffect(function () { if (initialId) lookup(initialId); }, []);

    React.useEffect(function () {
      setNews(null); setAi(null); setAiArm(false); setAiErr(null);
      if (res && res.m && res.code && window.HelmData && window.HelmData.stockNews) {
        window.HelmData.stockNews(res.code, res.m.name).then(function (d) { setNews(d || { items: [] }); }).catch(function () { setNews({ items: [] }); });
      }
    }, [res && res.code]);

    function runAI() {
      if (!res || !res.m || !(window.HelmData && window.HelmData.stockAI)) return;
      setAiArm(false); setAiBusy(true); setAiErr(null); setAi(null);
      var slim = Object.assign({}, res.m); delete slim.trend;
      window.HelmData.stockAI({ code: res.code, name: res.m.name, metrics: slim }).then(function (r) {
        setAiBusy(false);
        if (r && r.ok && r.data && r.data.analysis) setAi(r.data);
        else { var d = (r && r.data) || {}; setAiErr(d.error === "no_key" ? "後端尚未設定 AI 金鑰" : (r && r.error === "network") ? "網路問題,請稍後再試" : "分析失敗,請稍後再試"); }
      }).catch(function () { setAiBusy(false); setAiErr("分析失敗,請稍後再試"); });
    }

    function adviceCls(light) { return light === "red" ? "fx-advice--high" : light === "yellow" ? "fx-advice--mid" : "fx-advice--low"; }

    function report() {
      const s = res.score, m = res.m;
      const px = m.price != null ? Math.round(m.price * 100) / 100 : "—";
      const chg = m.changePct;
      const chgCol = (chg > 0) ? "var(--value-negative)" : (chg < 0) ? "var(--value-positive)" : "var(--text-secondary)";
      const chgTxt = chg == null ? "" : (chg > 0 ? "▲ " : chg < 0 ? "▼ " : "持平 ") + Math.abs(chg) + "%";
      const sectorZh = SECTOR_ZH[m.sector] || m.sector || "";
      return (
        <React.Fragment>
          {/* 標頭:名稱 + 代號 + 產業 + 市值 + 財報年度 */}
          <section className="fpage__card">
            <div className="stk-head">
              <div>
                <span className="stk-name">{m.name}</span>
                <span className="stk-code t-num">{res.code}</span>
              </div>
              <div className="stk-fresh">{m.asOf ? "財報截至 " + m.asOf + "(年報)" : "深度財報未收錄"}</div>
            </div>
            {(sectorZh || m.marketCap != null) && (
              <div className="stk-uschips">
                {sectorZh && <span className="stk-uschip"><i className="ph ph-briefcase" aria-hidden="true" /> {sectorZh}</span>}
                {m.marketCap != null && <span className="stk-uschip"><i className="ph ph-scales" aria-hidden="true" /> 市值 {capTxt(m.marketCap)}</span>}
              </div>
            )}

            <div className={"fx-advice " + adviceCls(s.overallLight)} style={{ marginTop: 12 }}>
              <span className="fx-advice__txt">{s.tag}</span>
            </div>

            <div className="stk-score">
              <span className="stk-score__num t-num" style={{ color: DOT[s.overallLight] }}>{(s.overall == null || s.suppressScore) ? "—" : s.overall}</span>
              <span className="stk-score__of">/ 100</span>
              <span className="stk-score__verdict"><Dot light={s.overallLight} /> {s.verdict}</span>
            </div>
          </section>

          {/* 未收錄深度財報:誠實告知只有估值+技術面 */}
          {!m.covered && (
            <section className="fpage__card">
              <div className="fx-advice fx-advice--mid"><span className="fx-advice__txt">⚠️ 這檔的<b>深度財報未收錄</b>(本工具主要收錄 S&P 500 + 熱門股的官方財報)。下面只有「估值 + 技術面」可看,獲利/成長/財務健康會是灰色;想看完整體質,先挑大型股試試。</span></div>
            </section>
          )}

          {/* 股價走勢 */}
          {m.trend && m.trend.length > 1 && (
            <section className="fpage__card">
              <div className="fpage__card-head"><span className="t-overline">股價走勢</span><span className="fpage__card-hint">收盤 {m.asOfPrice} · 紅漲綠跌</span></div>
              <div className="stk-px-row">
                <span className="stk-px t-num" style={{ color: chgCol }}>${px}</span>
                {chgTxt && <span className="stk-px-chg t-num" style={{ color: chgCol }}>{chgTxt}</span>}
              </div>
              <PriceTrend trend={m.trend} />
              <p className="stk-px-note">近 {m.trend.length} 個交易日收盤(美元)· 只是價格走勢、不代表未來;搭配上面的體質一起看。</p>
            </section>
          )}

          {/* 四大類紅黃綠燈 */}
          <section className="fpage__card">
            <div className="fpage__card-head"><span className="t-overline">體質四面向</span><span className="fpage__card-hint">點指標看「這是什麼」</span></div>
            <div className="stk-cats">
              {s.categories.map(function (c) {
                return (
                  <div key={c.key} className="stk-cat">
                    <div className="stk-cat__row">
                      <Dot light={c.light} />
                      <span className="stk-cat__label">{CAT_LABEL[c.key] || c.name}</span>
                      <span className="stk-cat__sub">{CAT_SUB[c.key] || ""}</span>
                      <span className="stk-cat__pct t-num">{c.pct == null ? "—" : c.pct + "%"}</span>
                    </div>
                    {c.conflict && <div className="stk-cat__conflict"><i className="ph ph-trend-down" aria-hidden="true" /> {c.conflict}</div>}
                    {c.note && !c.conflict && <div className="stk-cat__note">{c.note}</div>}
                    <div className="stk-items">
                      {c.items.map(function (it) {
                        const k = c.key + ":" + it.key, open = openKey === k;
                        return (
                          <div key={it.key} className="stk-item">
                            <button type="button" className="stk-item__btn" onClick={function () { setOpenKey(open ? null : k); }}>
                              <Dot light={it.light} />
                              <span className="stk-item__name">{it.name}</span>
                              <span className="stk-item__val">{it.verdict}</span>
                              <i className={"ph " + (open ? "ph-caret-up" : "ph-question")} aria-hidden="true" />
                            </button>
                            {open && <div className="stk-item__desc">{it.desc}</div>}
                          </div>
                        );
                      })}
                    </div>
                  </div>
                );
              })}
            </div>
            <p className="cc-note">門檻是「跨市場通用粗估」;美股估值天生比台股高(成長股尤其),別只看估值紅燈就嫌貴——配合獲利/成長一起看。獲利/成長/負債來自 <b>SEC EDGAR 官方年報</b>(每年更新一次)。</p>
          </section>

          {/* 本夢比:沒獲利/持續虧損時的教學卡(美股成長股很多是這型)*/}
          {(m.pe == null || m.persistentLoss) && (
            <section className="fpage__card">
              <div className="fpage__card-head"><span className="t-overline"><i className="ph ph-cloud" aria-hidden="true" /> 什麼是「本夢比」?</span></div>
              <p className="stk-dream">本益比(股價 ÷ 每股盈餘)是「幾年能賺回股價」。但這家公司{m.persistentLoss ? "近年是虧損的" : "目前算不出正的本益比(沒有穩定獲利)"},於是市場戲稱「<b>本夢比</b>」——買的不是「現在賺多少」,而是「未來的夢」。美股很多熱門成長股(電動車、生技、雲端 SaaS)都屬這型:夢做得成、股價海闊天空;<b>夢一旦破滅、或升息環境下,可能大幅回跌</b>。沒有獲利支撐的高價股,想像空間與風險都特別大,新手務必謹慎、用閒錢。</p>
            </section>
          )}

          {/* 技術面(分開、不計分)*/}
          {s.technical.length > 0 && (
            <section className="fpage__card">
              <div className="fpage__card-head"><span className="t-overline">技術面 · 短線時機</span><span className="fpage__card-hint">不計分 · 點 ❓ 看說明</span></div>
              {s.techSummary && <p className="stk-tech-sum"><i className="ph ph-chart-line" aria-hidden="true" /> {s.techSummary}</p>}
              <div className="stk-items">
                {s.technical.map(function (t, i) {
                  const k = "tech:" + i, open = openKey === k;
                  return (
                    <div key={i} className="stk-item">
                      <button type="button" className="stk-item__btn" onClick={function () { setOpenKey(open ? null : k); }}>
                        <Dot light={t.light} />
                        <span className="stk-item__name">{t.name}</span>
                        <span className="stk-item__val">{t.signal}</span>
                        <i className={"ph " + (open ? "ph-caret-up" : "ph-question")} aria-hidden="true" />
                      </button>
                      {t.detail && <div className="stk-tech-detail t-num">{t.detail}</div>}
                      {open && <div className="stk-item__desc">{t.desc}</div>}
                    </div>
                  );
                })}
              </div>
              <p className="cc-note">想搞懂這些指標怎麼用?到「理財工具 → <b>技術面入門</b>」有每個指標的白話講解,以及停損、部位、用閒錢等風險管理。技術面是短線時機參考、會失靈;美股無即時 KD(資料源沒給高低點),其餘照算。</p>
            </section>
          )}

          {/* 最新新聞 */}
          <section className="fpage__card">
            <div className="fpage__card-head"><span className="t-overline"><i className="ph ph-newspaper" aria-hidden="true" /> 最新新聞</span><span className="fpage__card-hint">Google 新聞</span></div>
            {news == null ? (
              <div className="fx-now"><span className="fx-now__unit">載入新聞中</span><span className="fx-now__rate">…</span></div>
            ) : (news.items && news.items.length) ? (
              <div className="stk-news">
                {news.items.map(function (it, i) {
                  return (
                    <a key={i} className="stk-news__item" href={it.link} target="_blank" rel="noopener noreferrer">
                      <span className="stk-news__title">{it.title}</span>
                      <span className="stk-news__meta">{[it.source, it.date].filter(Boolean).join(" · ")}<i className="ph ph-arrow-square-out" aria-hidden="true" /></span>
                    </a>
                  );
                })}
              </div>
            ) : (
              <p className="stk-note" style={{ marginTop: 0 }}>查無相關新聞。</p>
            )}
            <p className="cc-note">新聞由 Google 新聞彙整(中文為主),點擊外連原文。標題僅供參考、非投資建議。</p>
          </section>

          {/* AI 客觀分析 */}
          <section className="fpage__card stk-ai">
            <div className="fpage__card-head"><span className="t-overline"><i className="ph ph-sparkle" aria-hidden="true" /> AI 客觀分析</span><span className="fpage__card-hint">多空兩面 · 約 NT$0.5/次</span></div>
            {ai ? (
              <div>
                <p className="stk-note" style={{ marginTop: 0, marginBottom: 8 }}>(美股未收業務簡介,以下由 AI 補上「這家公司在做什麼 + 多空兩面」)</p>
                <div className="stk-ai__body">{aiParas(ai.analysis)}</div>
                <div className="stk-ai__bar">
                  <span className="stk-ai__cost">{ai.model === "demo" ? "展示版示範" : ("模型 Sonnet" + (estCost(ai.usage) ? " · 本次" + estCost(ai.usage) : ""))}</span>
                  <button type="button" className="stk-ai__redo" onClick={function () { setAi(null); setAiArm(true); }}>重新分析</button>
                </div>
              </div>
            ) : aiBusy ? (
              <div className="fx-now"><span className="fx-now__unit">AI 分析中(約 5–10 秒)</span><span className="fx-now__rate">…</span></div>
            ) : aiArm ? (
              <div className="stk-ai__confirm">
                <p className="stk-ai__warn">確定要分析嗎?會呼叫一次 AI、<b>花費約 NT$0.5</b>。</p>
                <div className="stk-ai__btns">
                  <button type="button" className="stk-ai__go" onClick={runAI}><i className="ph ph-check" aria-hidden="true" /> 確定分析</button>
                  <button type="button" className="stk-ai__cancel" onClick={function () { setAiArm(false); }}>取消</button>
                </div>
              </div>
            ) : (
              <div>
                {aiErr && <p className="stk-ai__warn" style={{ marginBottom: 10 }}>⚠️ {aiErr}</p>}
                <button type="button" className="stk-ai__trigger" onClick={function () { setAiArm(true); }}>
                  <i className="ph ph-sparkle" aria-hidden="true" />
                  <span className="stk-ai__trigger-l">
                    <b>用 AI 客觀解讀這檔</b>
                    <span>它在做什麼 + 多空兩面,避免好公司只因近期表現差被低估 · 點一下,約 NT$0.5</span>
                  </span>
                  <i className="ph ph-caret-right" aria-hidden="true" />
                </button>
              </div>
            )}
          </section>

          {/* 盲區 + 免責 + 資料來源 */}
          <section className="fpage__card stk-disclaim">
            <div className="fpage__card-head"><span className="t-overline"><i className="ph ph-eye-slash" aria-hidden="true" /> 這工具看不到什麼</span></div>
            {s.notes.map(function (n, i) { return <p key={i} className="stk-note">{n}</p>; })}
            <p className="stk-note">資料來源:即時股價/PE/EPS/市值 → GOOGLEFINANCE;深度財報(ROE/利潤率/成長/負債)→ <b>SEC EDGAR 美國證管會官方申報</b>,每年更新一次,故獲利/成長是「最新年報」數字、非即時。重大決定請查最新財報與公告。</p>
          </section>
        </React.Fragment>
      );
    }

    return (
      <div className="fpage" role="dialog" aria-modal="true" aria-label="美股健檢">
        <div className="fpage__panel">
          <header className="fpage__bar">
            <button className="fpage__cancel" onClick={onClose}><i className="ph ph-arrow-left" aria-hidden="true" />返回</button>
            <span className="fpage__title">美股健檢</span>
            <span aria-hidden="true" />
          </header>
          <div className="fpage__scroll" ref={scrollRef}>
            <div className="fpage__body">
              <section className="fpage__card">
                <div className="fpage__card-head"><span className="t-overline">查美股</span><span className="fpage__card-hint">代號或名稱</span></div>
                <div className="stk-search">
                  <Input placeholder="例:AAPL 或 蘋果" value={id}
                    onChange={function (e) { setId(e.target.value); }}
                    onKeyDown={function (e) { if (e.key === "Enter") lookup(); }} />
                  <Button variant="primary" onClick={function () { lookup(); }} loading={busy}>查健檢</Button>
                </div>
                <p className="prot-sum__note">用財報指標看一家美股公司的體質——<b>基本面為主、教材型、非投資建議</b>。<b>可打代號(AAPL)或中文俗名(蘋果、特斯拉)</b>。<b>第一次查某檔較慢(約 10 秒)</b>,之後就快。財報來自 SEC 官方、即時價來自 GOOGLEFINANCE。</p>
              </section>

              {busy && <section className="fpage__card"><div className="fx-now"><span className="fx-now__unit">查詢中(第一次約 10 秒)</span><span className="fx-now__rate">…</span></div></section>}
              {res && res.error && <section className="fpage__card"><div className="fx-advice fx-advice--mid"><span className="fx-advice__txt">⚠️ {res.error}</span></div></section>}
              {res && res.choose && (
                <section className="fpage__card">
                  <div className="fpage__card-head"><span className="t-overline"><i className="ph ph-list-magnifying-glass" aria-hidden="true" /> 找到多檔,請選一個</span></div>
                  <div className="stk-choose">
                    {res.choose.map(function (c) {
                      return (
                        <button key={c.code} type="button" className="stk-choose__row" onClick={function () { lookup(c.code); }}>
                          <span className="stk-choose__name">{c.name}</span>
                          <span className="stk-choose__code t-num">{c.code}</span>
                          <i className="ph ph-caret-right" aria-hidden="true" />
                        </button>
                      );
                    })}
                  </div>
                  <p className="stk-note" style={{ marginTop: 10 }}>沒看到要找的?直接打美股代號(例:AAPL)。</p>
                </section>
              )}
              {res && res.score && report()}
            </div>
          </div>
        </div>
      </div>
    );
  }

  window.USStockScreen = USStockScreen;
})();
