function NewInvoiceModal({ open, onClose, onCreate, clients, onAddClient }) {
  const { useState, useEffect } = React;
  const blankItem = () => ({ key: Math.random().toString(36).slice(2), desc: "", qty: "1", price: "", tax: "5" });
  const [client, setClient] = useState("");
  const [items, setItems] = useState([blankItem()]);
  const [catalog, setCatalog] = useState(D.catalog);
  const [due, setDue] = useState("2026-07-12");
  const [memo, setMemo] = useState("");
  const [errs, setErrs] = useState({});
  // nested "add" popups
  const [addClient, setAddClient] = useState(null);   // draft object or null
  const [addItem, setAddItem] = useState(null);        // { lineKey, name, price, tax } or null

  useEffect(() => {
    if (open) {
      setClient(""); setItems([blankItem()]); setCatalog(D.catalog);
      setDue("2026-07-12"); setMemo(""); setErrs({});
      setAddClient(null); setAddItem(null);
    }
  }, [open]);

  const lineNet = (it) => (parseFloat(it.qty) || 0) * (parseFloat(it.price) || 0);
  const lineTax = (it) => lineNet(it) * (parseFloat(it.tax) || 0) / 100;
  const subtotal = items.reduce((s, it) => s + lineNet(it), 0);
  const taxTotal = items.reduce((s, it) => s + lineTax(it), 0);
  const total = subtotal + taxTotal;
  // group tax amounts by rate for a clean breakdown
  const taxGroups = (() => {
    const m = {};
    items.forEach((it) => {
      const r = parseFloat(it.tax) || 0;
      const amt = lineTax(it);
      if (r > 0 && amt > 0) m[r] = (m[r] || 0) + amt;
    });
    return Object.keys(m).map((r) => ({ rate: parseFloat(r), amount: m[r] })).sort((a, b) => a.rate - b.rate);
  })();

  const setItem = (key, patch) => setItems((xs) => xs.map((it) => (it.key === key ? { ...it, ...patch } : it)));
  const addItemRow = () => setItems((xs) => [...xs, blankItem()]);
  const removeItem = (key) => setItems((xs) => (xs.length === 1 ? xs : xs.filter((it) => it.key !== key)));
  const pickItem = (key, name) => {
    const hit = catalog.find((c) => c.name === name);
    setItem(key, hit ? { desc: name, price: String(hit.price), tax: String(hit.tax != null ? hit.tax : 5) } : { desc: name });
  };
  const catalogNames = catalog.map((c) => c.name);
  // product info shown in the dropdown — price and its built-in tax rate
  const catalogMeta = catalog.reduce((m, c) => {
    m[c.name] = money(c.price) + " · " + (c.tax ? T("acct.taxPct", { pct: c.tax }) : T("acct.noTax"));
    return m;
  }, {});

  // open the detail popups (instead of adding a bare name)
  const openAddClient = (name) => setAddClient({ name: name || "", contact: "", email: "", phone: "", terms: "Net 30" });
  const saveClient = () => {
    const name = (addClient.name || "").trim();
    if (!name) return;
    onAddClient(name);
    setClient(name);
    setAddClient(null);
    notify(T("acct.clientAdded", { name: name }));
  };
  const openAddItem = (lineKey, name) => setAddItem({ lineKey, name: name || "", price: "", tax: "5" });
  const saveItem = () => {
    const name = (addItem.name || "").trim();
    const price = Math.round(parseFloat(addItem.price) || 0);
    const tax = parseFloat(addItem.tax) || 0;
    if (!name) return;
    setCatalog((cs) => (cs.some((c) => c.name === name) ? cs : [{ name, price, tax }, ...cs]));
    setItem(addItem.lineKey, { desc: name, price: String(price), tax: String(tax) });
    setAddItem(null);
    notify(T("acct.itemAddedToCatalog", { name: name }));
  };

  const validate = () => {
    const e = {};
    if (!client) e.client = T("acct.errChooseClient");
    const filled = items.filter((it) => it.desc.trim() !== "");
    if (filled.length === 0) e.items = T("acct.errNeedLineItem");
    else if (filled.some((it) => lineNet(it) <= 0)) e.items = T("acct.errQtyPriceAboveZero");
    if (!due.trim()) e.due = T("acct.errDueDateRequired");
    setErrs(e);
    return Object.keys(e).length === 0;
  };
  const make = (status) => {
    if (!validate()) return;
    const lines = items.filter((it) => it.desc.trim() !== "").map((it) => ({
      desc: it.desc.trim(), qty: parseFloat(it.qty) || 0, price: Math.round(parseFloat(it.price) || 0),
      tax: parseFloat(it.tax) || 0, amount: Math.round(lineNet(it)), taxAmount: Math.round(lineTax(it))
    }));
    onCreate({
      id: "INV-2091", client, issued: "Jun 12", due: prettyDate(due),
      amount: Math.round(total), status, memo, items: lines
    });
  };

  return (
    <Modal open={open} onClose={onClose} title={T("acct.newInvoice")} sub={T("acct.issuedTodaySub")} width={680}
      footer={
        <div className="je-foot">
          <span className="inv-foot-total">{T("common.total")} <b className="mono">{money(Math.round(total))}</b></span>
          <div className="btnrow">
            <Btn onClick={() => make("Draft")}>{T("acct.saveAsDraft")}</Btn>
            <Btn variant="primary" icon="send" onClick={() => make("Sent")}>{T("acct.sendInvoice")}</Btn>
          </div>
        </div>
      }>
      <Field label={T("common.client")} error={errs.client}>
        <SearchSelect options={clients} placeholder={T("acct.chooseOrAddClient")} value={client}
          onChange={setClient} onCreate={openAddClient} addLabel={T("acct.createClient")} />
      </Field>

      <div className="field">
        <div className="inv-items-head">
          <span className="field-label" style={{ margin: 0 }}>{T("acct.lineItems")}</span>
          {errs.items ? <span className="field-err">{errs.items}</span> : null}
        </div>
        <div className="inv-items">
          <div className="inv-item-row inv-item-headrow">
            <span>{T("common.description")}</span>
            <span className="ta-c">{T("common.qty")}</span>
            <span className="ta-r">{T("acct.unitPrice")}</span>
            <span className="ta-c">{T("acct.taxPercent")}</span>
            <span className="ta-r">{T("common.amount")}</span>
            <span></span>
          </div>
          {items.map((it) => (
            <div className="inv-item-row" key={it.key}>
              <SearchSelect options={catalogNames} value={it.desc} placeholder={T("acct.itemOrServicePlaceholder")} meta={catalogMeta}
                onChange={(name) => pickItem(it.key, name)} onCreate={(name) => openAddItem(it.key, name)}
                addLabel={T("acct.addCustomItem")} />
              <input className="input inv-cell ta-c" type="number" min="0" step="1" value={it.qty}
                onChange={(e) => setItem(it.key, { qty: e.target.value })} />
              <input className="input inv-cell ta-r" type="number" min="0" step="50" placeholder="0.00" value={it.price}
                onChange={(e) => setItem(it.key, { price: e.target.value })} />
              <input className="input inv-cell ta-c" type="number" min="0" step="0.5" value={it.tax}
                onChange={(e) => setItem(it.key, { tax: e.target.value })} title={T("acct.taxRateForItem")} />
              <span className="inv-line-amt mono">{money(Math.round(lineNet(it)))}</span>
              <button type="button" className="inv-del" onClick={() => removeItem(it.key)}
                disabled={items.length === 1} title={T("acct.removeLine")} aria-label={T("acct.removeLine")}>
                <Icon name="trash" size={15} />
              </button>
            </div>
          ))}
        </div>
        <button type="button" className="inv-additem" onClick={addItemRow}>
          <Icon name="plus" size={14} stroke={2.2} />{T("acct.addLineItem")}
        </button>
      </div>

      <div className="inv-totals">
        <div className="inv-trow"><span>{T("common.subtotal")}</span><span className="mono">{money(Math.round(subtotal))}</span></div>
        {taxGroups.length === 0 ? (
          <div className="inv-trow"><span>{T("acct.tax")}</span><span className="mono">{money(0)}</span></div>
        ) : taxGroups.map((g) => (
          <div className="inv-trow" key={g.rate}><span>{T("acct.taxRateRow", { rate: g.rate })}</span><span className="mono">{money(Math.round(g.amount))}</span></div>
        ))}
        <div className="inv-trow inv-total"><span>{T("common.total")}</span><span className="mono strong">{money(Math.round(total))}</span></div>
      </div>

      <div className="formgrid">
        <Field label={T("acct.dueDate")} error={errs.due}>
          <Input type="date" value={due} onChange={(e) => setDue(e.target.value)} />
        </Field>
        <Field label={T("acct.memoOptional")}>
          <Input placeholder={T("acct.memoPlaceholder")} value={memo} onChange={(e) => setMemo(e.target.value)} />
        </Field>
      </div>

      {/* nested: add a new client */}
      <Modal open={!!addClient} onClose={() => setAddClient(null)} z={130} width={460}
        title={T("acct.newClient")} sub={T("acct.newClientSub")}
        footer={
          <div className="btnrow">
            <Btn onClick={() => setAddClient(null)}>{T("common.cancel")}</Btn>
            <Btn variant="primary" icon="plus" onClick={saveClient}>{T("acct.addClient")}</Btn>
          </div>
        }>
        {addClient ? (
          <div>
            <Field label={T("acct.clientName")}>
              <Input placeholder={T("acct.companyOrPerson")} value={addClient.name} autoFocus
                onChange={(e) => setAddClient({ ...addClient, name: e.target.value })} />
            </Field>
            <div className="formgrid">
              <Field label={T("acct.contactPerson")}>
                <Input placeholder={T("acct.contactPersonPlaceholder")} value={addClient.contact}
                  onChange={(e) => setAddClient({ ...addClient, contact: e.target.value })} />
              </Field>
              <Field label={T("common.phone")}>
                <Input placeholder="+1 555 0100" value={addClient.phone}
                  onChange={(e) => setAddClient({ ...addClient, phone: e.target.value })} />
              </Field>
            </div>
            <Field label={T("common.email")}>
              <Input type="email" placeholder="name@company.com" value={addClient.email}
                onChange={(e) => setAddClient({ ...addClient, email: e.target.value })} />
            </Field>
            <Field label={T("acct.paymentTerms")}>
              <SearchSelect options={["Due on receipt", "Net 14", "Net 30", "Net 45", "Net 60"]}
                value={addClient.terms} onChange={(v) => setAddClient({ ...addClient, terms: v })} />
            </Field>
          </div>
        ) : null}
      </Modal>

      {/* nested: add a new catalog item */}
      <Modal open={!!addItem} onClose={() => setAddItem(null)} z={130} width={440}
        title={T("acct.newItem")} sub={T("acct.newItemSub")}
        footer={
          <div className="btnrow">
            <Btn onClick={() => setAddItem(null)}>{T("common.cancel")}</Btn>
            <Btn variant="primary" icon="plus" onClick={saveItem}>{T("acct.addItem")}</Btn>
          </div>
        }>
        {addItem ? (
          <div>
            <Field label={T("acct.itemOrService")}>
              <Input placeholder={T("acct.itemNamePlaceholder")} value={addItem.name} autoFocus
                onChange={(e) => setAddItem({ ...addItem, name: e.target.value })} />
            </Field>
            <div className="formgrid">
              <Field label={T("acct.defaultUnitPrice")}>
                <Input type="number" min="0" step="50" placeholder="0.00" value={addItem.price}
                  onChange={(e) => setAddItem({ ...addItem, price: e.target.value })} />
              </Field>
              <Field label={T("acct.defaultTaxRate")}>
                <Input type="number" min="0" step="0.5" placeholder="0" value={addItem.tax}
                  onChange={(e) => setAddItem({ ...addItem, tax: e.target.value })} />
              </Field>
            </div>
            <p className="formhint">{T("acct.savedToCatalogHint")}</p>
          </div>
        ) : null}
      </Modal>
    </Modal>
  );
}
window.NewInvoiceModal = NewInvoiceModal;
