/* ============================================================
   nakad.jsx — Nakad user (sender / status watcher)
   Monitors the pipeline + configures authorised finance emails
   across 40+ businesses. Read-only on approvals.
   ============================================================ */

function NakadApp({ store }) {
  const { docs, businesses, bizById } = store;
  const who = store.user || {};
  const [tab, setTab] = React.useState("docs");
  const [bizFilter, setBizFilter] = React.useState("all");
  const [statusFilter, setStatusFilter] = React.useState("all");
  const [openId, setOpenId] = React.useState(null);

  const open = openId && docs.find((d) => d.id === openId);

  const tabs = [
    { id: "docs", label: "Documents", count: docs.length },
    { id: "biz", label: "Businesses", count: businesses.length },
    { id: "audit", label: "Audit Log" },
  ];

  return (
    <div className="app">
      <AppHeader
        store={store}
        sub="Tally Bridge — Automated Document Posting"
        who={{ av: (who.name || "NK").slice(0, 2).toUpperCase(), name: who.name || "Nakad", role: "Nakad · operations" }}
      />
      <Tabs items={tabs} active={tab} onChange={setTab} />
      <div className="main">
        <div className="container">
          {tab === "docs" && (
            <NakadDocuments
              docs={docs} bizById={bizById} businesses={businesses}
              bizFilter={bizFilter} setBizFilter={setBizFilter}
              statusFilter={statusFilter} setStatusFilter={setStatusFilter}
              onOpen={setOpenId}
            />
          )}
          {tab === "biz" && <NakadBusinesses store={store} />}
          {tab === "audit" && <NakadAudit docs={docs} bizById={bizById} businesses={businesses} />}
        </div>
      </div>
      {open && <NakadDrawer doc={open} biz={bizById(open.biz)} onClose={() => setOpenId(null)} />}
    </div>
  );
}

function NakadDocuments({ docs, bizById, businesses, bizFilter, setBizFilter, statusFilter, setStatusFilter, onOpen }) {
  const [range, setRange] = React.useState("30d");
  let rows = docs.filter((d) => withinRange(d.createdAt, range));
  if (bizFilter !== "all") rows = rows.filter((d) => d.biz === bizFilter);
  if (statusFilter !== "all") rows = rows.filter((d) => d.status === statusFilter);

  const pending = docs.filter((d) => ["received", "validated", "draft", "pending_approval", "approved", "irn_pending", "irn_generated", "irn_failed", "posting", "posted", "post_failed"].includes(d.status)).length;
  const confirmed = docs.filter((d) => d.status === "verified_in_tally").length;

  return (
    <>
      <div className="page-head">
        <div><div className="ph-title">Documents</div><div className="ph-sub">Live status of every debit &amp; credit note you've originated.</div></div>
        <div className="spacer" />
        <div className="row gap16" style={{ marginRight: 4 }}>
          <Stat n={pending} label="In pipeline" />
          <Stat n={confirmed} label="Confirmed" tone="var(--green-fg)" />
        </div>
      </div>

      <div className="toolbar">
        <select className="select" value={bizFilter} onChange={(e) => setBizFilter(e.target.value)}>
          <option value="all">All businesses</option>
          {businesses.map((b) => <option key={b.id} value={b.id}>{b.name}</option>)}
        </select>
        <select className="select" value={statusFilter} onChange={(e) => setStatusFilter(e.target.value)}>
          <option value="all">All statuses</option>
          {Object.keys(STATUS).map((k) => <option key={k} value={k}>{STATUS[k].label}</option>)}
        </select>
        <TimeFilter value={range} onChange={setRange} />
        <div className="spacer" />
      </div>

      <div className="card tbl-wrap">
        <table className="tbl">
          <thead><tr><th>Doc #</th><th>Type</th><th>Business</th><th>Amount</th><th>Status</th><th></th></tr></thead>
          <tbody>
            {rows.map((d) => {
              const biz = bizById(d.biz);
              const hasCN = d.cnNo && d.cnNo !== "—";
              const docNo = hasCN ? d.cnNo : d.dnNo;
              return (
                <tr key={d.id} onClick={() => onOpen(d.id)}>
                  <td className="doc-no">{docNo}</td>
                  <td><span className="type-chip">{hasCN ? "credit_note" : "debit_note"}</span></td>
                  <td><span className="row gap8"><BizAvatar biz={biz} size={24} />{biz.name}</span></td>
                  <td className="amt">{fmtINR(d.amount)}</td>
                  <td><StatusBadge status={d.status} ops /></td>
                  <td style={{ width: 28 }}><Ic.chevron className="row-arrow" /></td>
                </tr>
              );
            })}
            {!rows.length && <tr><td colSpan="6"><div className="empty" style={{ padding: "40px 0" }}><div className="e-s">No documents match this filter.</div></div></td></tr>}
          </tbody>
        </table>
      </div>
    </>
  );
}

