/* Invoices — create, list, manage, PDF */

const Invoices = ({ goTo, invoiceState, setInvoiceState, txState, setTxState, profile, createFrom }) => {
  const [editing, setEditing] = React.useState(null); // invoice obj or "new"

  // Auto-open invoice editor if navigated here with createFrom
  React.useEffect(() => {
    if (createFrom) setEditing("new");
  }, [createFrom]);
  const [filter, setFilter] = React.useState("all"); // all | draft | sent | paid | overdue
  const [search, setSearch] = React.useState("");

  const today = window.CB_DATA.today.toISOString().slice(0, 10);

  // Compute status considering due dates (recompute overdue)
  const invoices = invoiceState.map(inv => {
    if (inv.status === "sent" && inv.dueAt < today) return { ...inv, status: "overdue" };
    return inv;
  });

  const filtered = invoices.filter(i => {
    if (filter !== "all" && i.status !== filter) return false;
    if (search) {
      const q = search.toLowerCase();
      if (!i.client.name.toLowerCase().includes(q) && !i.number.toLowerCase().includes(q)) return false;
    }
    return true;
  }).sort((a, b) => b.issuedAt.localeCompare(a.issuedAt));

  const totals = {
    outstanding: invoices.filter(i => i.status === "sent" || i.status === "overdue")
      .reduce((s, i) => s + invoiceTotal(i), 0),
    overdue: invoices.filter(i => i.status === "overdue")
      .reduce((s, i) => s + invoiceTotal(i), 0),
    paidThisMonth: invoices.filter(i => i.status === "paid" && i.paidAt?.startsWith(today.slice(0, 7)))
      .reduce((s, i) => s + invoiceTotal(i), 0),
    paidYTD: invoices.filter(i => i.status === "paid" && i.paidAt?.startsWith(today.slice(0, 4)))
      .reduce((s, i) => s + invoiceTotal(i), 0),
  };

  const markPaid = async (invId) => {
    const inv = invoices.find(i => i.id === invId);
    try {
      if (window.CB_API) {
        await window.CB_API.markInvoicePaid(invId);
        // Reload both invoices and transactions from the API
        const [updatedInvs, txRes] = await Promise.all([
          window.CB_API.getInvoices(),
          window.CB_API.getTransactions({ limit: 500 }),
        ]);
        setInvoiceState(updatedInvs.map(i => ({
          id: i.id, number: i.number, client: i.client,
          issuedAt: i.issuedAt, dueAt: i.dueAt, paidAt: i.paidAt,
          status: i.status, currency: i.currency, notes: i.notes,
          items: (i.items || []).map(it => ({ desc: it.desc, qty: it.qty, rate: it.rate })),
        })));
        setTxState((txRes?.data || []).map(t => ({
          id: t.id, date: t.date, type: t.type, category: t.category,
          vendor: t.vendor, amount: t.amount, account: t.account,
          note: t.note, status: t.status, receipt: t.receipt,
          needsReview: t.needsReview, autoCategorized: t.autoCategorized,
        })));
      } else {
        setInvoiceState(invs => invs.map(i => i.id === invId ? { ...i, status: "paid", paidAt: today } : i));
      }
      if (inv) window.toast?.({ message: `${inv.number} marked paid — ${CB.fmt(invoiceTotal(inv))} added to income` });
    } catch(e) {
      window.toast?.({ type: "error", message: "Failed to mark paid" });
    }
  };

  const deleteInvoice = async (id) => {
    if (!confirm("Delete this invoice?")) return;
    try {
      if (window.CB_API) await window.CB_API.deleteInvoice(id);
      setInvoiceState(invs => invs.filter(i => i.id !== id));
      window.toast?.({ type: "info", message: "Invoice deleted" });
    } catch(e) {
      window.toast?.({ type: "error", message: "Failed to delete invoice" });
    }
  };

  return (
    <div className="page-fade">
      <div className="page-head">
        <div>
          <h1 className="page-title">Invoices</h1>
          <div className="page-sub">
            {invoices.length} total · {CB.fmt(totals.outstanding, { cents: false })} outstanding
          </div>
        </div>
        <div className="page-actions">
          <button className="btn btn-primary" onClick={() => setEditing("new")}>
            <Icon name="plus" size={14} /> New invoice
          </button>
        </div>
      </div>

      {/* KPIs */}
      <div className="kpi-grid" style={{ gridTemplateColumns: "repeat(4, 1fr)" }}>
        <div className="kpi">
          <div className="kpi-label">Outstanding</div>
          <div className="bignum-sm">{CB.fmt(totals.outstanding, { cents: false })}</div>
          <div style={{ fontSize: 11, color: "var(--muted)" }}>
            {invoices.filter(i => i.status === "sent" || i.status === "overdue").length} unpaid
          </div>
        </div>
        <div className="kpi">
          <div className="kpi-label">Overdue</div>
          <div className="bignum-sm" style={{ color: totals.overdue > 0 ? "var(--expense)" : "var(--ink)" }}>
            {CB.fmt(totals.overdue, { cents: false })}
          </div>
          <div style={{ fontSize: 11, color: "var(--muted)" }}>
            {invoices.filter(i => i.status === "overdue").length} past due
          </div>
        </div>
        <div className="kpi">
          <div className="kpi-label">Paid this month</div>
          <div className="bignum-sm" style={{ color: "var(--income-text)" }}>
            {CB.fmt(totals.paidThisMonth, { cents: false })}
          </div>
          <div style={{ fontSize: 11, color: "var(--muted)" }}>
            {invoices.filter(i => i.status === "paid" && i.paidAt?.startsWith(today.slice(0, 7))).length} payment(s)
          </div>
        </div>
        <div className="kpi">
          <div className="kpi-label">Paid year-to-date</div>
          <div className="bignum-sm">{CB.fmt(totals.paidYTD, { cents: false })}</div>
          <div style={{ fontSize: 11, color: "var(--muted)" }}>
            {invoices.filter(i => i.status === "paid").length} total
          </div>
        </div>
      </div>

      {/* Filters */}
      <div className="filters" style={{ marginTop: 22 }}>
        <div className="search">
          <Icon name="search" size={15} color="var(--muted)" />
          <input placeholder="Search client or invoice #…" value={search} onChange={(e) => setSearch(e.target.value)} />
        </div>
        <div className="segmented">
          <button className={filter === "all" ? "on" : ""} onClick={() => setFilter("all")}>All</button>
          <button className={filter === "draft" ? "on" : ""} onClick={() => setFilter("draft")}>Draft</button>
          <button className={filter === "sent" ? "on" : ""} onClick={() => setFilter("sent")}>Sent</button>
          <button className={filter === "overdue" ? "on" : ""} onClick={() => setFilter("overdue")}>Overdue</button>
          <button className={filter === "paid" ? "on" : ""} onClick={() => setFilter("paid")}>Paid</button>
        </div>
      </div>

      <div className="card" style={{ padding: 0, overflow: "hidden" }}>
        <table className="tbl">
          <thead>
            <tr>
              <th style={{ width: 140 }}>Invoice #</th>
              <th>Client</th>
              <th style={{ width: 110 }}>Issued</th>
              <th style={{ width: 110 }}>Due</th>
              <th style={{ width: 120 }}>Status</th>
              <th style={{ width: 120, textAlign: "right" }}>Amount</th>
              <th style={{ width: 40 }}></th>
            </tr>
          </thead>
          <tbody>
            {filtered.length === 0 && invoices.length === 0 && (
              <tr><td colSpan="7" style={{ padding: 0, border: 0 }}>
                <EmptyState
                  icon="file"
                  title="No invoices yet"
                  subtitle="Create your first invoice — for a sponsorship, brand deal, or any client work. We'll generate a branded PDF and track payment status."
                  action={{ label: "New invoice", icon: "plus", onClick: () => setEditing("new") }}
                />
              </td></tr>
            )}
            {filtered.length === 0 && invoices.length > 0 && (
              <tr><td colSpan="7" className="empty">No invoices match.</td></tr>
            )}
            {filtered.map(inv => (
              <tr key={inv.id} className="row-clickable" onClick={() => setEditing(inv)}>
                <td style={{ fontFamily: "var(--font-mono)", fontSize: 12, color: "var(--ink-soft)" }}>{inv.number}</td>
                <td>
                  <div style={{ fontWeight: 500 }}>{inv.client.name}</div>
                  <div style={{ fontSize: 11.5, color: "var(--muted)" }}>{inv.items.length} item{inv.items.length > 1 ? "s" : ""}</div>
                </td>
                <td style={{ fontSize: 12, color: "var(--ink-soft)" }}>
                  {new Date(inv.issuedAt).toLocaleDateString("en-US", { month: "short", day: "numeric", year: "2-digit" })}
                </td>
                <td style={{ fontSize: 12, color: "var(--ink-soft)" }}>
                  {new Date(inv.dueAt).toLocaleDateString("en-US", { month: "short", day: "numeric", year: "2-digit" })}
                </td>
                <td><InvoiceStatusPill status={inv.status} /></td>
                <td className="num">{CB.fmt(invoiceTotal(inv))}</td>
                <td>
                  <button className="btn btn-ghost btn-sm" onClick={(e) => { e.stopPropagation(); setEditing(inv); }}>
                    <Icon name="chevronRight" size={12} />
                  </button>
                </td>
              </tr>
            ))}
          </tbody>
        </table>
      </div>

      <InvoiceEditor
        invoice={editing === "new" ? null : editing}
        open={!!editing}
        profile={profile}
        initialClient={editing === "new" && createFrom ? { name: createFrom.vendor || "", amount: createFrom.amount || 0, desc: createFrom.note || "Services" } : null}
        onClose={() => setEditing(null)}
        onSave={async (inv) => {
          try {
            const body = {
              number: inv.number,
              clientName: inv.client?.name || "",
              clientEmail: inv.client?.email || undefined,
              clientAddress: inv.client?.address || undefined,
              clientTaxId: inv.client?.taxId || undefined,
              issuedAt: inv.issuedAt,
              dueAt: inv.dueAt,
              status: inv.status,
              currency: inv.currency,
              notes: inv.notes,
              items: (inv.items || []).map(it => ({ description: it.desc || "", qty: it.qty || 1, rate: it.rate || 0 })),
            };
            let saved;
            const isNew = !invoiceState.find(i => i.id === inv.id);
            if (window.CB_API) {
              if (isNew) {
                saved = await window.CB_API.createInvoice(body);
              } else {
                saved = await window.CB_API.updateInvoice(inv.id, body);
              }
              // Normalize API response to frontend shape
              const norm = {
                id: saved.id, number: saved.number, client: saved.client,
                issuedAt: saved.issuedAt, dueAt: saved.dueAt, paidAt: saved.paidAt,
                status: saved.status, currency: saved.currency, notes: saved.notes,
                items: (saved.items || []).map(it => ({ desc: it.desc, qty: it.qty, rate: it.rate })),
              };
              setInvoiceState(invs => {
                const idx = invs.findIndex(i => i.id === norm.id);
                if (idx >= 0) { const copy = [...invs]; copy[idx] = norm; return copy; }
                return [norm, ...invs];
              });
            } else {
              setInvoiceState(invs => {
                const idx = invs.findIndex(i => i.id === inv.id);
                if (idx >= 0) { const copy = [...invs]; copy[idx] = inv; return copy; }
                return [inv, ...invs];
              });
            }
            window.toast?.({ message: `Invoice ${inv.number} ${isNew ? "created" : "updated"}` });
            setEditing(null);
          } catch(e) {
            window.toast?.({ type: "error", message: e?.data?.error || "Failed to save invoice" });
          }
        }}
        onDelete={(id) => { deleteInvoice(id); setEditing(null); }}
        onMarkPaid={(id) => { markPaid(id); setEditing(null); }}
      />
    </div>
  );
};

