// Journal entries (Accounting tab)
function jeLeaves(nodes, acc) {
  nodes.forEach((n) => {
    if (n.children) jeLeaves(n.children, acc);
    else acc.push(n.code + " · " + n.name);
  });
  return acc;
}

function JournalTab() {
  const { useState } = React;
  const [entries, setEntries] = useState(D.journal);
  const [filter, setFilter] = useState("All");
  const [sel, setSel] = useState(null);
  const [showNew, setShowNew] = useState(false);

  const sumD = (e) => e.lines.reduce((s, l) => s + (l.debit || 0), 0);
  const visible = entries.filter((e) => filter === "All" || e.status === filter);
  const selEntry = sel ? entries.find((e) => e.id === sel) : null;

  const post = (id) => {
    setEntries((es) => es.map((e) => (e.id === id ? { ...e, status: "Posted" } : e)));
    notify(T("je.entryPosted", { id: id }));
    setSel(null);
  };

  return (
    <><div className="toolbar page-toolbar">
        <Chips active={filter} onChange={setFilter} options={["All", "Posted", "Draft"].map((s) => ({
          id: s, label: s === "All" ? T("common.all") : TV(s), count: s === "All" ? entries.length : entries.filter((e) => e.status === s).length
        }))} />
        <Btn variant="primary" icon="plus" onClick={() => setShowNew(true)}>{T("je.newEntry")}</Btn>
      </div>
    <section className="card">
      <DataTable rowKey={(r) => r.id} onRow={(r) => setSel(r.id)} rows={visible} empty={T("je.noEntriesMatch")} cols={[
        { k: "id", label: T("common.ref"), w: "100px", render: (r) => <span className="mono strong">{r.id}</span> },
        { k: "date", label: T("common.date"), w: "90px", render: (r) => <span className="dim">{r.date}</span> },
        { k: "memo", label: T("common.description"), render: (r) => <span className="who2"><b>{r.memo}</b><small>{TV(r.source)}</small></span> },
        { k: "lines", label: T("je.lines"), align: "right", w: "70px", render: (r) => <span className="mono">{r.lines.length}</span> },
        { k: "amt", label: T("common.amount"), align: "right", w: "120px", render: (r) => <span className="mono strong">{money(sumD(r))}</span> },
        { k: "status", label: T("common.status"), w: "100px", render: (r) => <Badge tone={r.status === "Posted" ? "green" : "neutral"}>{r.status}</Badge> }
      ]} />

      <Drawer open={!!selEntry} onClose={() => setSel(null)}
        title={selEntry ? selEntry.id : ""} sub={selEntry ? selEntry.date + ", 2026 · " + TV(selEntry.source) : ""}
        footer={selEntry && selEntry.status === "Draft" ? (
          <div className="btnrow"><Btn variant="primary" icon="check" onClick={() => post(selEntry.id)}>{T("je.postEntry")}</Btn></div>
        ) : null}>
        {selEntry ? (
          <div>
            <div className="amount-hero">
              <span className="display">{money(sumD(selEntry))}</span>
              <Badge tone={selEntry.status === "Posted" ? "green" : "neutral"}>{selEntry.status}</Badge>
            </div>
            <KV k={T("common.description")} v={selEntry.memo} />
            <div className="lineitems">
              <div className="li-head">{T("je.lines")}</div>
              <div className="je-lines">
                <div className="je-line head"><span>{T("acct.account")}</span><span>{T("je.debit")}</span><span>{T("je.credit")}</span></div>
                {selEntry.lines.map((l, i) => (
                  <div key={i} className="je-line">
                    <span className="je-acct">{TV(l.acct)}</span>
                    <span className="mono">{l.debit ? money(l.debit) : ""}</span>
                    <span className="mono">{l.credit ? money(l.credit) : ""}</span>
                  </div>
                ))}
                <div className="je-line total">
                  <span>{T("common.total")}</span>
                  <span className="mono strong">{money(sumD(selEntry))}</span>
                  <span className="mono strong">{money(selEntry.lines.reduce((s, l) => s + (l.credit || 0), 0))}</span>
                </div>
              </div>
            </div>
          </div>
        ) : null}
      </Drawer>

      <NewJournalModal open={showNew} onClose={() => setShowNew(false)} onCreate={(entry) => {
        setEntries((es) => [entry, ...es]);
        setShowNew(false);
        notify(entry.status === "Posted" ? T("je.entryPosted", { id: entry.id }) : T("je.entrySavedDraft", { id: entry.id }));
      }} />
    </section></>
  );
}