function Stat({ n, label, tone }) {
  return (
    <div style={{ textAlign: "right" }}>
      <div style={{ fontSize: 22, fontWeight: 700, fontFamily: "var(--serif)", color: tone || "var(--text)", lineHeight: 1 }}>{n}</div>
      <div className="tiny" style={{ marginTop: 3 }}>{label}</div>
    </div>
  );
}

/* ---- businesses + finance-email config ---------------------------------- */
function NakadBusinesses({ store }) {
  const { businesses, setBizEmail } = store;
  const [edit, setEdit] = React.useState(null);
  const [val, setVal] = React.useState("");

  return (
    <>
      <div className="page-head">
        <div><div className="ph-title">Businesses</div><div className="ph-sub">Authorised finance email per business — only this address can approve their credit notes.</div></div>
        <div className="spacer" />
      </div>

      <div className="hint info mb20">
        <Ic.shield style={{ marginTop: 1, flex: "0 0 15px" }} />
        <div>You manage <b>{businesses.length} businesses</b>. Each needs one authorised finance email. Approvals from any other address are blocked.</div>
      </div>

      <div className="card">
        {businesses.map((b) => (
          <div className="biz-card" key={b.id}>
            <BizAvatar biz={b} size={40} />
            <div style={{ flex: "1 1 auto", minWidth: 0 }}>
              <div className="biz-name">{b.name}</div>
              <div className="biz-meta mono">{b.gst}</div>
            </div>
            <div style={{ flex: "0 0 320px" }}>
              {edit === b.id ? (
                <div className="row gap8">
                  <input className="input email-input grow" value={val} onChange={(e) => setVal(e.target.value)} placeholder="finance@business.in" autoFocus />
                  <button className="btn btn-primary btn-sm" onClick={() => { setBizEmail(b.id, val.trim()); setEdit(null); }}><Ic.check /></button>
                  <button className="btn btn-sm" onClick={() => setEdit(null)}><Ic.x /></button>
                </div>
              ) : b.email ? (
                <div className="row gap10" style={{ justifyContent: "space-between" }}>
                  <span className="row gap8" style={{ color: "var(--text-2)", fontSize: 13.5 }}><Ic.mail style={{ color: "var(--text-3)" }} /><span className="mono">{b.email}</span></span>
                  <button className="btn btn-ghost btn-sm" onClick={() => { setEdit(b.id); setVal(b.email); }}>Edit</button>
                </div>
              ) : (
                <div className="row gap10" style={{ justifyContent: "space-between" }}>
                  <span className="badge amber"><span className="b-dot" />No approver set</span>
                  <button className="btn btn-sm" onClick={() => { setEdit(b.id); setVal(""); }}>Set email</button>
                </div>
              )}
            </div>
            <span className={"badge " + (b.live ? "green" : "gray")} style={{ flex: "0 0 auto", width: 78, justifyContent: "center" }}>
              <span className="b-dot" />{b.live ? "Live" : "Paused"}
            </span>
          </div>
        ))}
      </div>
    </>
  );
}

function fmtAuditTime(iso) {
  if (!iso) return "";
  const d = new Date(iso);
  return d.toLocaleString("en-IN", { day: "2-digit", month: "short", year: "numeric", hour: "2-digit", minute: "2-digit" });
}

