// Helm — 我的觀察清單。讀 HelmWatch(跨裝置同步),逐檔跑引擎顯示當前紅黃綠燈/分數,
//   依市場(台股/美股)分區塊不混在一起;台股用 buildMetrics、美股用 buildUsMetrics。
//   點開個股健檢(各自的市場)、可移除。教材型、非投資建議。
(function () {
  const DOT = { green: "var(--value-positive)", yellow: "var(--accent-brass)", red: "var(--value-negative)", gray: "var(--text-tertiary)" };
  function Dot({ light }) { return <span style={{ display: "inline-block", width: 10, height: 10, borderRadius: "50%", background: DOT[light] || DOT.gray, flexShrink: 0 }} />; }

  // 目標買價狀態:現價落在你設的「願意買的區間」哪裡(在區/低於/高於)。非買賣訊號。
  const ZONE = { in: "🟢", below: "🔵", above: "⬜" };
  function zoneOf(price, lo, hi) {
    if (price == null || (lo == null && hi == null)) return null;
    if (lo != null && hi != null) {
      if (price < lo) return { k: "below", txt: "低於買區(更便宜了)" };
      if (price > hi) return { k: "above", txt: "高於買區(等回檔)" };
      return { k: "in", txt: "在買區" };
    }
    if (hi != null) return price <= hi ? { k: "in", txt: "到目標價" } : { k: "above", txt: "高於目標(等回檔)" };
    return price >= lo ? { k: "above", txt: "高於下限" } : { k: "below", txt: "低於下限" };
  }
  function fmtTarget(it, ccy) {
    if (it.tLow == null && it.tHigh == null) return "";
    return "(" + ccy + (it.tLow != null ? it.tLow : "") + (it.tLow != null && it.tHigh != null ? "~" : (it.tHigh != null ? "以下" : "以上")) + (it.tHigh != null ? it.tHigh : "") + ")";
  }
  function TargetEditor({ it, ccy, onSave }) {
    const [lo, setLo] = React.useState(it.tLow != null ? String(it.tLow) : "");
    const [hi, setHi] = React.useState(it.tHigh != null ? String(it.tHigh) : "");
    return (
      <div className="wt-tgt__edit">
        <p className="wt-tgt__hint">趁冷靜時先想好「我願意考慮買的價位」,設了之後<b>到價會 email 通知你</b>(每天收盤後檢查一次)——<b>這是你自己設的參考價、不是買賣訊號</b>;到價也要再看體質有沒有變壞(便宜常有原因)。可只填上限。</p>
        <div className="wt-tgt__inputs">
          <span className="wt-tgt__sym">{ccy || "NT$"}</span>
          <input type="text" inputMode="decimal" placeholder="從(便宜)" value={lo} onChange={function (e) { setLo(e.target.value); }} aria-label="目標買價下限" />
          <span className="wt-tgt__tilde">~</span>
          <input type="text" inputMode="decimal" placeholder="到(貴)" value={hi} onChange={function (e) { setHi(e.target.value); }} aria-label="目標買價上限" />
        </div>
        <div className="wt-tgt__btns">
          <button type="button" className="wt-tgt__save" onClick={function () { onSave(it.code, lo, hi); }}>儲存</button>
          <button type="button" className="wt-tgt__clear" onClick={function () { onSave(it.code, "", ""); }}>清除</button>
        </div>
      </div>
    );
  }

  var _wtScroll = 0;   // 模組層:記住捲動位置,撐過 unmount(返回時還原)

  function WatchScreen({ onClose, onOpenStock }) {
    const [items, setItems] = React.useState(null);
    const [results, setResults] = React.useState({});
    const [flags, setFlags] = React.useState({});
    const [openTarget, setOpenTarget] = React.useState(null);
    const scrollRef = React.useRef(null);
    const restoredRef = React.useRef(false);
    React.useLayoutEffect(function () {
      if (!restoredRef.current && items && items.length && scrollRef.current) { scrollRef.current.scrollTop = _wtScroll; restoredRef.current = true; }
    }, [items]);

    React.useEffect(function () {
      const l = (window.HelmWatch && window.HelmWatch.list()) || [];
      setItems(l);
      // 旗標(處置/警示)只有台股有 → 只在有台股時抓
      if (l.some(function (x) { return x.market !== "us"; })) {
        window.HelmStockData.getFlags().then(function (f) { setFlags((f && f.flags) || {}); });
      }
      (function next(i) {
        if (i >= l.length) return;
        const code = l[i].code;
        const builder = (l[i].market === "us") ? window.HelmStockData.buildUsMetrics : window.HelmStockData.buildMetrics;
        setResults(function (r) { const n = Object.assign({}, r); n[code] = { loading: true }; return n; });
        builder(code).then(function (rr) {
          setResults(function (r) {
            const n = Object.assign({}, r);
            n[code] = rr.metrics ? { score: window.HelmStockScore.scoreStock(rr.metrics), m: rr.metrics } : { etf: true };
            return n;
          });
        }).catch(function (e) {
          setResults(function (r) { const n = Object.assign({}, r); n[code] = { error: String((e && e.message) || e) }; return n; });
        }).then(function () { next(i + 1); });
      })(0);
    }, []);

    function remove(code) {
      if (window.HelmWatch) window.HelmWatch.remove(code);
      setItems(function (l) { return l.filter(function (x) { return x.code !== code; }); });
    }
    function saveTarget(code, lo, hi) {
      var nlo = (lo == null || lo === "" || isNaN(Number(lo))) ? null : Number(lo);
      var nhi = (hi == null || hi === "" || isNaN(Number(hi))) ? null : Number(hi);
      if (window.HelmWatch && window.HelmWatch.setTarget) window.HelmWatch.setTarget(code, nlo, nhi);
      setItems(function (l) { return l.map(function (x) { return x.code === code ? Object.assign({}, x, { tLow: nlo, tHigh: nhi }) : x; }); });
      setOpenTarget(null);
    }
    function sub(r) {
      if (!r || r.loading) return "查詢中…";
      if (r.error) return "查詢失敗(可能網路或限流,稍後再開)";
      if (r.etf) return "ETF / 無個股財報";
      if (r.score) return r.score.tag;
      return "—";
    }

    function rowOf(it) {
      const r = results[it.code] || { loading: true };
      const light = r.score ? r.score.overallLight : "gray";
      const fl = it.market === "us" ? null : flags[it.code];
      const ccy = it.market === "us" ? "$" : "";
      const price = r.m && r.m.price != null ? r.m.price : null;
      const z = zoneOf(price, it.tLow, it.tHigh);
      const editing = openTarget === it.code;
      return (
        <div key={it.code} className="wt-row">
          <div className="wt-row__top">
            <button type="button" className="wt-row__main" onClick={function () { onOpenStock(it.code, it.market); }}>
              <Dot light={light} />
              <span className="wt-row__l">
                <span className="wt-row__name">{it.name}<span className="wt-row__code t-num">{it.code}</span>{fl && <span className="wt-row__flag">⚠️ {fl.kinds[0]}</span>}</span>
                <span className="wt-row__sub">{sub(r)}</span>
              </span>
              <span className="wt-row__r">
                <span className="wt-row__price t-num" style={{ color: (r.m && r.m.changePct > 0) ? "var(--value-negative)" : (r.m && r.m.changePct < 0) ? "var(--value-positive)" : "var(--text-secondary)" }}>{price != null ? ccy + (Math.round(price * 100) / 100) : ""}</span>
                <span className="wt-row__score t-num" style={{ color: DOT[light] }}>{r.score ? ((r.score.overall == null || r.score.suppressScore) ? "—" : r.score.overall) : (r.loading ? "…" : "—")}</span>
              </span>
            </button>
            <button type="button" className="wt-row__del" onClick={function () { remove(it.code); }} aria-label="移除觀察"><i className="ph ph-x" aria-hidden="true" /></button>
          </div>
          <div className="wt-tgt">
            <button type="button" className="wt-tgt__toggle" onClick={function () { setOpenTarget(editing ? null : it.code); }} aria-expanded={editing}>
              <i className="ph ph-target" aria-hidden="true" /> 目標買價
              {z ? <span className={"wt-zone wt-zone--" + z.k}>{ZONE[z.k]} {z.txt} {fmtTarget(it, ccy)}</span> : <span className="wt-tgt__unset">未設定 · 點此設你願意的買價</span>}
              <i className={"ph " + (editing ? "ph-caret-up" : "ph-caret-down")} aria-hidden="true" style={{ marginLeft: "auto" }} />
            </button>
            {editing && <TargetEditor it={it} ccy={ccy} onSave={saveTarget} />}
          </div>
        </div>
      );
    }

    const tw = (items || []).filter(function (x) { return x.market !== "us"; });
    const us = (items || []).filter(function (x) { return x.market === "us"; });

    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} onScroll={function (e) { _wtScroll = e.currentTarget.scrollTop; }}>
            <div className="fpage__body">
              <section className="fpage__card">
                <p className="prot-sum__note">你加入觀察的股票,每次打開重新算當前體質——<b>跨裝置同步、台股 / 美股分開、教材型、非投資建議</b>。點任一檔看完整健檢。</p>
              </section>

              {items && items.length === 0 && (
                <section className="fpage__card">
                  <div className="wt-empty">
                    <i className="ph ph-binoculars" aria-hidden="true" />
                    <p>還沒有觀察的股票。</p>
                    <span>在「個股健檢」(台股或美股)查一檔後點<b>「加入觀察清單」</b>,或從「流派觀察名單」挑幾檔開始追蹤。</span>
                  </div>
                </section>
              )}

              {tw.length > 0 && (
                <section className="fpage__card">
                  <div className="fpage__card-head"><span className="t-overline"><i className="ph ph-flag" aria-hidden="true" /> 台股 · {tw.length} 檔</span></div>
                  <div className="wt-list">{tw.map(rowOf)}</div>
                </section>
              )}

              {us.length > 0 && (
                <section className="fpage__card">
                  <div className="fpage__card-head"><span className="t-overline"><i className="ph ph-globe-hemisphere-west" aria-hidden="true" /> 美股 · {us.length} 檔</span></div>
                  <div className="wt-list">{us.map(rowOf)}</div>
                </section>
              )}

              <section className="fpage__card stk-disclaim">
                <p className="stk-note">分數與紅黃綠燈是規則引擎的基本面健檢(同「個股健檢」),<b>不構成投資建議</b>。觀察清單的用途是讓你長期追蹤、熟悉不同股票的體質變化,慢慢找到適合自己的流派。</p>
              </section>
            </div>
          </div>
        </div>
      </div>
    );
  }

  window.WatchScreen = WatchScreen;
})();