function NewJournalModal({ open, onClose, onCreate }) {
  const { useState, useEffect } = React;
  const accounts = jeLeaves(D.coa, []);
  const blankLine = () => ({ acct: "", debit: "", credit: "" });
  const [date, setDate] = useState("2026-06-13");
  const [memo, setMemo] = useState("");
  const [lines, setLines] = useState([blankLine(), blankLine()]);
  const [err, setErr] = useState("");

  useEffect(() => {
    if (open) { setDate("2026-06-13"); setMemo(""); setLines([blankLine(), blankLine()]); setErr(""); }
  }, [open]);

  const num = (v) => { const n = parseFloat(v); return isNaN(n) ? 0 : n; };
  const totD = lines.reduce((s, l) => s + num(l.debit), 0);
  const totC = lines.reduce((s, l) => s + num(l.credit), 0);
  const diff = +(totD - totC).toFixed(2);
  const balanced = totD > 0 && diff === 0;

  const setLine = (i, k, v) => setLines((ls) => ls.map((l, j) => {
    if (j !== i) return l;
    const next = { ...l, [k]: v };
    if (k === "debit" && num(v) > 0) next.credit = "";
    if (k === "credit" && num(v) > 0) next.debit = "";
    return next;
  }));

  const make = (status) => {
    const used = lines.filter((l) => l.acct && (num(l.debit) > 0 || num(l.credit) > 0));
    if (!memo.trim()) { setErr(T("je.errDescription")); return; }
    if (used.length < 2) { setErr(T("je.errTwoLines")); return; }
    if (status === "Posted" && !balanced) { setErr(T("je.errMustBalance")); return; }
    onCreate({
      id: "JE-0242", date: prettyDate(date), memo: memo.trim(), source: "Manual", status,
      lines: used.map((l) => ({ acct: l.acct, debit: num(l.debit), credit: num(l.credit) }))
    });
  };

  return (
    <Modal open={open} onClose={onClose} width={760} title={T("je.newEntryTitle")} sub={T("je.newEntrySub")}
      footer={
        <div className="je-foot">
          <div className={"je-balance" + (balanced ? " ok" : totD + totC > 0 ? " bad" : "")}>
            <span>{T("je.debit")} <b className="mono">{money(totD)}</b></span>
            <span>{T("je.credit")} <b className="mono">{money(totC)}</b></span>
            <span className="je-diff">{balanced ? <Icon name="check" size={13} stroke={2.4} /> : null}{balanced ? T("je.balanced") : T("je.differenceOf", { amount: money(Math.abs(diff)) })}</span>
          </div>
          <div className="btnrow">
            <Btn variant="primary" icon="check" onClick={() => make("Posted")} disabled={!balanced}>{T("je.postEntry")}</Btn>
            <Btn onClick={() => make("Draft")}>{T("je.saveDraft")}</Btn>
          </div>
        </div>
      }>
      <div className="formgrid">
        <Field label={T("common.date")}>
          <Input type="date" value={date} onChange={(e) => setDate(e.target.value)} />
        </Field>
        <Field label={T("common.description")}>
          <Input placeholder={T("je.memoPlaceholder")} value={memo} onChange={(e) => setMemo(e.target.value)} />
        </Field>
      </div>

      <div className="formsec">{T("je.lines")}</div>
      <div className="je-edit">
        <div className="je-erow head">
          <span>{T("acct.account")}</span><span>{T("je.debit")}</span><span>{T("je.credit")}</span><span></span>
        </div>
        {lines.map((l, i) => (
          <div key={i} className="je-erow">
            <SearchSelect options={accounts} placeholder={T("je.chooseAccount")} value={l.acct} onChange={(v) => setLine(i, "acct", v)} />
            <Input type="number" min="0" step="0.5" placeholder="0.00" value={l.debit} onChange={(e) => setLine(i, "debit", e.target.value)} />
            <Input type="number" min="0" step="0.5" placeholder="0.00" value={l.credit} onChange={(e) => setLine(i, "credit", e.target.value)} />
            {lines.length > 2 ? (
              <button className="iconbtn" onClick={() => setLines((ls) => ls.filter((_, j) => j !== i))} aria-label={T("acct.removeLine")}>
                <Icon name="x" size={15} />
              </button>
            ) : <span></span>}
          </div>
        ))}
        <Btn small icon="plus" onClick={() => setLines((ls) => [...ls, blankLine()])}>{T("je.addLine")}</Btn>
      </div>
      {err ? <p className="field-err" style={{ marginTop: 10 }}>{err}</p> : null}
    </Modal>
  );
}
window.JournalTab = JournalTab;