function NakadAudit({ docs, bizById, businesses }) {
  const [bizFilter, setBizFilter] = React.useState("all");
  const [q, setQ] = React.useState("");
  const [events, setEvents] = React.useState(null);

  // Real append-only audit trail from audit_events (not reconstructed from status)
  React.useEffect(() => { api.get("/api/audit-log").then((d) => setEvents(d.items)).catch(() => setEvents([])); }, []);

  const term = q.trim().toLowerCase();
  const rows = (events || []).filter((e) =>
    (bizFilter === "all" || String(e.bizId) === String(bizFilter)) &&
    (!term || (e.act || "").toLowerCase().includes(term) ||
      (e.who || "").toLowerCase().includes(term) ||
      JSON.stringify(e.meta || {}).toLowerCase().includes(term))
  );

  return (
    <>
      <div className="page-head"><div><div className="ph-title">Audit Log</div><div className="ph-sub">Every state change across your businesses — who did what, and when.</div></div></div>
      <div className="toolbar">
        <select className="select" value={bizFilter} onChange={(e) => setBizFilter(e.target.value)}>
          <option value="all">All businesses</option>
          {(businesses || []).map((b) => <option key={b.id} value={b.id}>{b.name}</option>)}
        </select>
        <input className="input" style={{ minWidth: 240 }} placeholder="Search by credit note number…" value={q} onChange={(e) => setQ(e.target.value)} />
        <div className="spacer" />
      </div>
      <div className="card card-pad">
        {events === null ? (
          <div className="empty" style={{ padding: "32px 0" }}><div className="e-s">Loading…</div></div>
        ) : rows.length ? (
          <div className="timeline">
            {rows.slice(0, 120).map((e) => (
              <div className="tl-item" key={e.id}>
                <div className="tl-rail"><span className="tl-dot" /><span className="tl-line" /></div>
                <div className="tl-body">
                  <div className="tl-t">
                    {e.act}
                    {e.from && e.to && e.from !== e.to ? (
                      <span style={{ marginLeft: 8, fontSize: 11, fontWeight: 600, color: "var(--muted)", fontFamily: "var(--mono, monospace)" }}>{e.from} → {e.to}</span>
                    ) : null}
                  </div>
                  <div className="tl-meta">{e.who}{e.roleLabel ? " · " + e.roleLabel : ""}{e.biz ? " · " + e.biz : ""} · {fmtAuditTime(e.t)}</div>
                  <DiffView diff={e.diff} />
                  {e.comment && !(e.from && e.to) ? <div className="tiny" style={{ marginTop: 4, color: "var(--muted)" }}>{e.comment}</div> : null}
                </div>
              </div>
            ))}
          </div>
        ) : (
          <div className="empty" style={{ padding: "32px 0" }}><div className="e-s">No audit events match this filter.</div></div>
        )}
      </div>
    </>
  );
}

