// Helm — Overview (總覽 / 駕駛艙). 數字全部跟著真實資料自動算。
(function () {
  const NS = window.HelmDesignSystem_9613a7;
  const { Card, KpiCard, AmountDisplay, InsightCard, LiquidityBar } = NS;

  function fmt(n) { return Math.round(n).toLocaleString("en-US"); }
  function wan(n) { return "約 " + (Math.round(n / 1e4)).toLocaleString("en-US") + " 萬"; }
  function r2(n) { return Number(n).toLocaleString("en-US", { maximumFractionDigits: 2 }); }
  function wanS(n) { return (Math.round((n || 0) / 1e4)).toLocaleString("en-US") + " 萬"; }

  // 財務健檢:從 window.HELM 自動算出行動建議 + 排優先序(每次打開就跑,不需人工)
  function computeAdvice(H) {
    var out = [], cf = H.cashflow || {}, assets = H.assets || [], liabs = H.liabilities || [], prot = H.protection || [];
    function sumCat(arr, re) { return arr.reduce(function (s, x) { return s + (re.test((x.cat || "") + (x.name || "")) ? (x.twd || 0) : 0); }, 0); }
    var cash = sumCat(assets, /現金|活存|存款|定存/);
    var realEstate = sumCat(assets, /房|宅|地產/);
    var lifeCover = sumCat(prot, /壽險/);
    var disCover = sumCat(prot, /失能|長照/);
    var mExp = cf.expenseSum || 0, totalA = H.totalAssets || 0, totalL = H.totalLiab || 0;
    var maxRate = liabs.reduce(function (m, l) { return Math.max(m, l.loanRate || 0); }, 0);
    // 1 緊急預備金(現金 ÷ 月支出)
    if (mExp > 0) {
      var mo = cash / mExp;
      if (mo < 3) out.push({ sev: 0, icon: "ph-lifebuoy", title: "緊急預備金不足", detail: "你的現金只夠約 " + mo.toFixed(1) + " 個月開銷。先補到 6 個月(放活存)— 這是所有理財的地基。" });
      else if (mo < 6) out.push({ sev: 1, icon: "ph-lifebuoy", title: "緊急預備金再厚一點", detail: "現金約 " + mo.toFixed(1) + " 個月,建議補到 6 個月再安心。" });
      else out.push({ sev: 3, icon: "ph-lifebuoy", title: "緊急預備金充足", detail: "現金約 " + Math.round(mo) + " 個月,地基穩。" });
    }
    // 2 失能保障(最常被忽略、卻最傷)
    if (disCover <= 0) out.push({ sev: 0, icon: "ph-first-aid-kit", title: "幾乎沒有失能保障", detail: "萬一不能工作,收入停、還要被照顧——這常是最大的洞。去「理財工具 → 保障體檢 → 失能」看缺口。" });
    // 3 壽險 vs 負債
    if (totalL > 0 && lifeCover < totalL) {
      var cov = lifeCover / totalL;
      if (cov < 0.5) out.push({ sev: 1, icon: "ph-umbrella", title: "壽險遠低於負債", detail: "壽險 " + wanS(lifeCover) + " 遠低於負債 " + wanS(totalL) + ",萬一你走了家人要扛一大筆債。去保障體檢確認缺口。" });
      else out.push({ sev: 2, icon: "ph-umbrella", title: "壽險略低於負債", detail: "壽險 " + wanS(lifeCover) + " 還沒蓋過負債 " + wanS(totalL) + "(差 " + wanS(totalL - lifeCover) + ")。注意這只比「夠不夠還債」;含家人生活費的完整壽險缺口請看保障體檢(通常大很多)。" });
    }
    // 4 資產集中度
    if (totalA > 0 && realEstate / totalA > 0.6) out.push({ sev: 1, icon: "ph-buildings", title: "資產太集中在房地產", detail: Math.round(realEstate / totalA * 100) + "% 壓在不動產、流動性低。別再加碼房地產,把新存的錢養到流動資產(現金/股票)分散。" });
    // 5 現金流
    if (cf.incomeSum && (cf.savingPower || 0) <= 0) out.push({ sev: 0, icon: "ph-warning-circle", title: "入不敷出", detail: "支出快追上或超過收入了,先到「現金流」找漏洞。" });
    else if ((cf.freeBalance || 0) < 0) out.push({ sev: 1, icon: "ph-trend-down", title: "在吃老本", detail: "你的定期定額投入超過能存下的錢——降低投入或增加收入,別讓自由結餘是負的。" });
    else if (cf.incomeSum && cf.freeBalance != null) out.push({ sev: 3, icon: "ph-piggy-bank", title: "每月有結餘", detail: "扣掉投入後每月還能自由運用約 " + fmt(cf.freeBalance) + ",節奏健康。" });
    // 6 高利率債務
    if (maxRate >= 5) out.push({ sev: 1, icon: "ph-percent", title: "有高利率債務", detail: "有利率 " + maxRate + "% 的債,優先還它(去提前還款試算)— 利率高於投資報酬時,還債就是穩賺。" });
    // 7 閒置現金過多
    if (mExp > 0 && cash / mExp > 12) out.push({ sev: 2, icon: "ph-coins", title: "閒置現金偏多", detail: "現金遠超過緊急預備金,多的部分會被通膨慢慢吃掉,可考慮投資(看複利/通膨試算)。" });
    out.sort(function (a, b) { return a.sev - b.sev; });
    return out;
  }

  function Legend({ allocation, total, active, setActive }) {
    return (
      <div className="ov-legend">
        {allocation.map((s, i) => (
          <button key={s.cat} className={"ov-legend__row" + (active === i ? " is-active" : "")}
            onMouseEnter={() => setActive(i)} onMouseLeave={() => setActive(null)}
            onFocus={() => setActive(i)}>
            <span className="ov-legend__dot" style={{ background: s.color }} />
            <span className="ov-legend__cat">{s.cat}</span>
            <span className="ov-legend__amt t-num">{fmt(s.value)}</span>
            <span className="ov-legend__pct t-num">{total ? ((s.value / total) * 100).toFixed(1) : "0.0"}%</span>
          </button>
        ))}
      </div>
    );
  }

  function NetWorthTrend({ series }) {
    const ref = React.useRef(null);
    const chart = React.useRef(null);
    React.useEffect(function () {
      if (!ref.current || !window.Chart || !series || series.length < 2) 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 crosshair = {
        id: "nwcross",
        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: series.map(function (p) { return p.label; }),
          datasets: [{
            data: series.map(function (p) { return p.value; }),
            borderColor: brass, backgroundColor: brass + "22",
            fill: true, tension: 0.25, pointRadius: series.length > 40 ? 0 : 3, pointHoverRadius: 4, pointHoverBackgroundColor: brass, 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 "NT$ " + Math.round(c.parsed.y).toLocaleString("en-US"); } } },
          },
          scales: {
            y: { ticks: { color: tert, maxTicksLimit: 5, callback: function (v) { return Math.round(v / 10000) + "萬"; } }, grid: { color: grid } },
            x: { ticks: { color: tert, maxTicksLimit: 6, maxRotation: 0 }, grid: { display: false } },
          },
        },
      });
      return function () { if (chart.current) { chart.current.destroy(); chart.current = null; } };
    }, [series]);
    return <div className="ov-trendchart"><canvas ref={ref} /></div>;
  }

  function Overview({ onOpenFx }) {
    const H = window.HELM;
    const [active, setActive] = React.useState(null);
    const [dismissWelcome, setDismissWelcome] = React.useState(function () { try { return localStorage.getItem("helm-welcome-done") === "1"; } catch (e) { return false; } });
    const segments = H.allocation.map((a) => ({ label: a.cat, value: a.value, color: a.color }));

    // 跟著真實資料算:最大配置類別 + 流動性
    const top = H.allocation[0];
    const topPct = top && H.totalAssets ? (top.value / H.totalAssets) * 100 : 0;
    const liqPct = H.totalAssets ? (H.liquid / H.totalAssets) * 100 : 0;

    // 行動建議(自動健檢,依資料排序)
    const advice = computeAdvice(H);
    const todo = advice.filter(function (a) { return a.sev < 3; }).length;

    // (換匯參考已移到「理財工具」分頁)

    return (
      <div className="screen">
        {!H.birth && !dismissWelcome && (
          <div className="ov-welcome">
            <button type="button" className="ov-welcome__x" onClick={function () { setDismissWelcome(true); try { localStorage.setItem("helm-welcome-done", "1"); } catch (e) {} }} aria-label="關閉">×</button>
            <div className="ov-welcome__t">👋 歡迎!先花一分鐘設定基本資料</div>
            <p className="ov-welcome__p">點右上角 <i className="ph ph-gear-six" aria-hidden="true" /> <b>設定 → 個人資料</b>,填你的<b>生日、家庭狀況、工作型態</b>——退休、保障規劃、報稅這些工具才會用你的真實情況算(不填會用示意值)。資產、保單直接用底下的 <b>＋</b> 新增。</p>
          </div>
        )}
        {/* ① 淨值英雄區 */}
        <Card variant="lg" className="ov-hero">
          <div className="t-overline">淨資產</div>
          <AmountDisplay value={H.netWorth} size="hero" />
          <div className="ov-hero__sub">
            <span className="ov-colloq t-num">{wan(H.netWorth)}</span>
            <span className="ov-hero__guide">這是你目前掌握的淨值</span>
          </div>
          {/* 淨值趨勢:優先用每日自動記錄(netWorthHistory),不足才用月結;都不夠顯示鼓勵字 */}
          {(function () {
            var nwh = H.netWorthHistory || [];
            var daily = nwh.length >= 2;
            var series = daily ? nwh.map(function (p) { return { label: p.d, value: p.v }; })
              : (H.monthly && H.monthly.length >= 2) ? H.monthly.map(function (m) { return { label: m.ym, value: m.netWorth }; }) : null;
            return series ? (
              <React.Fragment>
                <div className="ov-trend__label t-caption">淨值趨勢 · {daily ? "每日" : "每月"}<span className="ov-trend__hint"> · 手指停在線上看當天</span></div>
                <NetWorthTrend series={series} />
              </React.Fragment>
            ) : (
              <div className="ov-trend">
                <i className="ph ph-chart-line-up" aria-hidden="true" />
                <span>淨值趨勢 · 每天打開 App 會自動記一筆,累積幾天就長出曲線</span>
              </div>
            );
          })()}
        </Card>

        {/* 行動建議：自動健檢、依資料排優先序(每次打開就跑,不用問) */}
        {advice.length > 0 && (
          <Card>
            <div className="ov-sec ov-adv__head">
              <span className="t-overline">行動建議</span>
              <span className="t-caption">{todo > 0 ? todo + " 件可加強" : "體質很穩"} · 自動</span>
            </div>
            <div className="ov-adv">
              {advice.map(function (a, i) {
                var c = a.sev === 0 ? "high" : a.sev === 1 ? "mid" : a.sev === 2 ? "low" : "good";
                return (
                  <div key={i} className={"ov-adv__item adv--" + c}>
                    <i className={"ph " + a.icon} aria-hidden="true" />
                    <span className="ov-adv__txt"><b>{a.title}</b><span>{a.detail}</span></span>
                  </div>
                );
              })}
            </div>
            <p className="ov-adv__note">依你目前的資料自動產生、自動排序——打開就會看,不用每次問。資料變了它就跟著變。</p>
          </Card>
        )}

        {/* 次級 KPI：總資產 / 總負債 */}
        <div className="helm-kpi-pair">
          <Card><KpiCard label="總資產" size="mini" icon="ph-trend-up" sub={wan(H.totalAssets)}>
            <AmountDisplay value={H.totalAssets} size="md" tone="positive" />
          </KpiCard></Card>
          <Card><KpiCard label="總負債" size="mini" icon="ph-trend-down" sub={wan(H.totalLiab)}>
            <AmountDisplay value={H.totalLiab} size="md" tone="negative" />
          </KpiCard></Card>
        </div>

        {/* ② 資產配置圓餅 */}
        <Card>
          <div className="ov-sec"><span className="t-overline">資產配置</span></div>
          <div className="ov-donut">
            <window.DonutChart
              segments={segments}
              centerLabel="總資產"
              centerValue={"NT$ " + fmt(H.totalAssets)}
              height={236}
            />
          </div>
          <Legend allocation={H.allocation} total={H.totalAssets} active={active} setActive={setActive} />
        </Card>

        {/* 配置洞察已併入上方「行動建議」(避免重複) */}
        <Card>
          <div className="ov-liq-head">
            <span className="t-label" style={{ fontWeight: 600 }}>流動性</span>
            <span className="t-caption">活錢只佔 <b style={{ color: "var(--text-primary)" }}>{liqPct.toFixed(1)}%</b></span>
          </div>
          <LiquidityBar segments={[
            { key: "liquid", label: "活錢（現金＋ETF＋美股）", value: H.liquid, color: "var(--c-alloc-4)" },
            { key: "illiquid", label: "不動／低流動", value: H.totalAssets - H.liquid, color: "var(--c-alloc-1)" },
          ]} />
        </Card>

        {/* 換匯已移到「理財工具」分頁 */}
      </div>
    );
  }

  window.Overview = Overview;
})();
