// 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 peerCmp(v, med) {   // 毛利/營益/ROE:高=好(跟同業比才有意義)
    if (v == null || med == null || med === 0) return "";
    var r = v / med;
    return r >= 1.15 ? "比同業高" : r <= 0.85 ? "比同業低" : "和同業相當";
  }
  function peBucket(pe) {   // 本益比白話分級(機械規則,非預測)
    if (pe == null) return "";
    if (pe < 15) return "<15 → 市場期待低(可能是穩定成熟、也可能在衰退)";
    if (pe < 25) return "15~25 → 一般水位";
    if (pe < 40) return "25~40 → 市場給它成長溢價";
    return ">40 → 高度成長期待(成長一熄火很容易修正)";
  }
  function capBucket(mc) {   // 市值規模白話分級(美元)
    if (mc == null) return null;
    if (mc >= 2e11) return { tier: "超大型權值股", note: "通常較穩、波動相對小,但也較難再翻倍成長。" };
    if (mc >= 1e10) return { tier: "大型股", note: "規模成熟、資訊較多,波動通常介於中間。" };
    return { tier: "中小型股", note: "波動大、資訊少,新手風險高。" };
  }
  // 共用:白話提醒框(沿用既有 stk-note 字級,inline 包一層淡底)
  function NoteBox({ children, style }) {
    return <div className="stk-note" style={Object.assign({ marginTop: 10, padding: "10px 12px", borderRadius: 10, background: "var(--surface-sunken, rgba(0,0,0,.03))", border: "1px solid var(--line-faint, rgba(0,0,0,.06))" }, style || {})}>{children}</div>;
  }
  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>;
  }

  // 美股回測:「如果早幾年買?」(Yahoo 月線 adjusted close=含息總報酬,對照 S&P 500;教材、非投資建議;美股無歷史本益比→不做估值位階)
  function usMoney(n) { return "$" + Math.round(n || 0).toLocaleString("en-US"); }
  function btUsHonest(r) {
    var s = r.stock, b = r.bench, parts = [];
    parts.push("這個回測只算得出『現在還在、查得到』的股;下市、被購併、爆雷下市的公司不會出現在這裡,所以個股回測天生偏向『活下來的贏家』,別當成『長期持有都會賺』。");
    if (b) parts.push(s.ret > b.ret
      ? "就算這檔過去贏了 S&P 500,你當年也無法事先知道是它——事後挑贏家容易、事前難;多數個股、連多數專業基金經理人長期都贏不了 S&P 500。"
      : "這檔同期還輸給 S&P 500;長期能贏大盤的個股與基金都是少數,『買大盤指數(如 S&P 500 ETF)』對多數人反而更實際。");
    parts.push("報酬是過去、不預測未來。真要進場,『分批 / 定期定額』本來就是不用賭單一時點的通用做法。這裡是教材、幫你看懂數字,不是叫你買這一檔。");
    return parts.join(" ");
  }
  function UsBacktest({ code }) {
    const B = window.HelmBacktest;
    const [open, setOpen] = React.useState(false);
    const [data, setData] = React.useState(null);
    const [err, setErr] = React.useState(null);
    const [loading, setLoading] = React.useState(false);
    const [years, setYears] = React.useState(10);
    const [mode, setMode] = React.useState("dca");
    const [amt, setAmt] = React.useState("500");
    React.useEffect(function () { setData(null); setErr(null); setOpen(false); }, [code]);
    function load() {
      if (data || loading || !(window.HelmStockData && window.HelmStockData.getUsBacktest)) return;
      setLoading(true); setErr(null);
      window.HelmStockData.getUsBacktest(code).then(function (d) {
        setLoading(false);
        if (!d || !d.ok) { setErr("這檔歷史資料太少(可能上市不久)或抓取失敗,無法回測。"); return; }
        setData(d);
      }).catch(function (e) { setLoading(false); setErr(String((e && e.message) || e)); });
    }
    function toggle() { var n = !open; setOpen(n); if (n) load(); }

    var result = null;
    if (data && B && data.prices.length) {
      var last = data.prices[data.prices.length - 1].date;
      var startDate = (Number(last.slice(0, 4)) - years) + last.slice(4);
      var rawAmt = B.num(amt); var input = rawAmt > 0 ? rawAmt : (mode === "dca" ? 500 : 10000);
      var run = mode === "dca" ? B.dca : B.lump;
      var stock = run(data.prices, input, startDate);
      if (stock) {
        result = { stock: stock, bench: run(data.bench, input, startDate), benchIsSelf: data.benchIsSelf,
          yrs: Math.round(B.monthsBetween(stock.startDate, last) / 12 * 10) / 10 };
      }
    }
    return (
      <section className="fpage__card">
        <button type="button" className="stk-bt__head" onClick={toggle} aria-expanded={open}>
          <span className="t-overline"><i className="ph ph-clock-counter-clockwise" aria-hidden="true" /> 如果早幾年買?(回測)</span>
          <i className={"ph " + (open ? "ph-caret-up" : "ph-caret-down")} aria-hidden="true" />
        </button>
        {open && (
          <div className="stk-bt">
            {loading && <div className="fx-now"><span className="fx-now__unit">抓 10 年歷史中</span><span className="fx-now__rate">…</span></div>}
            {err && <div className="fx-advice fx-advice--mid"><span className="fx-advice__txt">⚠️ {err}</span></div>}
            {result && (
              <div>
                <div className="stk-bt__segs">
                  {[1, 3, 5, 10].map(function (y) { var dis = data.availYears >= 2 && y > data.availYears; return <button key={y} type="button" disabled={dis} aria-pressed={years === y} className={"stk-bt__seg" + (years === y ? " is-on" : "")} onClick={function () { setYears(y); }}>{y} 年前</button>; })}
                </div>
                <div className="stk-bt__segs">
                  <button type="button" aria-pressed={mode === "dca"} className={"stk-bt__seg" + (mode === "dca" ? " is-on" : "")} onClick={function () { setMode("dca"); }}>定期定額 / 月</button>
                  <button type="button" aria-pressed={mode === "lump"} className={"stk-bt__seg" + (mode === "lump" ? " is-on" : "")} onClick={function () { setMode("lump"); }}>一次買進</button>
                </div>
                <div className="stk-bt__in"><span className="stk-bt__sym">US$</span><input type="text" inputMode="numeric" aria-label={mode === "dca" ? "每月投入金額" : "一次投入金額"} value={amt} onChange={function (e) { setAmt(e.target.value); }} /><span className="stk-bt__inhint">{mode === "dca" ? "每月投入" : "一次投入"}</span></div>

                <div className="fx-now"><span className="fx-now__unit">投入 {usMoney(result.stock.invested)}({result.yrs} 年)→ 現在約</span><span className={"fx-now__rate t-num " + (result.stock.profit >= 0 ? "fx-pl--up" : "fx-pl--down")}>{usMoney(result.stock.value)}</span></div>
                <p className="stk-bt__caveat">這是<b>過去 {result.yrs} 年的歷史結果、不是預測</b>,未來不會照抄、也不能重來。{result.yrs < years - 0.4 ? "(這檔只有 " + result.yrs + " 年資料,已用全部歷史)" : ""}</p>
                <div className="stk-bt__rows">
                  <div className="tax-row"><span>總報酬(含息)</span><b className={result.stock.ret >= 0 ? "fx-pl--up" : "fx-pl--down"}>{result.stock.ret >= 0 ? "+" : ""}{(result.stock.ret * 100).toFixed(0)}%</b></div>
                  {mode === "lump" && result.stock.cagr != null && <div className="tax-row"><span>年化報酬</span><b className="t-num">{(result.stock.cagr * 100).toFixed(1)}%</b></div>}
                  {result.bench && <div className="tax-row"><span>同期 S&amp;P 500(SPY,同方式)</span><b className={result.bench.ret >= 0 ? "fx-pl--up" : "fx-pl--down"}>{result.bench.ret >= 0 ? "+" : ""}{(result.bench.ret * 100).toFixed(0)}%</b></div>}
                </div>
                <p className="stk-bt__cap">股價用 <b>adjusted close(已還原股息+拆分)</b>,屬<b>含息總報酬</b>;跟 S&amp;P 500 同口徑(都含息)對照,公平。</p>
                <div className="fx-advice fx-advice--mid"><span className="fx-advice__tag">💡 誠實</span><span className="fx-advice__txt">{btUsHonest(result)}</span></div>
                <p className="stk-note">回測=「如果當時這樣做」的歷史結果,<b>過去績效不代表未來</b>。月線來自 Yahoo Finance(adjusted close)。<b>美股沒有歷史本益比資料,所以這裡只比報酬、不做估值位階</b>。教材、非投資建議。</p>
              </div>
            )}
          </div>
        )}
      </section>
    );
  }

  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]);

    const [watched, setWatched] = React.useState(false);
    React.useEffect(function () { setWatched(!!(res && res.code && window.HelmWatch && window.HelmWatch.has(res.code))); }, [res && res.code]);
    function toggleWatch() {
      if (!(res && res.code && res.m && window.HelmWatch)) return;
      if (watched) { window.HelmWatch.remove(res.code); setWatched(false); }
      else { window.HelmWatch.add(res.code, res.m.name, "us"); setWatched(true); }
    }

    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>
            )}
            {m.marketCap != null && (function () {
              var cb = capBucket(m.marketCap);
              return cb ? <div className="stk-note" style={{ marginTop: 6 }}><b>{cb.tier}</b>:{cb.note}</div> : null;
            })()}

            <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>

            <button type="button" className={"stk-watch" + (watched ? " stk-watch--on" : "")} onClick={toggleWatch}>
              <i className={"ph " + (watched ? "ph-check-circle" : "ph-plus-circle")} aria-hidden="true" />
              {watched ? "已在觀察清單" : "加入觀察清單"}
            </button>
          </section>

          {/* 未收錄深度財報:誠實告知只有估值+技術面 */}
          {!m.covered && (
            <section className="fpage__card">
              <div className="fx-advice fx-advice--mid"><span className="fx-advice__txt">⚠️ 這檔<b>沒有 SEC 標準年報(10-K)的深度財報</b>,所以下面的「獲利 / 成長 / 財務健康」會是灰色;但<b>即時股價、本益比、技術面、回測都正常</b>。常見兩種原因:① 它是<b>外國公司在美國掛的 ADR</b>(像台積電 TSM、ASML、Novo 這種用 IFRS 申報的,SEC 沒有它的標準 XBRL 財報);② 較冷門、不在收錄範圍的中小型美股。<br /><b>💡 小撇步:如果這家公司台股也有掛牌(例:台積電 → 用「台股健檢」查 2330),直接查它的台股代號,財報體質完整得多——TSM 只是它的美股存託憑證。</b></span></div>
            </section>
          )}
          {m.covered && m.foreign && (
            <section className="fpage__card">
              <div className="fx-advice fx-advice--mid"><span className="fx-advice__txt">ℹ️ 這是<b>外國公司的美股 ADR</b>(多以國際會計準則 IFRS 申報、財報用原始幣別如歐元/日圓)。下面的 <b>ROE、毛利、成長、負債都是正確比率</b>(這些比率跟幣別無關);但<b>殖利率因涉及財報幣別 / ADR 換股比例,未計算</b>(顯示 —)。若這家公司台股也有掛牌(例:台積電 → 用「台股健檢」查 <b>2330</b>),那邊的財報與殖利率更完整。</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} />
              {m.hi52 != null && m.lo52 != null && m.hi52 > m.lo52 && m.price != null && (function () {
                var pos = Math.max(0, Math.min(100, Math.round((m.price - m.lo52) / (m.hi52 - m.lo52) * 100)));
                var high = m.fromHigh != null && m.fromHigh >= -3;
                var zone = high ? "接近 52 週高點" : pos <= 25 ? "靠近 52 週低區" : pos >= 75 ? "52 週高區" : "52 週區間中段";
                var note = high ? "創新高附近——別只因為「一直漲」就覺得穩,追高萬一回檔會套。" : pos <= 25 ? "便宜可能有原因,先看下面體質會不會倒。" : "";
                return <div className="stk-px-pos"><b>52 週位階:約第 {pos} 百分位 · {zone}</b>{note ? " — " + note : ""}<div className="stk-px-pos__sub">這只是價格在過去一年的相對位置,不是「貴/便宜」的估值判斷(美股沒有自己的歷史本益比資料,做不到像台股那樣的估值位階)。</div></div>;
              })()}
              <p className="stk-px-note">近 {m.trend.length} 個交易日收盤(美元)· 只是價格走勢、不代表未來;搭配上面的體質一起看。</p>
            </section>
          )}

          {/* 這家公司是什麼來頭(AI 側寫;美股沒收錄就交給下面 AI 客觀分析補)*/}
          {m.profile && (
            <section className="fpage__card stk-prof">
              <div className="fpage__card-head"><span className="t-overline"><i className="ph ph-buildings" aria-hidden="true" /> 這家公司是什麼來頭</span></div>
              {m.profile.tags && m.profile.tags.length > 0 && (
                <div className="stk-prof__tags">{m.profile.tags.map(function (t, i) { return <span key={i} className="stk-prof__tag">{t}</span>; })}</div>
              )}
              <p className="stk-biz">{m.profile.biz}</p>
              {m.profile.founded && <p className="stk-prof__line"><i className="ph ph-flag" aria-hidden="true" /> <b>成立</b>{m.profile.founded}</p>}
              {m.profile.style && <p className="stk-prof__line"><i className="ph ph-user-focus" aria-hidden="true" /> <b>經營風格</b>{m.profile.style}</p>}
              {m.profile.edge && <p className="stk-prof__line stk-prof__edge"><i className="ph ph-shield-star" aria-hidden="true" /> <b>跟同業的差別</b>{m.profile.edge}</p>}
              <p className="stk-prof__line"><i className="ph ph-warning" aria-hidden="true" /> <b>要留意</b>{m.profile.risk ? m.profile.risk : "健檢只看得到過去的財報數字。最大的風險常常是「估值已經反映了很高的成長期待」、景氣循環、或過度依賴單一產品/客戶——這些一定要自己另外查公司新聞。"}</p>
              <p className="cc-note">公司側寫由 AI 整理、聚焦「跟同類公司的差異」幫你挑股有頭緒;為求精簡可能簡化,年份/數字請以公司官方資料為準、非投資建議。</p>
            </section>
          )}

          {/* 四大類紅黃綠燈 */}
          <section className="fpage__card">
            <div className="fpage__card-head"><span className="t-overline">體質四面向</span><span className="fpage__card-hint">點指標看「這是什麼」</span></div>
            <NoteBox style={{ marginTop: 0, marginBottom: 12 }}><b>看法:</b>先看「<b>會賺嗎 / 在長大嗎 / 會倒嗎</b>」這三格判斷它是不是好公司,再單獨看「<b>貴不貴</b>」決定現在是不是好價位——好公司可能很貴、爛公司可能很便宜,這兩件事要分開看。</NoteBox>
            <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>
                    {c.key === "valuation" && (
                      <React.Fragment>
                        {/* 估值「貴不貴?」白話框 — 帶實際 PE(m.pe 存在;沒有則純文字) */}
                        <NoteBox>
                          <b><i className="ph ph-question" aria-hidden="true" /> 這個本益比算貴嗎?</b>
                          <div style={{ marginTop: 4 }}>美股本益比沒有絕對好壞——公司成長越快、市場越願意付越高倍數。{m.pe != null ? <span>這檔現在約 <b>{Math.round(m.pe * 10) / 10} 倍</b>。</span> : <span>(這檔目前算不出正的本益比,沒有穩定獲利。)</span>}</div>
                          <div style={{ marginTop: 4 }}>粗略看:<b>&lt;15</b>=市場期待低(可能穩定、也可能在衰退)、<b>15~25</b>=一般、<b>25~40</b>=市場給它成長溢價、<b>&gt;40</b>=高度成長期待(成長一熄火很容易修正)。{m.pe != null && <span> 這檔落在「{peBucket(m.pe)}」。</span>}</div>
                          <div style={{ marginTop: 4 }}>跟<b>同類股</b>比,會比單看一個數字準。</div>
                        </NoteBox>
                        {/* 殖利率白話(美股少配息不等於體質差) */}
                        <NoteBox>
                          <b><i className="ph ph-coins" aria-hidden="true" /> 殖利率低 ≠ 體質差</b>
                          <div style={{ marginTop: 4 }}>美股很多好公司刻意少配息或不配息,把錢拿去<b>庫藏股回購</b>或<b>再投資成長</b>,殖利率低不代表不好——這跟台股「存股領息」玩法不同。重點是看它是「<b>成長型</b>(靠股價漲)」還是「<b>收息型</b>(靠配息)」,兩種期待不一樣。</div>
                        </NoteBox>
                      </React.Fragment>
                    )}
                  </div>
                );
              })}
            </div>
            <p className="cc-note">門檻是「跨市場通用粗估」;美股估值天生比台股高(成長股尤其),別只看估值紅燈就嫌貴——配合獲利/成長一起看。獲利/成長/負債來自 <b>SEC EDGAR 官方年報</b>(每年更新一次)。</p>
          </section>

          {/* 同業比較:本檔 vs 同 GICS 類股中位數(毛利/營益/ROE)+ 知名同業(點看健檢)*/}
          {m.sectorStats && (
            <section className="fpage__card">
              <div className="fpage__card-head"><span className="t-overline"><i className="ph ph-scales" aria-hidden="true" /> 同業比較 · {m.sectorStats.zh}</span><span className="fpage__card-hint">類股中位數</span></div>
              <div className="stk-peer">
                {[["毛利率", "gross", "medGross"], ["營業利益率", "opm", "medOpm"], ["ROE", "roe", "medRoe"]].map(function (row) {
                  var mv = m[row[1]], med = m.sectorStats[row[2]], read = peerCmp(mv, med);
                  return (
                    <div key={row[1]} className="stk-peer__row">
                      <span className="stk-peer__label">{row[0]}</span>
                      <span className="stk-peer__mine t-num">{mv == null ? "—" : mv + "%"}</span>
                      <span className="stk-peer__med t-num">同業 {med == null ? "—" : med + "%"}</span>
                      <span className="stk-peer__read">{read}</span>
                    </div>
                  );
                })}
              </div>
              {m.sectorStats.peers && m.sectorStats.peers.length > 0 && (
                <div className="stk-peers">
                  <span className="stk-peers__lbl">同類股(點看健檢)</span>
                  {m.sectorStats.peers.map(function (p) {
                    return <button key={p.code} type="button" className="stk-peer-chip" onClick={function () { lookup(p.code); }}>{p.code}</button>;
                  })}
                </div>
              )}
              <NoteBox style={{ marginBottom: 0 }}>估值(<b>本益比/股價淨值比</b>)這裡<b>沒有同業中位數可比</b>,請用上面那個「這個本益比算貴嗎?」白話框,自己拿它跟同類幾檔(下面那排同類股)比一比。</NoteBox>
              <p className="cc-note">毛利率/營益率/ROE「只能同業比」——這裡跟同 {m.sectorStats.zh} 類股約 {m.sectorStats.n} 檔的中位數比。同業取營收較大的代表公司。非投資建議。</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>
          )}

          {/* 景氣循環股(能源/原物料):誠實說沒有多年 EPS 位階,別被當下低 PE 騙 */}
          {m.cyclical && (
            <section className="fpage__card">
              <div className="fpage__card-head"><span className="t-overline"><i className="ph ph-arrows-clockwise" aria-hidden="true" /> 景氣循環股提醒</span></div>
              <p className="stk-dream">這是<b>景氣循環產業(能源/原物料)</b>,獲利隨油價/報價大起大落。本工具<b>沒有這檔的多年 EPS 軌跡</b>,所以當下看起來的低本益比,可能正好是循環高峰的「<b>假便宜</b>」——別只看一個當下數字。要判斷位階,得自己另外查它過去幾年的 EPS 走勢與產業供需(運價/報價/庫存)。</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>}
              <NoteBox style={{ marginTop: 0, marginBottom: 12 }}>
                {m.rsi != null && <div><b>RSI(14)約 {m.rsi}:</b>{m.rsi > 70 ? "短線可能漲過頭、留意回檔" : m.rsi < 30 ? "短線可能跌過頭(超賣)" : "中性區間"}。⚠️ 強勢股 RSI 會長期停在高檔「鈍化」,別把它當必買必賣訊號。</div>}
                {m.ret1y != null && <div style={{ marginTop: m.rsi != null ? 4 : 0 }}><b>近一年報酬約 {m.ret1y > 0 ? "+" : ""}{m.ret1y}%:</b>過去一年{m.ret1y >= 0 ? "漲" : "跌"}了這麼多,只是<b>回顧、不是預測未來</b>,拿來看現在站在什麼位階就好。</div>}
              </NoteBox>
              <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>

          {res.code && <UsBacktest code={res.code} />}

          {/* 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>
                {!m.profile && <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;
})();