/* ---- read-only detail drawer (numbering is automatic, no manual box) ----- */
function NakadDrawer({ doc, biz, onClose, admin }) {
  const s = STATUS[doc.status];
  const hasCN = doc.cnNo && doc.cnNo !== "—";
  const [acct, setAcct] = React.useState(null);
  const [detail, setDetail] = React.useState(null);   // enriched doc (lines carry tallyItem + GST)
  const reload = React.useCallback(() => {
    api.get(`/api/credit-notes/${doc.id}`).then((d) => { setAcct(d.accounting); setDetail(d); }).catch(() => {});
  }, [doc.id]);
  React.useEffect(() => {
    if (!hasCN) return;
    reload();
  }, [doc.id, hasCN, reload]);
  const num = acct && acct.numbering;
  const stages = [
    { t: "Debit note fetched via API", k: "done", meta: doc.dnNo + " · " + doc.fetched },
    { t: "Credit note generated", k: STATUS[doc.status].step >= 2 ? "done" : "pending", meta: hasCN ? doc.cnNo : "Awaiting Lekha admin gate" },
    { t: "Portal entry created", k: STATUS[doc.status].step >= 3 ? "done" : "pending", meta: "Linked to " + doc.invoice },
    { t: "Finance team notified", k: STATUS[doc.status].step >= 4 ? "done" : "pending", meta: biz.email || "No approver configured" },
    { t: doc.status === "cancelled" ? "Rejected by finance" : "Finance review", k: doc.status === "cancelled" ? "fail" : STATUS[doc.status].step >= 5 ? "done" : (STATUS[doc.status].step === 4 ? "active" : "pending"), meta: doc.status === "cancelled" ? doc.rejectReason : STATUS[doc.status].step >= 5 ? "Approved" : "Pending" },
    { t: "Posted to Tally", k: STATUS[doc.status].step >= 6 && doc.status !== "cancelled" ? "done" : "pending", meta: "" },
    { t: "Confirmed in Tally", k: doc.status === "verified_in_tally" ? "done" : "pending", meta: "" },
  ];
  return (
    <Drawer
      title={hasCN ? doc.cnNo : doc.dnNo}
      sub={<span className="row gap8"><BizAvatar biz={biz} size={18} />{biz.name} · against {doc.invoice}</span>}
      onClose={onClose}
      center
    >
      <div className="row gap10 mb20" style={{ justifyContent: "space-between" }}>
        <StatusBadge status={doc.status} ops={!admin} />
        <span style={{ fontFamily: "var(--serif)", fontSize: 22, fontWeight: 700 }}>{fmtINR(doc.amount)}</span>
      </div>
      <div className="card card-pad mb20">
        <div className="section-title">Pipeline progress</div>
        <Pipeline status={doc.status} compact />
        <div className="tiny mt12" style={{ marginTop: 12 }}>{s.blurb}</div>
      </div>

      {doc.status === "cancelled" && (
        <div className="hint mb20"><Ic.x style={{ marginTop: 1, flex: "0 0 14px" }} /><div><b>Rejected.</b> {doc.rejectReason}. No further action available from here.</div></div>
      )}

      <div className="card card-pad mb20">
        <div className="row gap8" style={{ justifyContent: "space-between", alignItems: "center", marginBottom: 12 }}>
          <div className="section-title" style={{ marginBottom: 0 }}>Credit note — Tally voucher</div>
          {acct && <PostBadge acct={acct} />}
        </div>
        <CNPreview doc={detail || doc} acct={acct} editable={!!admin} docId={doc.id}
          onSaved={(d) => { setAcct(d.accounting); setDetail(d); }} />
        {acct && acct.ar_impact && (
          <div className="tiny" style={{ marginTop: 10 }}>
            Downstream impact: <b>{acct.ar_impact.ledger}</b> (Accounts Receivable) is reduced by <b>{fmtINR(acct.ar_impact.amount)}</b> — Tally applies this automatically when the voucher posts.
          </div>
        )}
      </div>

      {/* Tally write preview — fed from the Step-5 DRAFT voucher XML: Tally
          ACTUALS only (confirmed stock items, brand-series voucher number).
          Platform naming never appears here. */}
      {acct && (num || (acct.inventory || []).length > 0 || acct.draft_xml) && (
        <div className="card card-pad mb20">
          <div className="section-title">Tally write preview — actuals</div>
          {num && (num.missing ? (
            <div className="hint mb20" style={{ borderColor: "var(--red-fg)" }}>
              <Ic.shield style={{ marginTop: 1, flex: "0 0 14px", color: "var(--red-fg)" }} />
              <div><b>No voucher number.</b> The brand's Tally shows no credit-note series to continue, and numbering is strictly manual — this note will not post until Lekha assigns a number in the brand's own style.</div>
            </div>
          ) : (
            <div className="tiny mb20">
              Voucher number <b className="mono">{num.number}</b> — {num.source === "manual" ? "set manually by Lekha admin" : <>continues the brand's own series{num.last_number ? <> (last in Tally: <span className="mono">{num.last_number}</span>)</> : null}</>}.
            </div>
          ))}
          {acct.draft_xml && (
            <details style={{ marginTop: 12 }}>
              <summary className="tiny" style={{ cursor: "pointer" }}>Draft import XML — exactly what will be sent to Tally</summary>
              <pre className="mono" style={{ fontSize: 11, lineHeight: 1.5, overflowX: "auto", background: "var(--bg)", border: "1px solid var(--border)", borderRadius: 8, padding: 12, marginTop: 8, maxHeight: 320 }}>{acct.draft_xml}</pre>
            </details>
          )}
        </div>
      )}

      <div className="card card-pad">
        <div className="section-title">Timeline</div>
        <div className="timeline">
          {stages.map((st, i) => (
            <div className={"tl-item " + (st.k === "pending" ? "pending" : st.k === "active" ? "active" : "")} key={i}>
              <div className="tl-rail"><span className="tl-dot" style={st.k === "fail" ? { background: "var(--red-fg)", boxShadow: "0 0 0 1.5px var(--red-fg)" } : {}} /><span className="tl-line" /></div>
              <div className="tl-body"><div className="tl-t">{st.t}</div>{st.meta && <div className="tl-meta">{st.meta}</div>}</div>
            </div>
          ))}
        </div>
      </div>

      {/* Real append-only history: every state change + edit, who + what changed */}
      {detail && detail.history ? <EventHistory events={detail.history} title="Full history" /> : null}
    </Drawer>
  );
}

Object.assign(window, { NakadApp, NakadDrawer });
