// Helm — 換匯參考(USD + JPY 近一年區間 + 台銀買賣牌價 + 富邦小抄)+ 定期定額換匯追蹤。
//   趨勢圖支援手指點觸看日期/價格(index 模式 + 十字準星)。
(function () {
  const NS = window.HelmDesignSystem_9613a7;
  const { Field, Input, Button } = NS;

  function fmt(n) { return Math.round(n).toLocaleString("en-US"); }
  function r2(n) { return Number(n).toLocaleString("en-US", { maximumFractionDigits: 2 }); }
  function rate(n) { if (n == null || n === "") return "—"; n = Number(n); return n < 1 ? n.toFixed(4) : n.toFixed(3); }   // JPY 4 位、USD 3 位

  function FxTrend({ series, mean, dec }) {
    const ref = React.useRef(null);
    const chart = React.useRef(null);
    React.useEffect(function () {
      if (!ref.current || !window.Chart || !series || !series.length) return;
      const css = getComputedStyle(document.documentElement);
      const brass = (css.getPropertyValue("--accent-brass") || "#cbac74").trim();
      const tert = (css.getPropertyValue("--text-tertiary") || "#9aa").trim();
      const grid = (css.getPropertyValue("--line-faint") || "rgba(0,0,0,.06)").trim();
      const decimals = dec || 3;
      if (chart.current) chart.current.destroy();
      const labels = series.map(function (p) { return p.d; });
      const ds = [{ data: series.map(function (p) { return p.v; }), borderColor: brass, backgroundColor: brass + "22", fill: true, tension: 0.25, pointRadius: 0, borderWidth: 2 }];
      if (mean) ds.push({ data: labels.map(function () { return mean; }), borderColor: tert, borderDash: [4, 4], pointRadius: 0, borderWidth: 1, fill: false });
      // 手指點/移動 → index 模式抓最近點顯示 tooltip + 畫垂直準星線
      const crosshair = {
        id: "fxcrosshair",
        afterDraw: function (c) {
          if (c.tooltip && c.tooltip._active && c.tooltip._active.length) {
            const x = c.tooltip._active[0].element.x; const ctx = c.ctx;
            ctx.save(); ctx.beginPath(); ctx.moveTo(x, c.chartArea.top); ctx.lineTo(x, c.chartArea.bottom);
            ctx.lineWidth = 1; ctx.strokeStyle = brass + "88"; ctx.stroke(); ctx.restore();
          }
        },
      };
      chart.current = new window.Chart(ref.current, {
        type: "line",
        data: { labels: labels, datasets: ds },
        options: {
          responsive: true, maintainAspectRatio: false,
          interaction: { mode: "index", intersect: false },
          plugins: {
            legend: { display: false },
            tooltip: {
              mode: "index", intersect: false, displayColors: false,
              callbacks: {
                title: function (it) { return it && it[0] ? it[0].label : ""; },
                label: function (c) { return "NT$ " + c.parsed.y.toFixed(decimals); },
              },
            },
          },
          scales: {
            y: { ticks: { color: tert, maxTicksLimit: 5, callback: function (v) { return v.toFixed(decimals <= 3 ? 1 : 3); } }, grid: { color: grid } },
            x: { ticks: { color: tert, maxTicksLimit: 6, maxRotation: 0 }, grid: { display: false } },
          },
        },
        plugins: [crosshair],
      });
      return function () { if (chart.current) { chart.current.destroy(); chart.current = null; } };
    }, [series, mean, dec]);
    return <div className="ov-trendchart" style={{ height: 140 }}><canvas ref={ref} /></div>;
  }

  // 台銀買賣牌價(現金/即期 買入賣出)
  function FxBidAsk({ r }) {
    if (!r || (!r.spotBuy && !r.spotSell)) return null;
    return (
      <div className="fx-ba">
        <div className="fx-ba__hd">台銀牌告買賣</div>
        <div className="fx-ba__grid">
          <div className="fx-ba__cell"><span className="fx-ba__lbl">即期買入</span><b className="t-num">{rate(r.spotBuy)}</b><span className="fx-ba__hint">你換回台幣</span></div>
          <div className="fx-ba__cell fx-ba__cell--ask"><span className="fx-ba__lbl">即期賣出</span><b className="t-num">{rate(r.spotSell)}</b><span className="fx-ba__hint">你買外幣付</span></div>
          <div className="fx-ba__cell"><span className="fx-ba__lbl">現金買入</span><b className="t-num">{rate(r.cashBuy)}</b></div>
          <div className="fx-ba__cell"><span className="fx-ba__lbl">現金賣出</span><b className="t-num">{rate(r.cashSell)}</b></div>
        </div>
        <p className="fx-ba__note">即期=線上/帳戶換匯(價差小、最常用);現金=換實體鈔票(價差大)。「賣出」是你拿台幣買外幣要付的價。</p>
      </div>
    );
  }

  // 通用報價區塊(現價 + 趨勢 + 區間/百分位 + 買賣)
  function FxQuote({ data, perLabel, headNote }) {
    if (!data) return <p className="fx-empty">匯率載入中(或暫時抓不到)。</p>;
    const dec = data.current && data.current < 1 ? 4 : 3;
    var pctile = (data.pct != null) ? data.pct : (data.high52 > data.low52 ? Math.round((data.current - data.low52) / (data.high52 - data.low52) * 100) : null);
    var zone = "", zoneClass = "mid", advice = "";
    if (pctile != null) {
      if (pctile <= 33) { zone = "偏低(便宜)"; zoneClass = "low"; advice = "現在相對便宜 —— 照計畫換,手頭有閒錢可以多換一點。"; }
      else if (pctile >= 67) { zone = "偏高(貴)"; zoneClass = "high"; advice = "現在相對貴 —— 換你的基本定期定額量就好,別加碼。"; }
      else { zone = "中間"; zoneClass = "mid"; advice = "落在中間 —— 照定期定額金額換就好,不用猜時機。"; }
    }
    return (
      <div>
        <div className="fx-now"><span className="fx-now__unit">{perLabel}</span><span className="fx-now__rate t-num">NT$ {rate(data.current)}</span></div>
        {headNote && <p className="fx-100yen">{headNote}</p>}
        {data.series && data.series.length > 1 && <FxTrend series={data.series} mean={data.mean} dec={dec} />}
        {data.low52 > 0 && (
          <div className="fx-stats">
            <span>一年均價 <b className="t-num">{rate(data.mean || 0)}</b></span>
            <span>區間 <b className="t-num">{rate(data.low52)}–{rate(data.high52)}</b></span>
            {pctile != null && <span className={"fx-zone fx-zone--" + zoneClass}>第 {pctile} 百分位 · {zone}</span>}
          </div>
        )}
        <FxBidAsk r={data} />
        {advice && (
          <div className={"fx-advice fx-advice--" + zoneClass}>
            <span className="fx-advice__tag">💡 這次建議</span>
            <span className="fx-advice__txt">{advice}</span>
          </div>
        )}
      </div>
    );
  }

  // 換多少計算機 + 價差透明:用既有台銀買賣牌價算實拿,並誠實顯示銀行從「買賣價差」賺走多少(=半個 bid-ask、單程換匯成本)
  function FxCalc({ data, unit, sym }) {
    const [amt, setAmt] = React.useState("");
    const [dir, setDir] = React.useState("buy");      // buy=台幣換外幣;sell=外幣換台幣
    const [chan, setChan] = React.useState("spot");   // spot=即期;cash=現金
    if (!data || data.spotSell == null || data.spotBuy == null) return null;
    const A = parseFloat(String(amt).replace(/,/g, "")) || 0;
    const mid = (Number(data.spotBuy) + Number(data.spotSell)) / 2;        // 中間價(買賣均值)
    const cashSell = data.cashSell != null ? Number(data.cashSell) : Number(data.spotSell);
    const cashBuy = data.cashBuy != null ? Number(data.cashBuy) : Number(data.spotBuy);
    const sellRate = chan === "spot" ? Number(data.spotSell) : cashSell;   // 你買外幣付的價
    const buyRate = chan === "spot" ? Number(data.spotBuy) : cashBuy;      // 你賣外幣拿的價
    let result, used, cost, fromSym, toSym;
    if (dir === "buy") {            // 台幣 A → 外幣
      used = sellRate; result = used > 0 ? A / used : 0;
      cost = (A > 0 && used > 0) ? A * (used - mid) / used : 0;            // 比中間價多付的台幣
      fromSym = "NT$"; toSym = sym;
    } else {                        // 外幣 A → 台幣
      used = buyRate; result = A * used;
      cost = (A > 0) ? A * (mid - buyRate) : 0;                            // 比中間價少拿的台幣
      fromSym = sym; toSym = "NT$";
    }
    // 換現金 vs 即期,多花多少
    let cashExtra = 0;
    if (chan === "cash" && A > 0) {
      if (dir === "buy") cashExtra = (Number(data.spotSell) > 0 && cashSell > 0) ? (A / Number(data.spotSell) - A / cashSell) : 0;   // 少拿的外幣
      else cashExtra = A * (Number(data.spotBuy) - cashBuy);                                                                          // 少拿的台幣
    }
    return (
      <div className="fx-calc">
        <div className="fx-calc__h"><i className="ph ph-calculator" aria-hidden="true" /> 換多少?(算實拿 + 價差成本)</div>
        <div className="fx-calc__seg" role="tablist">
          <button type="button" className={"fx-calc__btn" + (dir === "buy" ? " is-on" : "")} onClick={function () { setDir("buy"); }}>台幣 → {unit}</button>
          <button type="button" className={"fx-calc__btn" + (dir === "sell" ? " is-on" : "")} onClick={function () { setDir("sell"); }}>{unit} → 台幣</button>
        </div>
        <div className="fx-calc__in">
          <span className="fx-calc__sym">{fromSym}</span>
          <input type="text" inputMode="decimal" className="fx-calc__amt" placeholder={"輸入" + (dir === "buy" ? "台幣" : unit) + "金額"} value={amt} onChange={function (e) { setAmt(e.target.value); }} />
        </div>
        <div className="fx-calc__seg fx-calc__seg--sm" role="tablist">
          <button type="button" className={"fx-calc__btn" + (chan === "spot" ? " is-on" : "")} onClick={function () { setChan("spot"); }}>即期(線上)</button>
          <button type="button" className={"fx-calc__btn" + (chan === "cash" ? " is-on" : "")} onClick={function () { setChan("cash"); }}>現金(鈔票)</button>
        </div>
        {A > 0 ? (
          <div className="fx-calc__out">
            <div className="fx-calc__res"><span>換得約</span><b className="t-num">{toSym} {r2(result)}</b></div>
            <div className="fx-calc__line">用台銀{chan === "spot" ? "即期" : "現金"}{dir === "buy" ? "賣出" : "買入"} <b className="t-num">{rate(used)}</b>(中間價 {rate(mid)})</div>
            <div className="fx-calc__cost"><i className="ph ph-scissors" aria-hidden="true" /> 銀行從買賣價差賺走約 <b>NT$ {fmt(Math.abs(cost))}</b>{chan === "cash" && cashExtra > 0 ? "　·　換現金又比即期多花約 " + (dir === "buy" ? sym + " " + r2(cashExtra) : "NT$ " + fmt(cashExtra)) : ""}</div>
          </div>
        ) : (
          <p className="fx-calc__tip">輸入金額,馬上算實拿多少、以及銀行從價差賺走你多少。<b>即期</b>(線上換匯)價差小、<b>現金</b>(換鈔票)價差大,差很多。</p>
        )}
      </div>
    );
  }

  // 美股部位 · 匯率影響:用換匯平均成本 vs 現價，單獨把「匯率」這一層帳面損益從股價拆出來
  function USExposure({ H, current, sum }) {
    const us = (H.assets || []).filter(function (a) { return a.ccy === "USD" && a.twd > 0; });
    if (!us.length || !(current > 0)) return null;
    const twdNow = us.reduce(function (s, a) { return s + a.twd; }, 0);
    const usd = twdNow / current;
    const avg = (sum && sum.avgRate > 0) ? sum.avgRate : 0;
    const fxPL = avg > 0 ? usd * (current - avg) : 0;
    const fxPct = avg > 0 ? (current / avg - 1) * 100 : 0;
    const up = fxPL >= 0;
    return (
      <section className="fpage__card">
        <div className="fpage__card-head"><span className="t-overline">美股部位 · 匯率影響</span></div>
        <div className="fx-avg">
          <div className="fx-avg__row"><span>美股部位(現值)</span><span className="t-num">US$ {fmt(usd)} · NT$ {fmt(twdNow)}</span></div>
          {avg > 0 ? (
            <React.Fragment>
              <div className="fx-avg__row"><span>換匯平均成本</span><span className="t-num">1 USD = NT$ {r2(avg)}(現價 {r2(current)})</span></div>
              <div className="fx-avg__row fx-avg__main"><span>其中「匯率」這層帳面</span><span className={"t-num " + (up ? "fx-pl--up" : "fx-pl--down")}>{up ? "+" : "−"}NT$ {fmt(Math.abs(fxPL))}（{up ? "+" : "−"}{Math.abs(fxPct).toFixed(1)}%）</span></div>
            </React.Fragment>
          ) : (
            <div className="fx-avg__row"><span>匯率損益</span><span className="t-num">到下方記幾筆換匯，就能拆出這層</span></div>
          )}
        </div>
        <div className="fire-desc">
          <p>💡 你美股賺賠有<b>兩層</b>:<b>股價</b>漲跌 ＋ <b>匯率</b>(台幣貶→換回台幣多賺、台幣升→少賺)。這裡用你的<b>換匯平均成本</b>對比現價，單獨抓出「匯率」貢獻多少{avg > 0 ? (up ? "——目前台幣走貶，讓你帳面多賺一些。" : "——目前台幣走升，侵蝕了一些報酬。") : "。"}</p>
        </div>
        <p className="fx-disclaim">粗估:假設美股部位都以你的換匯平均成本換得的美金投入;只拆「匯率」這一層，不含股價損益與手續費。教育用途、非投資建議。</p>
      </section>
    );
  }

  function FxScreen({ onClose, onChanged }) {
    const H = window.HELM || {};
    const fx = H.fx || null;
    const jpy = H.fxJpy || null;
    const sum = H.fxSummary || { totalTwd: 0, totalUsd: 0, avgRate: 0, count: 0 };
    const records = H.fxRecords || [];
    const current = fx ? fx.current : (H.RATE || 0);

    const [showAdd, setShowAdd] = React.useState(false);
    const [date, setDate] = React.useState(new Date().toISOString().slice(0, 10));
    const [twd, setTwd] = React.useState("");
    const [usd, setUsd] = React.useState("");
    const [saving, setSaving] = React.useState(false);
    const [busyRow, setBusyRow] = React.useState(0);

    const twdNum = parseFloat(String(twd).replace(/,/g, "")) || 0;
    const usdNum = parseFloat(String(usd).replace(/,/g, "")) || 0;
    const previewRate = usdNum > 0 ? twdNum / usdNum : 0;

    function add() {
      if (twdNum <= 0 || usdNum <= 0) return;
      setSaving(true);
      window.HelmData.addFx({ date: date.replace(/-/g, "/"), twd: twdNum, usd: usdNum }).then(function () {
        setSaving(false); setShowAdd(false); setTwd(""); setUsd("");
        onChanged();
      });
    }
    function del(row) {
      setBusyRow(row);
      window.HelmData.deleteFx(row).then(function () { setBusyRow(0); onChanged(); });
    }

    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">
            <div className="fpage__body">
              <p style={{ margin: "0 0 12px", padding: "8px 12px", background: "#fff7e6", border: "1px solid #e9dcc3", borderRadius: "10px", fontSize: "13px", lineHeight: 1.5, color: "#6a4420" }}>📌 試用版:下面的匯率是<b>示範數據、非即時</b>(接自己後端的正式版才會抓即時匯率)。你自己記的換匯紀錄仍照算。</p>

              {/* 美元 */}
              <section className="fpage__card">
                <div className="fpage__card-head"><span className="t-overline">換匯參考</span><span className="fpage__card-hint">USD / TWD</span></div>
                <FxQuote data={fx} perLabel="1 USD =" />
                <FxCalc data={fx} unit="美元" sym="US$" />
                {fx && (
                  <div className="fire-desc">
                    <p><b>怎麼看</b>:金線 = 近一年走勢(手指點圖看當下日期與價格)、灰虛線 = 一年均價;<b>「第 N 百分位」= 現價在近一年裡的高低位置</b>,越小越便宜。買賣牌價是台銀即時報價,<b>線上換匯看「即期」</b>。</p>
                  </div>
                )}
                <p className="fx-disclaim">建議是「定期定額為主、便宜時多換一點」的機械規則,不是預測匯率 —— 沒人能準報低點。</p>
              </section>

              {/* 日圓 */}
              <section className="fpage__card">
                <div className="fpage__card-head"><span className="t-overline">換匯參考</span><span className="fpage__card-hint">JPY / TWD</span></div>
                <FxQuote data={jpy} perLabel="1 JPY =" headNote={jpy && jpy.current ? "100 日圓 ≈ NT$ " + r2(jpy.current * 100) : ""} />
                <FxCalc data={jpy} unit="日圓" sym="¥" />
                {jpy && <p className="fx-disclaim">日圓報價以「1 日圓 = 幾元台幣」表示;100 日圓約等於上面換算值。去日本玩或買日股/日圓資產時可參考。</p>}
              </section>

              {/* 富邦換匯小抄 */}
              <section className="fpage__card">
                <div className="fpage__card-head"><span className="t-overline">富邦換匯小抄</span></div>
                <ul className="fx-tips">
                  <li>用<b>一本萬利 App 線上換匯</b>(換匯/外幣轉帳→買外幣),挑 <b>09:00–15:30</b> 吃優惠最高 3 分,別臨櫃。</li>
                  <li><b>外幣交割</b>:先把台幣分批換成美元囤著,要買 SPCX 直接用美元下單。</li>
                  <li>最穩做法:<b>定期定額換匯</b>(每月固定一筆),用下面記錄追蹤平均成本。</li>
                  <li>單筆 <b>≥ 50 萬</b>有大額優惠,但那等於全壓當下匯率;新手分批通常更安心。</li>
                </ul>
              </section>

              {/* 定期定額換匯追蹤(美元)*/}
              <section className="fpage__card">
                <div className="fpage__card-head">
                  <span className="t-overline">定期定額換匯追蹤 · 美元</span>
                  {!showAdd && <button className="fx-addbtn" onClick={() => setShowAdd(true)}><i className="ph ph-plus" aria-hidden="true" />新增換匯</button>}
                </div>

                {sum.count > 0 && (
                  <div className="fx-avg">
                    <div className="fx-avg__row"><span>累計</span><span className="t-num">NT$ {fmt(sum.totalTwd)} → US$ {fmt(sum.totalUsd)}</span></div>
                    <div className="fx-avg__row fx-avg__main"><span>平均成本</span><span className="t-num">1 USD = NT$ {r2(sum.avgRate)}</span></div>
                    {current > 0 && sum.avgRate > 0 && (
                      <div className={"fx-avg__cmp " + (current >= sum.avgRate ? "fx-pl--up" : "fx-pl--down")}>
                        你換的美金以現價算,帳面 {current >= sum.avgRate ? "+" : "−"}{Math.abs((current / sum.avgRate - 1) * 100).toFixed(1)}%
                        (約 {current >= sum.avgRate ? "+" : "−"}NT$ {fmt(Math.abs((current - sum.avgRate) * sum.totalUsd))})
                      </div>
                    )}
                  </div>
                )}

                {showAdd && (
                  <div className="fx-addform">
                    <Field label="日期"><Input type="date" value={date} onChange={(e) => setDate(e.target.value)} /></Field>
                    <Field label="換出台幣"><Input amount affix="NT$" inputMode="decimal" placeholder="0" value={twd} onChange={(e) => setTwd(e.target.value)} /></Field>
                    <Field label="換得美元"><Input amount affix="US$" inputMode="decimal" placeholder="0" value={usd} onChange={(e) => setUsd(e.target.value)} /></Field>
                    {previewRate > 0 && <div className="fx-note">這筆匯率 1 USD = NT$ {r2(previewRate)}</div>}
                    <div className="fx-addform__row">
                      <Button variant="secondary" block onClick={() => { setShowAdd(false); setTwd(""); setUsd(""); }} disabled={saving}>取消</Button>
                      <Button variant="primary" block onClick={add} loading={saving}>加入</Button>
                    </div>
                  </div>
                )}

                <div className="fx-list">
                  {records.length === 0 && !showAdd && <p className="fx-empty">還沒有換匯記錄。每次換美元後加一筆,就能看平均成本。</p>}
                  {records.map(function (r) {
                    return (
                      <div className="fx-row" key={r.id}>
                        <div className="fx-row__main">
                          <span className="fx-row__date">{r.date}</span>
                          <span className="fx-row__amt t-num">NT$ {fmt(r.twd)} → US$ {fmt(r.usd)}</span>
                        </div>
                        <span className="fx-row__rate t-num">{r2(r.rate)}</span>
                        <button className="fx-row__del" onClick={() => del(r._row)} disabled={busyRow === r._row} aria-label="刪除這筆">
                          <i className={"ph " + (busyRow === r._row ? "ph-circle-notch" : "ph-trash")} aria-hidden="true" />
                        </button>
                      </div>
                    );
                  })}
                </div>
              </section>

              <USExposure H={H} current={current} sum={sum} />

            </div>
          </div>
        </div>
      </div>
    );
  }

  window.FxScreen = FxScreen;
})();