const InvoiceStatusPill = ({ status }) => {
  const map = {
    draft:   { kind: "",        label: "Draft" },
    sent:    { kind: "primary", label: "Sent" },
    paid:    { kind: "income",  label: "Paid" },
    overdue: { kind: "expense", label: "Overdue" },
  };
  const cfg = map[status] || map.draft;
  return <Pill kind={cfg.kind} dot={status !== "draft"}>{cfg.label}</Pill>;
};

function invoiceTotal(inv) {
  return inv.items.reduce((s, it) => s + (it.qty || 1) * (it.rate || 0), 0);
}

// ─── Editor / create modal ─────────────────────────────────────────
const InvoiceEditor = ({ invoice, open, profile, onClose, onSave, onDelete, onMarkPaid, initialClient }) => {
  const isNew = !invoice;
  const today = window.CB_DATA.today.toISOString().slice(0, 10);
  const blank = () => ({
    id: "inv_" + Date.now(),
    number: "CB-" + new Date().getFullYear() + "-" + String(Math.floor(Math.random() * 900) + 100),
    client: initialClient ? { name: initialClient.name || "", email: initialClient.email || "", address: initialClient.address || "", taxId: initialClient.taxId || "" } : { name: "", email: "", address: "", taxId: "" },
    issuedAt: today,
    dueAt: new Date(Date.now() + 30 * 86400000).toISOString().slice(0, 10),
    paidAt: null,
    status: "draft",
    items: initialClient?.amount ? [{ desc: initialClient.desc || "Services", qty: 1, rate: initialClient.amount }] : [{ desc: "", qty: 1, rate: 0 }],
    notes: "",
  });

  const [draft, setDraft] = React.useState(blank());

  // Saved clients list
  const [savedClients, setSavedClients] = React.useState([]);
  const [clientDropdownOpen, setClientDropdownOpen] = React.useState(false);
  const clientDropdownRef = React.useRef(null);

  React.useEffect(() => {
    if (open && window.CB_API) {
      window.CB_API.getClients().then(setSavedClients).catch(() => {});
    }
  }, [open]);

  // Close dropdown on outside click
  React.useEffect(() => {
    const handler = (e) => { if (clientDropdownRef.current && !clientDropdownRef.current.contains(e.target)) setClientDropdownOpen(false); };
    document.addEventListener("mousedown", handler);
    return () => document.removeEventListener("mousedown", handler);
  }, []);

  const pickClient = (client) => {
    setDraft(d => ({
      ...d,
      client: {
        name: client.name || "",
        email: client.email || "",
        address: client.address || "",
        taxId: client.taxId || "",
      },
    }));
    setClientDropdownOpen(false);
  };

  // Filter saved clients by what's typed in the name field
  const clientMatches = React.useMemo(() => {
    const q = (draft.client.name || "").toLowerCase().trim();
    if (!q) return savedClients;
    return savedClients.filter(c => c.name.toLowerCase().includes(q));
  }, [savedClients, draft.client.name]);

  React.useEffect(() => {
    if (open) setDraft(invoice ? { ...invoice, client: { ...invoice.client }, items: invoice.items.map(i => ({ ...i })) } : blank());
  }, [open, invoice?.id]);

  const updateField = (path, value) => {
    setDraft(d => {
      const copy = { ...d };
      const keys = path.split(".");
      let cur = copy;
      for (let i = 0; i < keys.length - 1; i++) {
        cur[keys[i]] = { ...cur[keys[i]] };
        cur = cur[keys[i]];
      }
      cur[keys[keys.length - 1]] = value;
      return copy;
    });
  };

  const updateItem = (idx, field, value) => {
    setDraft(d => ({ ...d, items: d.items.map((it, i) => i === idx ? { ...it, [field]: value } : it) }));
  };
  const addItem = () => setDraft(d => ({ ...d, items: [...d.items, { desc: "", qty: 1, rate: 0 }] }));
  const removeItem = (idx) => setDraft(d => ({ ...d, items: d.items.filter((_, i) => i !== idx) }));

  const total = invoiceTotal(draft);

  const save = (newStatus) => {
    onSave({ ...draft, status: newStatus || draft.status });
  };

  const downloadPDF = () => {
    if (!window.CB_EXPORT?.buildInvoicePDF) return;
    window.CB_EXPORT.buildInvoicePDF(draft, { profile });
  };
  const printInvoice = () => {
    if (!window.CB_EXPORT?.buildInvoicePDF) return;
    window.CB_EXPORT.buildInvoicePDF(draft, { profile, print: true });
  };

  return (
    <Modal open={open} onClose={onClose}
      maxWidth={720}
      title={isNew ? "New invoice" : draft.number}
      subtitle={isNew ? "Create a new invoice for a client" : `${draft.client.name} · ${CB.fmt(total)}`}
      footer={
        <div style={{ display: "flex", gap: 8, width: "100%", justifyContent: "space-between" }}>
          <div style={{ display: "flex", gap: 6 }}>
            {!isNew && draft.status !== "paid" && (
              <button className="btn btn-ghost btn-sm" onClick={() => onDelete(draft.id)} style={{ color: "var(--expense)" }}>
                Delete
              </button>
            )}
            {!isNew && <button className="btn" onClick={printInvoice}><Icon name="file" size={12} /> Print</button>}
            {!isNew && <button className="btn" onClick={downloadPDF}><Icon name="download" size={12} /> PDF</button>}
          </div>
          <div style={{ display: "flex", gap: 8 }}>
            {draft.status !== "paid" && (
              <button className="btn" onClick={() => onMarkPaid(draft.id)} disabled={isNew}>
                <Icon name="check" size={12} /> Mark paid
              </button>
            )}
            <button className="btn" onClick={() => save("draft")}>Save draft</button>
            <button className="btn btn-primary" onClick={() => save("sent")}>
              {draft.status === "sent" || draft.status === "overdue" ? "Update" : "Save & send"}
            </button>
          </div>
        </div>
      }>
      <div style={{ display: "grid", gridTemplateColumns: "1fr 1fr", gap: 12, marginBottom: 14 }}>
        <div>
          <label className="label">Invoice number</label>
          <input className="input" value={draft.number} onChange={(e) => updateField("number", e.target.value)} />
        </div>
        <div>
          <label className="label">Status</label>
          <div style={{ paddingTop: 6 }}><InvoiceStatusPill status={draft.status} /></div>
        </div>
        <div>
          <label className="label">Issued</label>
          <input className="input" type="date" value={draft.issuedAt} onChange={(e) => updateField("issuedAt", e.target.value)} />
        </div>
        <div>
          <label className="label">Due</label>
          <input className="input" type="date" value={draft.dueAt} onChange={(e) => updateField("dueAt", e.target.value)} />
        </div>
      </div>

      <div className="card-quiet" style={{ padding: 14, marginBottom: 14 }}>
        <div style={{ display: "flex", justifyContent: "space-between", alignItems: "center", marginBottom: 10 }}>
          <div className="label" style={{ margin: 0 }}>Bill to (buyer)</div>
          {savedClients.length > 0 && (
            <div ref={clientDropdownRef} style={{ position: "relative" }}>
              <button className="btn btn-ghost btn-sm" style={{ fontSize: 11 }} type="button"
                onClick={() => setClientDropdownOpen(o => !o)}>
                <Icon name="tag" size={11} /> Saved clients ({savedClients.length})
                <Icon name="chevronDown" size={10} />
              </button>
              {clientDropdownOpen && (
                <div style={{
                  position: "absolute", top: "100%", right: 0, marginTop: 4,
                  background: "var(--surface)", border: "1px solid var(--hairline)",
                  borderRadius: 10, padding: 4, boxShadow: "var(--shadow-2)",
                  zIndex: 20, minWidth: 260, maxHeight: 280, overflowY: "auto",
                }}>
                  {clientMatches.length === 0 && (
                    <div style={{ padding: "10px 12px", fontSize: 12, color: "var(--muted)" }}>No matching clients</div>
                  )}
                  {clientMatches.map(c => (
                    <button key={c.id} className="nav-item" onClick={() => pickClient(c)}
                      style={{ padding: "8px 10px", width: "100%", textAlign: "left" }}>
                      <div style={{ fontWeight: 500, fontSize: 13 }}>{c.name}</div>
                      {(c.email || c.address) && (
                        <div style={{ fontSize: 11, color: "var(--muted)", marginTop: 1 }}>
                          {c.email}{c.email && c.address ? " · " : ""}{c.address ? c.address.slice(0, 40) : ""}
                        </div>
                      )}
                    </button>
                  ))}
                </div>
              )}
            </div>
          )}
        </div>
        <input className="input" placeholder="Client / company name" value={draft.client.name}
          onChange={(e) => updateField("client.name", e.target.value)}
          onFocus={() => { if (savedClients.length > 0 && !draft.client.name) setClientDropdownOpen(true); }}
          style={{ marginBottom: 8 }} />
        <input className="input" placeholder="Email" value={draft.client.email}
          onChange={(e) => updateField("client.email", e.target.value)} style={{ marginBottom: 8 }} />
        <input className="input" placeholder="Address" value={draft.client.address}
          onChange={(e) => updateField("client.address", e.target.value)} style={{ marginBottom: 8 }} />
        <input className="input" placeholder="Tax ID (EIN, VAT, etc.) — optional" value={draft.client.taxId || ""}
          onChange={(e) => updateField("client.taxId", e.target.value)} />
      </div>

      {/* From (seller) — pulled from profile, read-only here */}
      {profile && (
        <div className="card-quiet" style={{ padding: 14, marginBottom: 14, background: "var(--surface-2)" }}>
          <div style={{ display: "flex", justifyContent: "space-between", alignItems: "start", marginBottom: 8 }}>
            <div className="label">From (seller — your business)</div>
            <button className="btn btn-ghost btn-sm" style={{ fontSize: 11 }} type="button"
              onClick={() => {
                // We can't navigate from inside a Modal — just hint where to go
                alert("Edit your seller info in Settings → Profile → Business.");
              }}>
              Edit in Settings <Icon name="chevronRight" size={11} />
            </button>
          </div>
          <div style={{ fontSize: 13.5, fontWeight: 500 }}>{profile.businessName || "—"}</div>
          <div style={{ fontSize: 12.5, color: "var(--ink-soft)", marginTop: 4, lineHeight: 1.6 }}>
            {profile.ownerName && <>{profile.ownerName}<br/></>}
            {profile.addressLine1}{profile.addressLine1 && profile.addressLine2 ? ", " : ""}{profile.addressLine2}
            {profile.country && <>{(profile.addressLine1 || profile.addressLine2) ? " · " : ""}{profile.country}</>}
            {(profile.email || profile.phone) && <><br />{profile.email}{profile.email && profile.phone ? " · " : ""}{profile.phone}</>}
            {profile.taxId && <><br /><b style={{ color: "var(--ink)" }}>{profile.taxIdLabel || "Tax ID"}: {profile.taxId}</b></>}
          </div>
        </div>
      )}

      {/* Line items */}
      <div className="label" style={{ marginBottom: 8 }}>Line items</div>
      <table className="tbl" style={{ border: "1px solid var(--hairline)", borderRadius: 10, overflow: "hidden", marginBottom: 12 }}>
        <thead>
          <tr>
            <th>Description</th>
            <th style={{ width: 70 }}>Qty</th>
            <th style={{ width: 110 }}>Rate</th>
            <th style={{ width: 110, textAlign: "right" }}>Amount</th>
            <th style={{ width: 40 }}></th>
          </tr>
        </thead>
        <tbody>
          {draft.items.map((item, idx) => (
            <tr key={idx}>
              <td style={{ padding: 6 }}>
                <input className="input" placeholder="Description" value={item.desc}
                  onChange={(e) => updateItem(idx, "desc", e.target.value)}
                  style={{ border: "0", padding: "6px 8px", background: "transparent" }} />
              </td>
              <td style={{ padding: 6 }}>
                <input className="input" type="number" value={item.qty}
                  onChange={(e) => updateItem(idx, "qty", parseFloat(e.target.value) || 0)}
                  style={{ border: "0", padding: "6px 8px", background: "transparent", textAlign: "center" }} />
              </td>
              <td style={{ padding: 6 }}>
                <input className="input" type="number" step="0.01" value={item.rate}
                  onChange={(e) => updateItem(idx, "rate", parseFloat(e.target.value) || 0)}
                  style={{ border: "0", padding: "6px 8px", background: "transparent", textAlign: "right", fontFamily: "var(--font-mono)" }} />
              </td>
              <td className="num">{CB.fmt(item.qty * item.rate)}</td>
              <td>
                {draft.items.length > 1 && (
                  <button className="btn btn-ghost btn-sm" onClick={() => removeItem(idx)} aria-label="Remove">
                    <Icon name="close" size={12} />
                  </button>
                )}
              </td>
            </tr>
          ))}
        </tbody>
      </table>
      <button className="btn btn-sm" onClick={addItem}>
        <Icon name="plus" size={12} /> Add line
      </button>

      <div style={{ marginTop: 16, padding: 14, background: "var(--surface-2)", borderRadius: 10,
        display: "flex", justifyContent: "space-between", alignItems: "center" }}>
        <span style={{ fontSize: 13, color: "var(--ink-soft)" }}>Total</span>
        <span style={{ fontFamily: "var(--font-display)", fontSize: 28 }}>{CB.fmt(total)}</span>
      </div>

      <div style={{ marginTop: 14 }}>
        <label className="label">Notes / payment terms (optional)</label>
        <textarea className="input" rows="2" value={draft.notes}
          onChange={(e) => updateField("notes", e.target.value)}
          placeholder="e.g. Net 30. Wire transfer to account ending 4421." />
      </div>
    </Modal>
  );
};

window.Invoices = Invoices;
window.invoiceTotal = invoiceTotal;
