// Helm — 新增/編輯項目（Claude Design 重設計版:.fpage 單一捲動層 + 三張卡片）。接真實後端。
(function () {
  const NS = window.HelmDesignSystem_9613a7;
  const { SegmentedControl, Field, Input, Select, Button } = NS;

  const CATS = {
    "資產": ["房地產", "車輛", "ETF", "現金", "美股", "投資", "保險", "其他"],
    "負債": ["房貸", "車貸", "信貸", "信用卡", "其他"],
    "保障": ["壽險", "失能/長照", "重疾/癌症", "醫療", "意外", "年金/儲蓄", "其他"],
  };
  const TICKER_CATS = ["ETF", "美股", "股票", "投資"];   // 只有這些類別才顯示股票代號(現金/房地產/車/保險不顯示)
  // 代號正規化:台股漏打 .TW 會被當美股、抓到 TWD 價卻標 USD 再乘匯率 → 市值暴增 ~32 倍。
  //   純數字 4~6 碼 / 數字+單一字母(00631L、00679B、00981A)= 台股 → 自動補 .TW;美股(英文代號)不動。
  function normTicker(t) { t = String(t || "").trim().toUpperCase(); return /^\d{4,6}[A-Z]?$/.test(t) ? t + ".TW" : t; }

  // 金額千分位:只把「整數部分」加逗號,小數部分原樣保留(才能輸入小數點,例如美金 1,234.56)
  function groupAmount(s) {
    s = String(s == null ? "" : s).replace(/,/g, "");
    if (s === "") return "";
    var neg = s.charAt(0) === "-"; if (neg) s = s.slice(1);
    var dot = s.indexOf(".");
    var intPart = (dot >= 0 ? s.slice(0, dot) : s).replace(/[^0-9]/g, "");
    var fracPart = dot >= 0 ? s.slice(dot + 1).replace(/[^0-9]/g, "") : null;
    var gi = intPart ? Number(intPart).toLocaleString("en-US") : "";
    var out = (fracPart != null) ? ((gi || "0") + "." + fracPart) : gi;
    return (neg ? "-" : "") + out;
  }

  // 分組卡片(基本資料 / 金額 / 其他)
  function Card({ title, hint, children }) {
    return (
      <section className="fpage__card">
        <div className="fpage__card-head">
          <span className="t-overline">{title}</span>
          {hint ? <span className="fpage__card-hint">{hint}</span> : null}
        </div>
        <div className="fpage__fields">{children}</div>
      </section>
    );
  }

  function AddEditScreen({ item, onClose, onSaved, onDeleted }) {
    const RATE = (window.HELM && window.HELM.RATE) || 32.3;
    const editing = !!item;
    const [type, setType] = React.useState(item ? (item._side === "liab" ? "負債" : (item._side === "prot" ? "保障" : "資產")) : "資產");
    const [cat, setCat] = React.useState(item ? item.cat : "");
    const [name, setName] = React.useState(item ? item.name : "");
    const [amount, setAmount] = React.useState(item ? String(item.baseAmount != null ? item.baseAmount : (item.ccy === "USD" ? (item.usd || "") : (item.twd || ""))) : "");
    const [ccy, setCcy] = React.useState(item ? item.ccy : "TWD");
    const [ticker, setTicker] = React.useState(item && item.ticker ? item.ticker : "");
    const [shares, setShares] = React.useState(item && item.shares ? String(item.shares) : "");
    const [loanRate, setLoanRate] = React.useState(item && item.loanRate ? String(item.loanRate) : "");
    const [loanPay, setLoanPay] = React.useState(item && item.loanPay ? String(item.loanPay) : "");
    const [debitDay, setDebitDay] = React.useState(item && item.debitDay ? String(item.debitDay) : "");
    const [debitAcct, setDebitAcct] = React.useState(item && item.debitAcct ? item.debitAcct : "");
    const [note, setNote] = React.useState(item && item.note ? item.note : "");
    const [date, setDate] = React.useState(item && item.date ? item.date.replace(/\//g, "-") : new Date().toISOString().slice(0, 10));
    const [saving, setSaving] = React.useState(false);
    const [deleting, setDeleting] = React.useState(false);
    const [confirmDel, setConfirmDel] = React.useState(false);
    const [touched, setTouched] = React.useState(false);
    const [txnKind, setTxnKind] = React.useState("入帳");
    const [txnAmt, setTxnAmt] = React.useState("");
    const [txnNote, setTxnNote] = React.useState("");
    const [editCt, setEditCt] = React.useState(null);   // 正在編輯的現金記錄
    const [posting, setPosting] = React.useState(false);

    const num = parseFloat(String(amount).replace(/,/g, "")) || 0;
    const shareNum = parseFloat(String(shares).replace(/,/g, "")) || 0;
    const showTicker = type === "資產" && TICKER_CATS.indexOf(cat) >= 0;
    const hasStock = showTicker && !!ticker && shareNum > 0;
    const grouped = groupAmount(amount);
    const isLoan = type === "負債" && cat !== "" && cat !== "信用卡";   // 房貸/車貸/信貸/其他 都能自動遞減;信用卡是循環、不適用
    const loanRateNum = parseFloat(String(loanRate).replace(/,/g, "")) || 0;
    const loanPayNum = parseFloat(String(loanPay).replace(/,/g, "")) || 0;
    const loanPayGrouped = loanPayNum ? loanPayNum.toLocaleString("en-US") : "";
    const loanOn = isLoan && loanPayNum > 0;
    const cashAccts = ((window.HELM && window.HELM.assets) || []).filter(function (a) { return a.cat === "現金"; }).map(function (a) { return a.name; });
    const debitDayNum = parseInt(String(debitDay).replace(/[^0-9]/g, ""), 10) || 0;
    const autoDebitOn = loanOn && debitDayNum >= 1 && debitDayNum <= 31 && !!debitAcct;
    const nameErr = touched && !name.trim();
    const catErr = touched && !cat;
    const amtErr = touched && !hasStock && num <= 0;
    const shareErr = touched && showTicker && !!ticker && shareNum <= 0;
    const isCash = editing && type === "資產" && cat === "現金";
    const txns = (isCash && window.HELM && window.HELM.cashTxns) ? window.HELM.cashTxns.filter(function (t) { return t.account === item.name; }) : [];
    const txnNum = parseFloat(String(txnAmt).replace(/,/g, "")) || 0;

    function save() {
      setTouched(true);
      if (!name.trim() || !cat) return;
      if (!hasStock && num <= 0) return;
      if (ticker && shareNum <= 0) return;
      setSaving(true);
      const fields = {
        type: type, category: cat, name: name.trim(),
        amount: num, currency: ccy, note: note,
        updatedAt: date.replace(/-/g, "/"),
        ticker: showTicker ? normTicker(ticker) : "", shares: hasStock ? shareNum : "",
        loanRate: isLoan ? loanRateNum : "", loanPay: isLoan ? loanPayNum : "",
        debitDay: autoDebitOn ? debitDayNum : "", debitAcct: autoDebitOn ? debitAcct : "",
      };
      const p = editing
        ? window.HelmData.updateItem(Object.assign({ _row: item._row }, fields))
        : window.HelmData.addItem(fields);
      p.then(function () { onSaved(editing ? "已更新「" + name + "」" : "已新增「" + name + "」"); });
    }

    function doDelete() {
      setDeleting(true);
      window.HelmData.deleteItem(item._row).then(function () { onDeleted("已刪除「" + name + "」"); });
    }

    function postTxn() {
      if (txnNum <= 0) return;
      const delta = txnKind === "支出" ? -txnNum : txnNum;
      setPosting(true);
      window.HelmData.addCashTxn({ _row: item._row, name: item.name, delta: delta, note: txnNote })
        .then(function () { onSaved("已記一筆 " + (delta > 0 ? "+" : "") + delta.toLocaleString("en-US") + " 到「" + item.name + "」"); });
    }

    function startEditTxn(t) {
      setEditCt({ id: t.id, cashRow: t._row, kind: t.amount < 0 ? "支出" : "入帳", amt: String(Math.abs(t.amount)), date: String(t.date || "").replace(/\//g, "-"), note: t.note || "" });
    }
    function saveTxn() {
      const a = parseFloat(String(editCt.amt).replace(/,/g, "")) || 0;
      if (a <= 0) return;
      const signed = editCt.kind === "支出" ? -a : a;
      setPosting(true);
      window.HelmData.updateCashTxn({ cashRow: editCt.cashRow, _row: item._row, name: item.name, amount: signed, date: editCt.date, note: editCt.note })
        .then(function () { onSaved("已更新這筆記錄,餘額已同步"); });
    }
    function delTxn() {
      setPosting(true);
      window.HelmData.deleteCashTxn({ cashRow: editCt.cashRow, _row: item._row })
        .then(function () { onDeleted("已刪除這筆現金記錄,餘額已回沖"); });
    }

    return (
      <div className="fpage" role="dialog" aria-modal="true" aria-label={editing ? "編輯項目" : "新增項目"}>
        <div className="fpage__panel">
          {/* 固定頂 bar:左 取消 · 中 標題 · 右 儲存(永不捲動) */}
          <header className="fpage__bar">
            <button className="fpage__cancel" onClick={onClose} disabled={saving}>
              <i className="ph ph-x" aria-hidden="true" />取消
            </button>
            <span className="fpage__title">{editing ? "編輯項目" : "新增項目"}</span>
            <button className="fpage__save" onClick={save} disabled={saving} aria-busy={saving || undefined}>
              {saving ? <span className="fpage__save-spin" aria-hidden="true" /> : null}
              {saving ? "儲存中" : "儲存"}
            </button>
          </header>

          {/* 唯一捲動層 */}
          <div className="fpage__scroll">
            <div className="fpage__body">
              <Card title="基本資料">
                <Field label="類型" required>
                  <SegmentedControl options={["資產", "負債", "保障"]} value={type}
                    onChange={(v) => { setType(v); setCat(""); setTicker(""); setShares(""); setLoanRate(""); setLoanPay(""); }} tones={["positive", "negative", "brass"]} />
                </Field>
                <Field label="類別" required error={catErr ? "選一個類別" : null}>
                  <Select placeholder="選擇類別" value={cat} invalid={catErr}
                    onChange={(e) => setCat(e.target.value)} options={CATS[type]} />
                </Field>
                <Field label="項目名稱" required error={nameErr ? "幫這筆項目取個名字吧" : null}>
                  <Input placeholder="例:玉山活存 / 0050" value={name} invalid={nameErr}
                    onChange={(e) => setName(e.target.value)} />
                </Field>
                {showTicker && (
                  <React.Fragment>
                    <Field label="股票代號" hint="台股打代號就好(如 009816,自動補 .TW)、美股打英文代號(如 SPCX);填了就每天自動抓市價算市值">
                      <Input placeholder="留空 = 手動填金額" value={ticker} onChange={(e) => setTicker(e.target.value)} />
                    </Field>
                    {ticker ? (
                      <Field label="股數" required error={shareErr ? "請輸入股數" : null}>
                        <Input inputMode="decimal" placeholder="例:1000" value={shares} invalid={shareErr}
                          onChange={(e) => setShares(e.target.value)} />
                      </Field>
                    ) : null}
                  </React.Fragment>
                )}
              </Card>

              <Card title={isLoan ? "目前欠款" : (type === "保障" ? "保額" : "金額")}>
                <Field label={hasStock ? "金額(自動更新,可留空)" : (isLoan ? "目前剩餘本金" : (type === "保障" ? "保額(保險金額)" : "金額"))} required={!hasStock}
                  error={amtErr ? "請輸入大於 0 的金額" : null}
                  hint={hasStock ? "市值會依市價每天自動算" : (isLoan ? "填「更新日期」那天的剩餘本金,之後每月自動遞減" : (type === "保障" ? "這張保單的理賠保額;壽險/失能/重疾類會自動帶進保障體檢算缺口(醫療/意外/年金只列管)" : "自動套用千分位"))}>
                  <Input amount affix={ccy === "USD" ? "US$" : "NT$"} inputMode="decimal"
                    placeholder={hasStock ? "自動" : "0"} value={grouped} invalid={amtErr}
                    onChange={(e) => setAmount(e.target.value)} />
                </Field>
                <Field label="幣別">
                  <SegmentedControl options={["TWD", "USD"]} value={ccy} onChange={setCcy} />
                  {ccy === "USD" && !hasStock && (
                    <div className="fpage__fx">≈ NT$ {Math.round(num * RATE).toLocaleString("en-US")}　(1 USD = NT$ {RATE})</div>
                  )}
                </Field>
              </Card>

              {isLoan && (
                <Card title="貸款試算" hint="本息攤還">
                  <Field label="年利率(%)" hint="從貸款合約抄,例:房貸 2.1、車貸 3.5">
                    <Input inputMode="decimal" placeholder="例:2.1" value={loanRate}
                      onChange={(e) => setLoanRate(e.target.value)} />
                  </Field>
                  <Field label="每月應繳(月付金)" hint="本金+利息的固定月付,例:38000">
                    <Input amount affix="NT$" inputMode="decimal" placeholder="例:38000" value={loanPayGrouped}
                      onChange={(e) => setLoanPay(e.target.value)} />
                  </Field>
                  <div className="fpage__fx">
                    {loanOn
                      ? "✓ 已啟用:每月自動把剩餘本金往下調(本息平均攤還)。"
                      : "兩個都填,餘額才會每月自動遞減;留空就當一般固定負債。"}
                  </div>
                  {loanOn && (
                    <div className="ae-debit">
                      <Field label="每月幾號自動扣款(選填)" hint="填了 → 扣款日到會自動記一筆現金支出;留空 → 只算負債遞減、現金自己更新">
                        <Input inputMode="numeric" placeholder="例:5" value={debitDay}
                          onChange={(e) => setDebitDay(e.target.value.replace(/[^0-9]/g, "").slice(0, 2))} />
                      </Field>
                      {debitDayNum >= 1 && (
                        <Field label="從哪個現金帳戶扣" hint="到期時這個帳戶餘額自動減月付金;是一筆可在該帳戶「現金記帳」裡刪掉回沖的紀錄">
                          {cashAccts.length ? (
                            <select className="ae-debit__sel" value={debitAcct} onChange={(e) => setDebitAcct(e.target.value)}>
                              <option value="">請選擇…</option>
                              {cashAccts.map(function (n) { return <option key={n} value={n}>{n}</option>; })}
                            </select>
                          ) : (
                            <div className="ae-debit__none">你還沒有「現金」類別的帳戶——先到資產新增一個現金帳戶,才能設自動扣款。</div>
                          )}
                        </Field>
                      )}
                      <div className={"fpage__fx" + (autoDebitOn ? " ae-debit__on" : "")}>
                        {autoDebitOn
                          ? ("✓ 每月 " + debitDayNum + " 號自動從「" + debitAcct + "」扣 NT$ " + loanPayGrouped + "。⚠️ 開了這個就別再手動照銀行對帳扣同一筆(會扣兩次);薪水入帳也要記進現金,不然現金會越算越少。")
                          : debitDayNum >= 1
                            ? "還要選一個「現金帳戶」才會生效。"
                            : "選填:設「扣款日 + 現金帳戶」→ 到期自動扣現金,負債和現金一起動。"}
                      </div>
                    </div>
                  )}
                </Card>
              )}

              {isCash && (
                <Card title="記一筆" hint="入帳／支出 · 直接更新餘額">
                  <Field label="類型">
                    <SegmentedControl options={["入帳", "支出"]} value={txnKind} onChange={setTxnKind} tones={["positive", "negative"]} />
                  </Field>
                  <Field label="金額" hint="按下「記一筆」會直接把餘額加上(入帳)或減去(支出),不用自己算">
                    <Input amount affix={txnKind === "支出" ? "−NT$" : "＋NT$"} inputMode="decimal" placeholder="例:2000"
                      value={txnAmt} onChange={(e) => setTxnAmt(e.target.value)} />
                  </Field>
                  <Field label="備註" hint="選填">
                    <Input placeholder="例:獎金入帳 / 繳保費" value={txnNote} onChange={(e) => setTxnNote(e.target.value)} />
                  </Field>
                  <Button variant="primary" block onClick={postTxn} loading={posting} disabled={txnNum <= 0}>記一筆</Button>
                  {txns.length > 0 && (
                    <div className="cf-list" style={{ marginTop: 6 }}>
                      <p className="prot-sum__note" style={{ margin: "2px 0 6px" }}>點任一筆可改日期/金額或刪除——餘額會自動跟著調整</p>
                      {txns.slice(0, 12).map(function (t) {
                        if (editCt && editCt.id === t.id) {
                          return (
                            <div key={t.id} className="ct-edit">
                              <SegmentedControl options={["入帳", "支出"]} value={editCt.kind} onChange={function (v) { setEditCt(Object.assign({}, editCt, { kind: v })); }} tones={["positive", "negative"]} />
                              <Input amount affix={editCt.kind === "支出" ? "−NT$" : "＋NT$"} inputMode="decimal" value={editCt.amt} onChange={function (e) { setEditCt(Object.assign({}, editCt, { amt: e.target.value })); }} />
                              <Input type="date" value={editCt.date} onChange={function (e) { setEditCt(Object.assign({}, editCt, { date: e.target.value })); }} />
                              <Input placeholder="備註(選填)" value={editCt.note} onChange={function (e) { setEditCt(Object.assign({}, editCt, { note: e.target.value })); }} />
                              <div className="ct-edit__btns">
                                <Button variant="danger" onClick={delTxn} loading={posting}>刪除</Button>
                                <Button variant="secondary" onClick={function () { setEditCt(null); }} disabled={posting}>取消</Button>
                                <Button variant="primary" onClick={saveTxn} loading={posting}>儲存</Button>
                              </div>
                            </div>
                          );
                        }
                        return (
                          <button key={t.id} type="button" className="cf-row cf-row--tap" onClick={function () { startEditTxn(t); }}>
                            <span className="cf-row__l">
                              <span className="cf-row__name">{t.date}</span>
                              {t.note ? <span className="cf-row__sub">{t.note}</span> : null}
                            </span>
                            <span className={"cf-row__amt t-num " + (t.amount < 0 ? "cf-amt--neg" : "cf-amt--pos")}>{t.amount > 0 ? "+" : ""}{Number(t.amount).toLocaleString("en-US")}</span>
                            <i className="ph ph-pencil-simple cf-row__edit" aria-hidden="true" />
                          </button>
                        );
                      })}
                    </div>
                  )}
                </Card>
              )}

              <Card title="其他">
                <Field label="備註" hint="選填">
                  <Input as="textarea" placeholder="寫點筆記…" value={note} onChange={(e) => setNote(e.target.value)} />
                </Field>
                <Field label="更新日期">
                  <Input type="date" value={date} onChange={(e) => setDate(e.target.value)} />
                </Field>
              </Card>

              {editing && (
                <section className="fpage__danger">
                  {!confirmDel ? (
                    <Button variant="danger" block iconLeft="ph-trash" onClick={() => setConfirmDel(true)}>刪除這筆項目</Button>
                  ) : (
                    <div className="fpage__confirm">
                      <p className="fpage__confirm-q">確定刪除「{name}」?此動作無法復原。</p>
                      <div className="fpage__confirm-row">
                        <Button variant="secondary" block onClick={() => setConfirmDel(false)} disabled={deleting}>取消</Button>
                        <Button variant="danger" block onClick={doDelete} loading={deleting}>確定刪除</Button>
                      </div>
                    </div>
                  )}
                </section>
              )}
            </div>
          </div>
        </div>
      </div>
    );
  }

  window.AddEditSheet = AddEditScreen;
})();
