/* NutriDMS — Inventory & Production workspace (Phase 1 UI).
   Overview KPIs · Items · Lots · Production Runs · Traceability. Reads the
   immutable ledger via window.NutriInventory. Receive / adjust / allocate. */
(function () {
  const { useState: iS, useMemo: iM, useEffect: iE } = React;
  const INV = window.NutriInventory;
  const money = (n) => "$" + (Number(n) || 0).toLocaleString();

  function useInvTick() {
    const [, b] = iS(0);
    iE(() => { const h = () => b(n => n + 1); window.addEventListener("nutridms-inventory", h); return () => window.removeEventListener("nutridms-inventory", h); }, []);
  }

  function Kpi({ label, value, tone, onClick }) {
    return (
      <button className={"inv-kpi" + (tone ? " " + tone : "")} onClick={onClick} disabled={!onClick}>
        <span className="inv-kpi-v">{value}</span><span className="inv-kpi-l">{label}</span>
      </button>
    );
  }

  function LotStatus({ s }) {
    const tone = /available/.test(s) ? "ok" : /quarant|hold/.test(s) ? "warn" : /recall|reject|expired|destroy/.test(s) ? "block" : "info";
    return <span className={"inv-pill " + tone}>{s}</span>;
  }

  /* ── Create Purchase Order drawer ── */
  function PODrawer({ editPO, onClose }) {
    const PO = window.NutriInvPO;
    const orderable = (PO.suppliers() || []).filter((s) => PO.canOrderFrom(s.id));
    const base = editPO || {};
    const [supplierId, setSupplierId] = iS(base.supplierId || (orderable[0] || {}).id || "");
    const [supSearch, setSupSearch] = iS("");
    const [orderDate, setOrderDate] = iS(base.orderDate || new Date().toISOString().slice(0, 10));
    const [expected, setExpected] = iS(base.expected || new Date(Date.now() + 7 * 86400000).toISOString().slice(0, 10));
    const [reference, setReference] = iS(base.reference || "");
    const [paymentTerms, setPaymentTerms] = iS(base.paymentTerms || "Net 30");
    const [owner, setOwner] = iS(base.owner || "");
    const [warehouseId, setWarehouseId] = iS(base.warehouseId || (INV.warehouses()[0] || {}).id || "WH-DRY");
    const [deliverTo, setDeliverTo] = iS(base.deliverTo || "Main kitchen · 24 Harbord St, Toronto ON");
    const [taxMode, setTaxMode] = iS(base.taxMode || "exclusive");
    const [discount, setDiscount] = iS(base.discount || "");
    const [discountType, setDiscountType] = iS(base.discountType || "pct");
    const [notes, setNotes] = iS(base.notes || "");
    const [terms, setTerms] = iS(base.terms || "Goods must match the agreed specification. Damaged or expired stock will be rejected on receipt.");
    const [attachments, setAttachments] = iS(base.attachments || []);
    const [lines, setLines] = iS(base.lines && base.lines.length ? base.lines.map((l) => Object.assign({}, l)) : [{ id: PO.newLineId(), itemId: (INV.items()[0] || {}).id || "", qty: "", unitPrice: "", taxRate: taxMode === "exclusive" ? 13 : 0 }]);
    const setLine = (id, k, v) => setLines((ls) => ls.map((l) => l.id === id ? Object.assign({}, l, { [k]: v }) : l));
    const addLine = () => setLines((ls) => ls.concat([{ id: PO.newLineId(), itemId: (INV.items()[0] || {}).id || "", qty: "", unitPrice: "", taxRate: taxMode === "exclusive" ? 13 : 0 }]));
    const delLine = (id) => setLines((ls) => ls.length > 1 ? ls.filter((l) => l.id !== id) : ls);
    const filteredSup = orderable.filter((s) => !supSearch || (s.name + " " + (s.code || "")).toLowerCase().includes(supSearch.toLowerCase()));
    const sub = lines.reduce((s, l) => s + (Number(l.qty) || 0) * (Number(l.unitPrice) || 0), 0);
    const discAmt = discountType === "pct" ? sub * (Number(discount) || 0) / 100 : (Number(discount) || 0);
    const taxAmt = lines.reduce((s, l) => { const lb = (Number(l.qty) || 0) * (Number(l.unitPrice) || 0); const ld = sub ? lb / sub * discAmt : 0; return s + (lb - ld) * (Number(l.taxRate) || 0) / 100; }, 0);
    const grand = sub - discAmt + taxAmt;
    const valid = supplierId && lines.some((l) => l.itemId && Number(l.qty) > 0);
    const onFiles = (e) => { const fs = Array.from(e.target.files || []).map((f) => ({ name: f.name, size: f.size })); setAttachments((a) => a.concat(fs)); };
    const submit = (status) => {
      const sup2 = PO.getSupplier(supplierId);
      PO.savePO({
        id: base.id, supplierId, supplierName: sup2 ? sup2.name : "", status, orderDate, expected, reference, paymentTerms, owner, warehouseId, deliverTo, taxMode, discount: Number(discount) || 0, discountType, notes, terms, attachments,
        lines: lines.filter((l) => l.itemId && Number(l.qty) > 0).map((l) => {
          const it = INV.getItem(l.itemId);
          return { id: l.id, itemId: l.itemId, itemName: it ? it.name : l.itemId, qty: Number(l.qty), unit: it ? it.unit : "", unitPrice: Number(l.unitPrice) || (it ? it.cost : 0) || 0, taxRate: Number(l.taxRate) || 0, received: Number(l.received) || 0 };
        }),
      });
      try { window.__toast && window.__toast(status === "draft" ? "PO saved as draft" : "PO submitted for approval"); } catch (e) {}
      onClose();
    };
    return ReactDOM.createPortal(
      <div className="inv-scrim" onMouseDown={(e) => e.target === e.currentTarget && onClose()}>
        <div className="inv-drawer inv-drawer-wide">
          <div className="inv-drawer-h"><h3>{base.id ? "Edit purchase order" : "New purchase order"}</h3><button className="inv-x" onClick={onClose}><Icon name="x" size={18} /></button></div>
          <div className="inv-drawer-b">
            <div className="inv-formsec">Vendor &amp; delivery</div>
            <label className="inv-lbl">Vendor</label>
            <div className="inv-search" style={{ marginBottom: 6 }}><Icon name="search" size={14} /><input value={supSearch} onChange={(e) => setSupSearch(e.target.value)} placeholder="Search approved vendors…" /></div>
            <select className="inv-in" value={supplierId} onChange={(e) => setSupplierId(e.target.value)}>
              {filteredSup.length === 0 && <option value="">No matching approved vendors</option>}
              {filteredSup.map((s) => <option key={s.id} value={s.id}>{s.name}{s.code ? " · " + s.code : ""} · {s.leadTime}d lead</option>)}
            </select>
            <div className="inv-row2" style={{ marginTop: 10 }}>
              <div><label className="inv-lbl">Deliver to</label><input className="inv-in" value={deliverTo} onChange={(e) => setDeliverTo(e.target.value)} /></div>
              <div><label className="inv-lbl">Receiving warehouse</label><select className="inv-in" value={warehouseId} onChange={(e) => setWarehouseId(e.target.value)}>{INV.warehouses().map((w) => <option key={w.id} value={w.id}>{w.name}</option>)}</select></div>
            </div>

            <div className="inv-formsec">Order details</div>
            <div className="inv-row2">
              <div><label className="inv-lbl">Reference #</label><input className="inv-in" value={reference} onChange={(e) => setReference(e.target.value)} placeholder="Auto-generated if blank" /></div>
              <div><label className="inv-lbl">Purchasing owner</label><input className="inv-in" value={owner} onChange={(e) => setOwner(e.target.value)} placeholder="e.g. Jordan Bello" /></div>
            </div>
            <div className="inv-row2" style={{ marginTop: 10 }}>
              <div><label className="inv-lbl">Order date</label><input className="inv-in" type="date" value={orderDate} onChange={(e) => setOrderDate(e.target.value)} /></div>
              <div><label className="inv-lbl">Expected delivery</label><input className="inv-in" type="date" value={expected} onChange={(e) => setExpected(e.target.value)} /></div>
            </div>
            <div className="inv-row2" style={{ marginTop: 10 }}>
              <div><label className="inv-lbl">Payment terms</label><select className="inv-in" value={paymentTerms} onChange={(e) => setPaymentTerms(e.target.value)}>{["Due on receipt", "Net 15", "Net 30", "Net 45", "Net 60", "50% deposit"].map((t) => <option key={t} value={t}>{t}</option>)}</select></div>
              <div><label className="inv-lbl">Tax</label><select className="inv-in" value={taxMode} onChange={(e) => { setTaxMode(e.target.value); }}><option value="exclusive">Tax exclusive</option><option value="inclusive">Tax inclusive</option><option value="none">No tax</option></select></div>
            </div>

            <div className="inv-formsec">Items</div>
            <div className="inv-poline inv-poline-h5"><span>Item</span><span>Qty</span><span>Rate</span><span>Tax %</span><span>Amount</span><span /></div>
            {lines.map((l) => {
              const it = INV.getItem(l.itemId); const amt = (Number(l.qty) || 0) * (Number(l.unitPrice) || 0);
              return (
                <div className="inv-poline inv-poline5" key={l.id}>
                  <select className="inv-in sm" value={l.itemId} onChange={(e) => setLine(l.id, "itemId", e.target.value)}>{INV.items().map((x) => <option key={x.id} value={x.id}>{x.name}</option>)}</select>
                  <input className="inv-in sm" type="number" value={l.qty} onChange={(e) => setLine(l.id, "qty", e.target.value)} placeholder="0" />
                  <input className="inv-in sm" type="number" value={l.unitPrice} onChange={(e) => setLine(l.id, "unitPrice", e.target.value)} placeholder={it ? it.cost : "0.00"} />
                  <input className="inv-in sm" type="number" value={l.taxRate} disabled={taxMode === "none"} onChange={(e) => setLine(l.id, "taxRate", e.target.value)} placeholder="0" />
                  <span className="inv-poline-amt">{money(amt)}</span>
                  <button className="inv-x sm" onClick={() => delLine(l.id)}><Icon name="trash-2" size={14} /></button>
                </div>
              );
            })}
            <button className="inv-linkbtn" onClick={addLine} style={{ marginTop: 6 }}>+ Add line</button>

            <div className="inv-po-totals">
              <div className="inv-po-trow"><span>Subtotal</span><b>{money(sub)}</b></div>
              <div className="inv-po-trow"><span>Discount <select className="inv-in xs" value={discountType} onChange={(e) => setDiscountType(e.target.value)}><option value="pct">%</option><option value="amt">$</option></select> <input className="inv-in xs" type="number" value={discount} onChange={(e) => setDiscount(e.target.value)} placeholder="0" /></span><b>−{money(discAmt)}</b></div>
              <div className="inv-po-trow"><span>Tax</span><b>{money(taxAmt)}</b></div>
              <div className="inv-po-trow grand"><span>Total</span><b>{money(grand)}</b></div>
            </div>

            <div className="inv-formsec">Notes &amp; terms</div>
            <label className="inv-lbl">Notes to vendor</label><textarea className="inv-in" rows={2} value={notes} onChange={(e) => setNotes(e.target.value)} placeholder="Optional notes shown on the PO" />
            <label className="inv-lbl" style={{ marginTop: 10 }}>Terms &amp; conditions</label><textarea className="inv-in" rows={2} value={terms} onChange={(e) => setTerms(e.target.value)} />
            <label className="inv-lbl" style={{ marginTop: 10 }}>Attachments</label>
            <label className="inv-attach"><Icon name="paperclip" size={14} /> Attach files<input type="file" multiple style={{ display: "none" }} onChange={onFiles} /></label>
            {attachments.length > 0 && <div className="inv-attach-list">{attachments.map((a, i) => <span key={i} className="inv-attach-chip"><Icon name="file" size={11} /> {a.name}</span>)}</div>}
          </div>
          <div className="inv-drawer-f"><button className="btn ghost" onClick={onClose}>Cancel</button><button className="btn secondary" onClick={() => submit("draft")} disabled={!valid}>Save as draft</button><button className="btn primary" onClick={() => submit("pending_approval")} disabled={!valid}><Icon name="send" size={14} /> Save &amp; submit</button></div>
        </div>
      </div>, document.body);
  }

  /* ── New production run drawer ── */
  function RunDrawer({ onClose }) {
    const PR = window.NutriInvProd;
    const recipes = PR.recipeOptions();
    const [recipeId, setRecipeId] = iS((recipes[0] || {}).id || "");
    const [qty, setQty] = iS(10);
    const preview = recipeId ? PR.planInputs(recipes.find((r) => r.id === recipeId), Number(qty) || 1) : [];
    const blocked = preview.filter((i) => i.missing || i.shortfall > 0 || i.unmapped);
    const submit = () => {
      if (!recipeId) return;
      PR.create(recipeId, Number(qty) || 1, "production");
      try { window.__toast && window.__toast("Production run created — ready to execute"); } catch (e) {}
      onClose();
    };
    return ReactDOM.createPortal(
      <div className="inv-scrim" onMouseDown={(e) => e.target === e.currentTarget && onClose()}>
        <div className="inv-drawer inv-drawer-wide">
          <div className="inv-drawer-h"><h3>New production run</h3><button className="inv-x" onClick={onClose}><Icon name="x" size={18} /></button></div>
          <div className="inv-drawer-b">
            <div className="inv-row2">
              <div><label className="inv-lbl">Approved recipe</label><select className="inv-in" value={recipeId} onChange={(e) => setRecipeId(e.target.value)}>{recipes.length === 0 && <option value="">No approved recipes</option>}{recipes.map((r) => <option key={r.id} value={r.id}>{r.name}</option>)}</select></div>
              <div><label className="inv-lbl">Batch quantity</label><input className="inv-in" type="number" value={qty} onChange={(e) => setQty(e.target.value)} /></div>
            </div>
            <label className="inv-lbl" style={{ marginTop: 12 }}>Material plan (FIFO/FEFO)</label>
            <div className="inv-table-wrap"><table className="inv-table"><thead><tr><th>Ingredient</th><th>Needed</th><th>Status</th></tr></thead>
              <tbody>{preview.map((i, ix) => <tr key={ix}><td>{i.itemName}</td><td>{i.need} {i.unit}</td><td>{i.missing ? <span className="inv-pill block">not stocked</span> : i.shortfall > 0 ? <span className="inv-pill warn">short {i.shortfall}</span> : i.unmapped ? <span className="inv-pill warn">unmapped</span> : <span className="inv-pill ok">allocated</span>}</td></tr>)}</tbody>
            </table></div>
            {blocked.length > 0 && <div className="inv-note warn" style={{ marginTop: 10 }}><Icon name="alert-triangle" size={13} /> {blocked.length} input(s) blocked — resolve stock/mapping before executing.</div>}
          </div>
          <div className="inv-drawer-f"><button className="btn ghost" onClick={onClose}>Cancel</button><button className="btn primary" onClick={submit} disabled={!recipeId}><Icon name="check" size={14} /> Create run</button></div>
        </div>
      </div>, document.body);
  }

  function ItemDrawer({ item, onClose }) {
    const canon = (() => { try { return window.INGREDIENT_ITEMS || []; } catch (e) { return []; } })();
    const vendors = (() => { try { return (window.NutriInvPO ? window.NutriInvPO.suppliers() : []); } catch (e) { return []; } })();
    const [f, setF] = iS(item || { name: "", goods: "goods", brand: "", manufacturer: "", type: "food", unit: "kg", sku: "", sell: "", sellDesc: "", cost: "", costDesc: "", preferredVendor: "", track: true, binTracking: false, invTracking: "none", valuation: "FIFO", reorderPoint: "", dimL: "", dimW: "", dimH: "", dimUnit: "cm", weight: "", weightUnit: "kg", notes: "", canonicalId: "", frontImg: "", rearImg: "" });
    const set = (k, v) => setF(Object.assign({}, f, { [k]: v }));
    const submit = () => {
      if (!f.name.trim()) return;
      INV.saveItem(Object.assign({}, f, { cost: Number(f.cost) || 0, sell: Number(f.sell) || 0, reorderPoint: Number(f.reorderPoint) || 0, status: "active" }));
      try { window.__toast && window.__toast(item ? "Item updated" : "Item created"); } catch (e) {}
      onClose();
    };
    return ReactDOM.createPortal(
      <div className="inv-scrim" onMouseDown={(e) => e.target === e.currentTarget && onClose()}>
        <div className="inv-drawer sup-drawer inv-itemdrawer">
          <div className="inv-drawer-h"><h3>{item ? "Edit item" : "New Item"}</h3><button className="inv-x" onClick={onClose}><Icon name="x" size={18} /></button></div>
          <div className="inv-drawer-b">
            <div className="itm-top">
              <div className="itm-top-fields">
                <div className="sup-frow"><label className="sup-flbl req">Name*</label><div className="sup-fctl"><input className="inv-in" value={f.name} onChange={(e) => set("name", e.target.value)} autoFocus placeholder="Item name" /></div></div>
                <div className="sup-frow"><label className="sup-flbl">Type</label><div className="sup-fctl itm-radios">
                  <label className={"itm-radio" + (f.goods === "goods" ? " on" : "")}><input type="radio" checked={f.goods === "goods"} onChange={() => set("goods", "goods")} /> Goods</label>
                  <label className={"itm-radio" + (f.goods === "service" ? " on" : "")}><input type="radio" checked={f.goods === "service"} onChange={() => set("goods", "service")} /> Service</label>
                </div></div>
                <div className="sup-frow"><label className="sup-flbl">Brand</label><div className="sup-fctl"><input className="inv-in" value={f.brand} onChange={(e) => set("brand", e.target.value)} placeholder="Select or add brand" /></div></div>
                <div className="sup-frow"><label className="sup-flbl">Manufacturer</label><div className="sup-fctl"><input className="inv-in" value={f.manufacturer} onChange={(e) => set("manufacturer", e.target.value)} placeholder="Select or add manufacturer" /></div></div>
              </div>
              <div className="itm-imgbox">
                <div className="itm-imglbl">Front View</div>
                <div className="itm-imgslot"><Icon name="upload" size={16} /> Upload Front Image</div>
                <div className="itm-imglbl">Rear View</div>
                <div className="itm-imgslot"><Icon name="upload" size={16} /> Upload Rear Image</div>
                <div className="itm-imgdrop"><Icon name="upload-cloud" size={20} /><b>Drag &amp; Drop Images</b><span>Up to 15 images, each ≤ 5 MB.</span></div>
              </div>
            </div>

            <div className="itm-sec-h">Item Details</div>
            <div className="inv-row2">
              <div><label className="inv-lbl req">Unit*</label><select className="inv-in" value={f.unit} onChange={(e) => set("unit", e.target.value)}>{["kg", "g", "L", "ml", "ea", "box", "roll", "case", "each"].map((u) => <option key={u} value={u}>{u}</option>)}</select></div>
              <div><label className="inv-lbl">SKU</label><input className="inv-in" value={f.sku} onChange={(e) => set("sku", e.target.value)} /></div>
            </div>
            <div className="inv-row2" style={{ marginTop: 8 }}>
              <div><label className="inv-lbl">Type</label><select className="inv-in" value={f.type} onChange={(e) => set("type", e.target.value)}>{["food", "packaging", "label", "finished", "consumable"].map((t) => <option key={t} value={t}>{t}</option>)}</select></div>
              <div></div>
            </div>

            <label className="itm-check"><input type="checkbox" checked={f.sales !== false} onChange={(e) => set("sales", e.target.checked)} /> <span className="itm-sec-h" style={{ margin: 0 }}>Sales Information</span></label>
            {f.sales !== false && (
              <div className="inv-row2">
                <div><label className="inv-lbl req">Selling Price*</label><div className="itm-money"><span>{f.currency || "CAD"}</span><input className="inv-in" type="number" value={f.sell} onChange={(e) => set("sell", e.target.value)} /></div>
                  <label className="inv-lbl">Description</label><textarea className="inv-in" style={{ minHeight: 54 }} value={f.sellDesc} onChange={(e) => set("sellDesc", e.target.value)} /></div>
                <div><label className="inv-lbl">Sales account</label><select className="inv-in" value={f.salesAcct || "40000"} onChange={(e) => set("salesAcct", e.target.value)}><option value="40000">[ 40000 ] Sales</option></select>
                  <label className="inv-lbl">Tax code</label><input className="inv-in" value={f.taxCode || ""} onChange={(e) => set("taxCode", e.target.value)} placeholder="Select or add" /></div>
              </div>
            )}

            <label className="itm-check"><input type="checkbox" checked={f.purchase !== false} onChange={(e) => set("purchase", e.target.checked)} /> <span className="itm-sec-h" style={{ margin: 0 }}>Purchase Information</span></label>
            {f.purchase !== false && (
              <div className="inv-row2">
                <div><label className="inv-lbl req">Cost Price*</label><div className="itm-money"><span>{f.currency || "CAD"}</span><input className="inv-in" type="number" value={f.cost} onChange={(e) => set("cost", e.target.value)} /></div>
                  <label className="inv-lbl">Description</label><textarea className="inv-in" style={{ minHeight: 54 }} value={f.costDesc} onChange={(e) => set("costDesc", e.target.value)} /></div>
                <div><label className="inv-lbl">Purchase account</label><select className="inv-in" value={f.purchAcct || "51000"} onChange={(e) => set("purchAcct", e.target.value)}><option value="51000">[ 51000 ] Hardware - CGS</option></select>
                  <label className="inv-lbl">Preferred vendor</label><select className="inv-in" value={f.preferredVendor} onChange={(e) => set("preferredVendor", e.target.value)}><option value="">Select</option>{vendors.map((v) => <option key={v.id} value={v.id}>{v.name}</option>)}</select></div>
              </div>
            )}

            <label className="itm-check"><input type="checkbox" checked={f.track !== false} onChange={(e) => set("track", e.target.checked)} /> <span className="itm-sec-h" style={{ margin: 0 }}>Track Inventory for this item</span></label>
            {f.track !== false && (
              <div className="itm-tabbody">
                <div className="inv-note" style={{ background: "var(--gray-50)", color: "var(--gray-600)", marginBottom: 10 }}><Icon name="info" size={13} /> You cannot change tracking once transactions exist for this item.</div>
                <div className="sup-frow"><label className="sup-flbl">Bin location tracking</label><div className="sup-fctl itm-radios">
                  <label className="itm-radio"><input type="radio" checked={f.binTracking === true} onChange={() => set("binTracking", true)} /> Yes</label>
                  <label className="itm-radio"><input type="radio" checked={f.binTracking !== true} onChange={() => set("binTracking", false)} /> No</label></div></div>
                <div className="sup-frow"><label className="sup-flbl">Inventory tracking</label><div className="sup-fctl itm-radios">
                  <label className="itm-radio"><input type="radio" checked={f.invTracking !== "serial"} onChange={() => set("invTracking", "none")} /> None</label>
                  <label className="itm-radio"><input type="radio" checked={f.invTracking === "serial"} onChange={() => set("invTracking", "serial")} /> Serial</label></div></div>
                <div className="inv-row2">
                  <div><label className="inv-lbl req">Inventory valuation*</label><select className="inv-in" value={f.valuation} onChange={(e) => set("valuation", e.target.value)}>{["FIFO", "FEFO", "Weighted average"].map((v) => <option key={v} value={v}>{v}</option>)}</select></div>
                  <div><label className="inv-lbl">Reorder point</label><input className="inv-in" type="number" value={f.reorderPoint} onChange={(e) => set("reorderPoint", e.target.value)} /></div>
                </div>
                {f.type === "food" && (
                  <div><label className="inv-lbl">Map to verified ingredient</label>
                    <select className="inv-in" value={f.canonicalId} onChange={(e) => set("canonicalId", e.target.value)}><option value="">Unmapped (received lots quarantine)</option>{canon.map((c) => <option key={c.id} value={c.id}>{c.name}</option>)}</select>
                    <div className="inv-note warn" style={{ marginTop: 8 }}><Icon name="info" size={13} /> Food items must map to a verified ingredient before their lots can go available.</div>
                  </div>
                )}
              </div>
            )}

            <div className="itm-sec-h">Fulfilment Details</div>
            <div className="inv-row2">
              <div><label className="inv-lbl">Dimensions (L × W × H)</label><div className="itm-dims"><input className="inv-in" value={f.dimL} onChange={(e) => set("dimL", e.target.value)} placeholder="L" /><input className="inv-in" value={f.dimW} onChange={(e) => set("dimW", e.target.value)} placeholder="W" /><input className="inv-in" value={f.dimH} onChange={(e) => set("dimH", e.target.value)} placeholder="H" /><select className="inv-in itm-unit" value={f.dimUnit} onChange={(e) => set("dimUnit", e.target.value)}>{["cm", "in", "m"].map((u) => <option key={u}>{u}</option>)}</select></div></div>
              <div><label className="inv-lbl">Weight</label><div className="itm-dims"><input className="inv-in" value={f.weight} onChange={(e) => set("weight", e.target.value)} /><select className="inv-in itm-unit" value={f.weightUnit} onChange={(e) => set("weightUnit", e.target.value)}>{["kg", "g", "lb", "oz"].map((u) => <option key={u}>{u}</option>)}</select></div></div>
            </div>

            <div className="itm-sec-h">Additional Information</div>
            <label className="inv-lbl">Internal notes</label><textarea className="inv-in" style={{ minHeight: 54 }} value={f.notes} onChange={(e) => set("notes", e.target.value)} />
          </div>
          <div className="inv-drawer-f"><button className="btn ghost" onClick={onClose}>Cancel</button><button className="btn primary" onClick={submit} disabled={!f.name.trim()}><Icon name="check" size={14} /> {item ? "Save" : "Save item"}</button></div>
        </div>
      </div>, document.body);
  }

  /* ── Create/edit price list drawer ── */
  function PriceListDrawer({ pl, onClose }) {
    const PO = window.NutriInvPO;
    const its = (() => { try { return INV.items() || []; } catch (e) { return []; } })();
    // Estimate a recipe/offering cost from its ingredient prices (matched to the
    // verified ingredient library / inventory item cost, portion-weighted).
    const canon = (() => { try { return window.INGREDIENT_ITEMS || []; } catch (e) { return []; } })();
    const ingCost = (nm) => {
      const s = String(nm || "").toLowerCase().split("—")[0].split(",")[0].trim();
      if (!s) return 0;
      const item = its.find((it) => (it.name || "").toLowerCase().includes(s)) || canon.find((c) => (c.name || "").toLowerCase().includes(s));
      const per = item ? (item.cost || (item.nutr && 0) || 0) : 0;
      const m = String(nm).match(/(\d+(?:\.\d+)?)\s*(g|kg|ml|l|ea|each|cup|tbsp|tsp)?/i);
      let qty = m ? parseFloat(m[1]) : 100; const unit = (m && m[2] ? m[2] : "g").toLowerCase();
      const frac = unit === "kg" || unit === "l" ? qty : unit === "g" || unit === "ml" ? qty / 1000 : unit === "cup" ? 0.24 : unit === "tbsp" ? 0.015 : unit === "tsp" ? 0.005 : qty;
      return (per || 0.6) * frac;
    };
    const recipeCost = (r) => { const list = r.ingredients || r.ings || []; const c = list.reduce((s, x) => s + ingCost(typeof x === "string" ? x : (x.name || "")), 0); return Math.round((c || (list.length * 0.85)) * 100) / 100; };
    // Detailed ingredient rows for a recipe: name, qty text, purchase (cost) + sales rate.
    const ingRows = (r) => (r.ingredients || r.ings || []).map((x, i) => {
      const nm = typeof x === "string" ? x : (x.name || "");
      const cost = Math.round(ingCost(nm) * 100) / 100;
      return { id: "ing_" + i, name: nm.split("—")[0].trim(), qty: (nm.split("—")[1] || "").trim(), purchase: cost, sales: Math.round(cost * 2.8 * 100) / 100 };
    });
    const recipes = (() => { try { return (window.RECIPES || []).filter((r) => ["approved", "published"].includes(r.status)); } catch (e) { return []; } })();
    const offerings = (() => { try { return (typeof ofLoad === "function" ? ofLoad() : (window.__offerings || [])) || []; } catch (e) { return []; } })();
    // Selectable sources: approved recipes + all offerings (resolved to their recipe).
    const sources = []
      .concat(recipes.map((r) => ({ id: "rec_" + r.id, name: r.name, kind: "Recipe", recipe: r })))
      .concat(offerings.map((o) => {
        const rid = (o.single && o.single.recipeId) || o.recipeId;
        let rec = rid ? recipes.find((r) => r.id === rid) : null;
        if (!rec) rec = recipes.find((r) => (r.name || "").toLowerCase() === (o.name || o.title || "").toLowerCase().replace(/,?\s*(retail|dinner menu|combo)$/i, "").trim());
        return { id: "off_" + o.id, name: o.name || o.title, kind: (o.type || "Offering"), recipe: rec };
      }));
    const [f, setF] = iS(pl || { name: "", sourceId: "", txnType: "sales", currency: "CAD", marginPct: 65, status: "active", rates: {} });
    const [q, setQ] = iS("");
    const [pick, setPick] = iS(false);
    const set = (k, v) => setF(Object.assign({}, f, { [k]: v }));
    const sel = sources.find((s) => s.id === f.sourceId) || null;
    const selRecipe = sel && sel.recipe;
    const baseRows = selRecipe ? ingRows(selRecipe) : [];
    const rateOf = (r) => { const ov = (f.rates || {})[r.id]; if (ov != null && ov !== "") return Number(ov); return f.txnType === "purchase" ? r.purchase : r.sales; };
    const setRate = (id, v) => setF(Object.assign({}, f, { rates: Object.assign({}, f.rates, { [id]: v }) }));
    const costTot = baseRows.reduce((s, r) => s + r.purchase, 0);
    const priceTot = baseRows.reduce((s, r) => s + rateOf(r), 0);
    const margin = priceTot > 0 ? Math.round(((priceTot - costTot) / priceTot) * 100) : 0;
    const shown = baseRows.filter((r) => !q || r.name.toLowerCase().includes(q.toLowerCase()));
    const submit = () => { if (!selRecipe) return; PO.savePriceList(Object.assign({}, f, { name: (sel && sel.name) || "Price list", items: baseRows.map((r) => ({ itemId: r.id, name: r.name, baseRate: r.purchase, customRate: rateOf(r) })) })); try { window.__toast && window.__toast(pl ? "Price list updated" : "Price list created"); } catch (e) {} onClose(); };
    return ReactDOM.createPortal(
      <div className="inv-scrim" onMouseDown={(e) => e.target === e.currentTarget && onClose()}>
        <div className="inv-drawer sup-drawer inv-itemdrawer">
          <div className="inv-drawer-h"><h3>{pl ? "Edit Price List" : "New Price List"}</h3><button className="inv-x" onClick={onClose}><Icon name="x" size={18} /></button></div>
          <div className="inv-drawer-b">
            <div className="sup-frow"><label className="sup-flbl req">Recipe / offering*</label>
              <div className="sup-fctl" style={{ position: "relative" }}>
                <button className="inv-in pl-picktrigger" onClick={() => setPick((v) => !v)}>
                  {sel ? <span>{sel.name} <span className="pl-kind">{sel.kind}</span></span> : <span className="inv-muted">Select a recipe or offering…</span>}
                  <Icon name="chevron-down" size={16} />
                </button>
                {pick && (
                  <div className="pl-dropdown">
                    <div className="inv-search-sm pl-ddsearch"><Icon name="search" size={13} /><input autoFocus value={q} onChange={(e) => setQ(e.target.value)} placeholder="Search recipes & offerings" /></div>
                    <div className="pl-ddlist">
                      {sources.filter((s) => !q || s.name.toLowerCase().includes(q.toLowerCase())).map((s) => (
                        <button key={s.id} className={"pl-ddrow" + (f.sourceId === s.id ? " on" : "")} onClick={() => { set("sourceId", s.id); setPick(false); setQ(""); }}>
                          <span>{s.name}</span><span className="pl-kind">{s.kind}</span>
                        </button>
                      ))}
                    </div>
                  </div>
                )}
              </div>
            </div>
            <div className="sup-frow"><label className="sup-flbl">Currency</label><div className="sup-fctl"><select className="inv-in" style={{ maxWidth: 160 }} value={f.currency} onChange={(e) => set("currency", e.target.value)}>{["CAD", "USD", "GBP", "EUR", "NGN"].map((c) => <option key={c}>{c}</option>)}</select></div></div>

            {selRecipe ? (
              <div className="pl-rates">
                <div className="pl-pmhead">
                  <div className="itm-sec-h" style={{ margin: 0 }}>Price &amp; margins</div>
                  <div className="pl-toggle">
                    <button className={f.txnType === "sales" ? "on" : ""} onClick={() => set("txnType", "sales")}>Sales price</button>
                    <button className={f.txnType === "purchase" ? "on" : ""} onClick={() => set("txnType", "purchase")}>Purchase price</button>
                  </div>
                </div>
                <div className="pl-summary">
                  <div className="pl-sum"><span>Total cost</span><b>{f.currency} {costTot.toFixed(2)}</b></div>
                  <div className="pl-sum"><span>Total {f.txnType === "purchase" ? "purchase" : "sales"}</span><b>{f.currency} {priceTot.toFixed(2)}</b></div>
                  <div className="pl-sum"><span>Margin</span><b className={"invx-pl-margin " + (margin >= 40 ? "ok" : margin >= 20 ? "warn" : "low")}>{margin}%</b></div>
                </div>
                <div className="inv-search-sm" style={{ margin: "4px 0 8px" }}><Icon name="search" size={13} /><input value={q} onChange={(e) => setQ(e.target.value)} placeholder="Find ingredient" /></div>
                <table className="inv-table pl-ratetable"><thead><tr><th>Ingredient</th><th>Qty</th><th style={{ textAlign: "right" }}>Cost</th><th style={{ textAlign: "right" }}>{f.txnType === "purchase" ? "Purchase" : "Sales"} rate</th></tr></thead>
                  <tbody>{shown.length ? shown.map((r) => (
                    <tr key={r.id}><td>{r.name}</td><td className="inv-muted">{r.qty || "—"}</td><td className="inv-muted" style={{ textAlign: "right" }}>{f.currency} {r.purchase.toFixed(2)}</td>
                      <td style={{ textAlign: "right" }}><div className="pl-rate-in"><span>{f.currency}</span><input className="inv-in" type="number" value={(f.rates || {})[r.id] != null && (f.rates || {})[r.id] !== "" ? (f.rates || {})[r.id] : rateOf(r)} onChange={(e) => setRate(r.id, e.target.value)} /></div></td></tr>
                  )) : <tr><td colSpan={4} className="inv-muted" style={{ textAlign: "center", padding: 20 }}>No ingredients match.</td></tr>}</tbody>
                </table>
              </div>
            ) : (
              <div className="inv-empty" style={{ padding: 28 }}><Icon name="tag" size={26} /><p>Select a recipe or offering to load its ingredient pricing.</p></div>
            )}
          </div>
          <div className="inv-drawer-f"><button className="btn ghost" onClick={onClose}>Cancel</button><button className="btn primary" onClick={submit} disabled={!selRecipe}><Icon name="check" size={14} /> {pl ? "Save" : "Create price list"}</button></div>
        </div>
      </div>, document.body);
  }

  /* ── Create/edit supplier drawer ── */
  function SupplierDrawer({ supplier, onClose }) {
    const PO = window.NutriInvPO;
    const [f, setF] = iS(supplier || { salutation: "", firstName: "", lastName: "", name: "", displayName: "", email: "", workPhone: "", mobile: "", lang: "English", code: "", status: "pending", leadTime: 7, country: "", rating: "", currency: "CAD", taxRate: "", paymentTerms: "Due on Receipt", billing: {}, shipping: {}, contacts: [], remarks: "" });
    const [tab, setTab] = iS("other");
    const set = (k, v) => setF(Object.assign({}, f, { [k]: v }));
    const setAddr = (which, k, v) => setF(Object.assign({}, f, { [which]: Object.assign({}, f[which] || {}, { [k]: v }) }));
    const copyBilling = () => setF(Object.assign({}, f, { shipping: Object.assign({}, f.billing) }));
    const setContact = (i, k, v) => { const cs = (f.contacts || []).slice(); cs[i] = Object.assign({}, cs[i], { [k]: v }); setF(Object.assign({}, f, { contacts: cs })); };
    const addContact = () => setF(Object.assign({}, f, { contacts: [...(f.contacts || []), { salutation: "", firstName: "", lastName: "", email: "", workPhone: "", mobile: "" }] }));
    const rmContact = (i) => setF(Object.assign({}, f, { contacts: (f.contacts || []).filter((_, j) => j !== i) }));
    const displayName = f.displayName || f.name || [f.firstName, f.lastName].filter(Boolean).join(" ") || f.company || "";
    const submit = () => {
      if (!displayName.trim()) { setTab("other"); return; }
      PO.saveSupplier(Object.assign({}, f, { name: displayName.trim(), displayName: displayName.trim(), leadTime: Number(f.leadTime) || 0, rating: Number(f.rating) || 0 }));
      try { window.__toast && window.__toast(supplier ? "Vendor updated" : "Vendor added"); } catch (e) {}
      onClose();
    };
    const CC = ["+1", "+44", "+234", "+91", "+61"];
    const AddrCol = (which, title, extra) => (
      <div className="sup-addr-col">
        <div className="sup-addr-h">{title}{extra}</div>
        <label className="inv-lbl">Attention</label><input className="inv-in" value={(f[which] || {}).attention || ""} onChange={(e) => setAddr(which, "attention", e.target.value)} />
        <label className="inv-lbl">Country / Region</label><input className="inv-in" value={(f[which] || {}).country || ""} onChange={(e) => setAddr(which, "country", e.target.value)} placeholder="Select or type" />
        <label className="inv-lbl">Address</label>
        <input className="inv-in" style={{ marginBottom: 6 }} value={(f[which] || {}).street1 || ""} onChange={(e) => setAddr(which, "street1", e.target.value)} placeholder="Street 1" />
        <input className="inv-in" value={(f[which] || {}).street2 || ""} onChange={(e) => setAddr(which, "street2", e.target.value)} placeholder="Street 2" />
        <div className="inv-row2">
          <div><label className="inv-lbl">City</label><input className="inv-in" value={(f[which] || {}).city || ""} onChange={(e) => setAddr(which, "city", e.target.value)} /></div>
          <div><label className="inv-lbl">State</label><input className="inv-in" value={(f[which] || {}).state || ""} onChange={(e) => setAddr(which, "state", e.target.value)} /></div>
        </div>
        <div className="inv-row2">
          <div><label className="inv-lbl">ZIP Code</label><input className="inv-in" value={(f[which] || {}).zip || ""} onChange={(e) => setAddr(which, "zip", e.target.value)} /></div>
          <div><label className="inv-lbl">Phone</label><input className="inv-in" value={(f[which] || {}).phone || ""} onChange={(e) => setAddr(which, "phone", e.target.value)} /></div>
        </div>
      </div>
    );
    return ReactDOM.createPortal(
      <div className="inv-scrim" onMouseDown={(e) => e.target === e.currentTarget && onClose()}>
        <div className="inv-drawer sup-drawer">
          <div className="inv-drawer-h"><h3>{supplier ? "Edit vendor" : "New vendor"}</h3><button className="inv-x" onClick={onClose}><Icon name="x" size={18} /></button></div>
          <div className="inv-drawer-b">
            <div className="sup-primary">
              <div className="sup-frow"><label className="sup-flbl">Primary contact</label>
                <div className="sup-fctl sup-name3">
                  <select className="inv-in" value={f.salutation} onChange={(e) => set("salutation", e.target.value)}><option value="">Salutation</option>{["Mr.", "Ms.", "Mrs.", "Dr."].map((s) => <option key={s} value={s}>{s}</option>)}</select>
                  <input className="inv-in" value={f.firstName} onChange={(e) => set("firstName", e.target.value)} placeholder="First Name" />
                  <input className="inv-in" value={f.lastName} onChange={(e) => set("lastName", e.target.value)} placeholder="Last Name" />
                </div>
              </div>
              <div className="sup-frow"><label className="sup-flbl">Company Name</label><div className="sup-fctl"><input className="inv-in" value={f.company || ""} onChange={(e) => set("company", e.target.value)} /></div></div>
              <div className="sup-frow"><label className="sup-flbl req">Display Name*</label><div className="sup-fctl"><input className="inv-in" value={f.displayName} onChange={(e) => set("displayName", e.target.value)} placeholder="Select or type to add" /></div></div>
              <div className="sup-frow"><label className="sup-flbl">Email Address</label><div className="sup-fctl"><input className="inv-in" type="email" value={f.email} onChange={(e) => set("email", e.target.value)} /></div></div>
              <div className="sup-frow"><label className="sup-flbl">Phone</label>
                <div className="sup-fctl sup-phone2">
                  <div className="sup-phone"><select className="inv-in sup-cc" value={f.workCc || "+1"} onChange={(e) => set("workCc", e.target.value)}>{CC.map((c) => <option key={c}>{c}</option>)}</select><input className="inv-in" value={f.workPhone} onChange={(e) => set("workPhone", e.target.value)} placeholder="Work Phone" /></div>
                  <div className="sup-phone"><select className="inv-in sup-cc" value={f.mobileCc || "+1"} onChange={(e) => set("mobileCc", e.target.value)}>{CC.map((c) => <option key={c}>{c}</option>)}</select><input className="inv-in" value={f.mobile} onChange={(e) => set("mobile", e.target.value)} placeholder="Mobile" /></div>
                </div>
              </div>
              <div className="sup-frow"><label className="sup-flbl">Vendor Language</label><div className="sup-fctl"><select className="inv-in" value={f.lang} onChange={(e) => set("lang", e.target.value)}>{["English", "French", "Spanish"].map((l) => <option key={l}>{l}</option>)}</select></div></div>
            </div>

            <div className="sup-tabs">
              {[["other", "Other Details"], ["address", "Address"], ["contacts", "Contact Persons"], ["remarks", "Remarks"]].map(([id, l]) => (
                <button key={id} className={"sup-tab" + (tab === id ? " on" : "")} onClick={() => setTab(id)}>{l}</button>
              ))}
            </div>

            {tab === "other" && (
              <div className="sup-tabbody">
                <div className="inv-row2">
                  <div><label className="inv-lbl">Vendor code</label><input className="inv-in" value={f.code} onChange={(e) => set("code", e.target.value)} /></div>
                  <div><label className="inv-lbl">Status</label><select className="inv-in" value={f.status} onChange={(e) => set("status", e.target.value)}>{PO.SUP_STATUS.map((s) => <option key={s} value={s}>{s}</option>)}</select></div>
                </div>
                <div className="inv-row2">
                  <div><label className="inv-lbl">Tax rate</label><input className="inv-in" value={f.taxRate} onChange={(e) => set("taxRate", e.target.value)} placeholder="Select a tax" /></div>
                  <div><label className="inv-lbl">Currency</label><select className="inv-in" value={f.currency} onChange={(e) => set("currency", e.target.value)}>{["CAD", "USD", "GBP", "EUR", "NGN"].map((c) => <option key={c}>{c}</option>)}</select></div>
                </div>
                <div className="inv-row2">
                  <div><label className="inv-lbl">Payment terms</label><select className="inv-in" value={f.paymentTerms} onChange={(e) => set("paymentTerms", e.target.value)}>{["Due on Receipt", "Net 15", "Net 30", "Net 45", "Net 60"].map((c) => <option key={c}>{c}</option>)}</select></div>
                  <div><label className="inv-lbl">Lead time (days)</label><input className="inv-in" type="number" value={f.leadTime} onChange={(e) => set("leadTime", e.target.value)} /></div>
                </div>
                <label className="inv-lbl">Rating (0-5)</label><input className="inv-in" type="number" value={f.rating} onChange={(e) => set("rating", e.target.value)} />
                <div className="inv-note warn" style={{ marginTop: 10 }}><Icon name="shield" size={13} /> Only Approved / Conditional vendors can receive purchase orders. Status changes are written to the audit log.</div>
              </div>
            )}
            {tab === "address" && <div className="sup-tabbody sup-addr">{AddrCol("billing", "Billing Address")}{AddrCol("shipping", "Shipping Address", <button className="sup-copy" onClick={copyBilling}><Icon name="arrow-down" size={12} /> Copy billing</button>)}</div>}
            {tab === "contacts" && (
              <div className="sup-tabbody">
                {(f.contacts || []).map((c, i) => (
                  <div key={i} className="sup-contact">
                    <input className="inv-in" value={c.firstName || ""} onChange={(e) => setContact(i, "firstName", e.target.value)} placeholder="First name" />
                    <input className="inv-in" value={c.lastName || ""} onChange={(e) => setContact(i, "lastName", e.target.value)} placeholder="Last name" />
                    <input className="inv-in" value={c.email || ""} onChange={(e) => setContact(i, "email", e.target.value)} placeholder="Email" />
                    <input className="inv-in" value={c.mobile || ""} onChange={(e) => setContact(i, "mobile", e.target.value)} placeholder="Mobile" />
                    <button className="sup-rm" onClick={() => rmContact(i)} title="Remove"><Icon name="x" size={14} /></button>
                  </div>
                ))}
                <button className="sup-addcontact" onClick={addContact}><Icon name="plus-circle" size={15} /> Add Contact Person</button>
              </div>
            )}
            {tab === "remarks" && <div className="sup-tabbody"><label className="inv-lbl">Remarks (for internal use)</label><textarea className="inv-in" style={{ minHeight: 120, resize: "vertical" }} value={f.remarks} onChange={(e) => set("remarks", e.target.value)} /></div>}
          </div>
          <div className="inv-drawer-f"><button className="btn ghost" onClick={onClose}>Cancel</button><button className="btn primary" onClick={submit} disabled={!displayName.trim()}><Icon name="check" size={14} /> {supplier ? "Save" : "Save vendor"}</button></div>
        </div>
      </div>, document.body);
  }

  function ReceiveDrawer({ onClose }) {
    const [f, setF] = iS({ itemId: (INV.items()[0] || {}).id || "", qty: "", supplierLot: "", warehouseId: "WH-DRY", expiresAt: "", unitCost: "" });
    const set = (k, v) => setF(Object.assign({}, f, { [k]: v }));
    const it = INV.getItem(f.itemId);
    const submit = () => {
      if (!f.itemId || !(Number(f.qty) > 0)) return;
      INV.receive({ itemId: f.itemId, qty: Number(f.qty), unit: it && it.unit, supplierLot: f.supplierLot, warehouseId: f.warehouseId, expiresAt: f.expiresAt ? new Date(f.expiresAt).toISOString() : null, unitCost: Number(f.unitCost) || (it && it.cost), by: "receiving" });
      try { window.__toast && window.__toast("Received — lot created & posted to ledger"); } catch (e) {}
      onClose();
    };
    return ReactDOM.createPortal(
      <div className="inv-scrim" onMouseDown={(e) => e.target === e.currentTarget && onClose()}>
        <div className="inv-drawer">
          <div className="inv-drawer-h"><b>Receive inventory</b><button className="inv-x" onClick={onClose}><Icon name="x" size={18} /></button></div>
          <div className="inv-drawer-b">
            <label className="inv-lbl">Item</label>
            <select className="inv-in" value={f.itemId} onChange={(e) => set("itemId", e.target.value)}>{INV.items().map((x) => <option key={x.id} value={x.id}>{x.name}</option>)}</select>
            <div className="inv-row2">
              <div><label className="inv-lbl">Quantity ({it && it.unit})</label><input className="inv-in" type="number" value={f.qty} onChange={(e) => set("qty", e.target.value)} /></div>
              <div><label className="inv-lbl">Unit cost</label><input className="inv-in" type="number" value={f.unitCost} onChange={(e) => set("unitCost", e.target.value)} placeholder={it && it.cost} /></div>
            </div>
            <label className="inv-lbl">Supplier lot code</label>
            <input className="inv-in" value={f.supplierLot} onChange={(e) => set("supplierLot", e.target.value)} placeholder="SL-1234" />
            <div className="inv-row2">
              <div><label className="inv-lbl">Warehouse</label><select className="inv-in" value={f.warehouseId} onChange={(e) => set("warehouseId", e.target.value)}>{INV.warehouses().map((w) => <option key={w.id} value={w.id}>{w.name}</option>)}</select></div>
              <div><label className="inv-lbl">Expiry date</label><input className="inv-in" type="date" value={f.expiresAt} onChange={(e) => set("expiresAt", e.target.value)} /></div>
            </div>
            {it && (it.type === "food" || it.type === "ingredient") && !it.canonicalId && <div className="inv-note warn"><Icon name="alert-triangle" size={13} /> Unmapped food item — will be received into quarantine.</div>}
          </div>
          <div className="inv-drawer-f"><button className="btn ghost" onClick={onClose}>Cancel</button><button className="btn primary" onClick={submit}><Icon name="download" size={14} /> Receive & post</button></div>
        </div>
      </div>, document.body);
  }

  /* ── Branded PO PDF (VOLANTE-style layout) ── */
  function poPdfHTML(po) {
    const PO = window.NutriInvPO, sup = PO.getSupplier(po.supplierId);
    const rows = (po.lines || []).map((l, i) => "<tr><td>" + (i + 1) + "</td><td><b>" + l.itemName + "</b></td><td class='r'>" + l.qty + " " + (l.unit || "") + "</td><td class='r'>" + money(l.unitPrice) + "</td><td class='r'>" + (l.taxRate || 0) + "%</td><td class='r'>" + money(l.qty * l.unitPrice) + "</td></tr>").join("");
    return "<html><head><title>" + po.number + "</title><style>*{box-sizing:border-box}body{font-family:-apple-system,Segoe UI,Roboto,sans-serif;color:#1a2b22;margin:0;padding:40px}.top{display:flex;justify-content:space-between;align-items:flex-start;border-bottom:3px solid #1B7528;padding-bottom:18px}.brand{font-size:22px;font-weight:800;color:#1B7528}.brand small{display:block;font-size:11px;color:#667;font-weight:600;letter-spacing:.08em;text-transform:uppercase;margin-top:2px}.po-meta{text-align:right}.po-meta h1{margin:0;font-size:26px;letter-spacing:.02em}.po-meta .n{color:#1B7528;font-weight:800}.grid{display:flex;gap:40px;margin:22px 0}.grid > div{flex:1}.lbl{font-size:10px;font-weight:800;letter-spacing:.07em;text-transform:uppercase;color:#8a978f;margin-bottom:5px}table{width:100%;border-collapse:collapse;margin-top:8px;font-size:13px}th{background:#f2f8f4;text-align:left;padding:9px 10px;font-size:10px;text-transform:uppercase;letter-spacing:.05em;color:#4a5c52;border-bottom:2px solid #dCe7df}td{padding:9px 10px;border-bottom:1px solid #eef3ef}td.r,th.r{text-align:right}.tot{margin-top:16px;margin-left:auto;width:280px}.tot .row{display:flex;justify-content:space-between;padding:6px 0;font-size:13px}.tot .grand{border-top:2px solid #1B7528;margin-top:6px;padding-top:10px;font-size:16px;font-weight:800;color:#0f3d24}.notes{margin-top:26px;font-size:12px;color:#556}.sig{display:flex;gap:40px;margin-top:40px}.sig > div{flex:1;border-top:1px solid #c3d0c8;padding-top:6px;font-size:11px;color:#8a978f}@media print{body{padding:0}}</style></head><body>" +
      "<div class='top'><div class='brand'>NutriDMS<small>Purchase Order</small></div><div class='po-meta'><h1>PURCHASE ORDER</h1><div class='n'>" + po.number + "</div><div style='font-size:12px;color:#667;margin-top:4px'>Ref " + (po.reference || "—") + "</div></div></div>" +
      "<div class='grid'><div><div class='lbl'>Vendor</div><b>" + (sup ? sup.name : po.supplierName) + "</b><br>" + (sup && sup.code ? sup.code + "<br>" : "") + (sup && sup.country ? sup.country : "") + "</div>" +
      "<div><div class='lbl'>Deliver to</div>" + (po.deliverTo || "—") + "</div>" +
      "<div><div class='lbl'>Details</div>Order date: " + (po.orderDate || "—") + "<br>Expected: " + (po.expected || "—") + "<br>Payment: " + (po.paymentTerms || "—") + "<br>Owner: " + (po.owner || "—") + "</div></div>" +
      "<table><thead><tr><th>#</th><th>Item</th><th class='r'>Qty</th><th class='r'>Rate</th><th class='r'>Tax</th><th class='r'>Amount</th></tr></thead><tbody>" + rows + "</tbody></table>" +
      "<div class='tot'><div class='row'><span>Subtotal</span><b>" + money(PO.poSubtotal(po)) + "</b></div><div class='row'><span>Discount</span><b>−" + money(PO.poDiscountAmt(po)) + "</b></div><div class='row'><span>Tax</span><b>" + money(PO.poTaxAmt(po)) + "</b></div><div class='row grand'><span>Total</span><b>" + money(PO.poGrand(po)) + "</b></div></div>" +
      (po.notes ? "<div class='notes'><div class='lbl'>Notes</div>" + po.notes + "</div>" : "") +
      (po.terms ? "<div class='notes'><div class='lbl'>Terms &amp; conditions</div>" + po.terms + "</div>" : "") +
      "<div class='sig'><div>Authorized by " + (po.approvedBy || "________________") + "</div><div>Vendor acceptance</div></div></body></html>";
  }

  /* ── PO detail page (Zoho-style) ── */
  function PODetail({ poId, onClose, onEdit }) {
    useInvTick();
    const PO = window.NutriInvPO;
    const po = PO.getPO(poId);
    const [pdf, setPdf] = iS(false);
    if (!po) return null;
    const sup = PO.getSupplier(po.supplierId);
    const nextAction = po.status === "draft" ? { label: "Submit for approval", to: "pending_approval", ic: "send" }
      : po.status === "pending_approval" ? { label: "Approve PO", to: "approved", ic: "check" }
      : po.status === "approved" ? { label: "Send to vendor", to: "sent", ic: "mail" } : null;
    const openLines = (po.lines || []).filter((l) => (Number(l.received) || 0) < (Number(l.qty) || 0));
    const doReceive = () => { const l = openLines[0]; if (l) { PO.receivePOLine(po.id, l.id, { qty: l.qty - (Number(l.received) || 0), supplierLot: "SL-" + Math.floor(Math.random() * 9000 + 1000), warehouseId: po.warehouseId || "WH-DRY", expiresAt: new Date(Date.now() + 14 * 86400000).toISOString() }); try { window.__toast && window.__toast("Received " + l.itemName + " — lot posted to ledger"); } catch (e) {} } };
    const printPdf = () => { const w = window.open("", "_blank"); if (w) { w.document.write(poPdfHTML(po)); w.document.close(); setTimeout(() => w.print(), 300); } };
    return ReactDOM.createPortal(
      <div className="inv-scrim" onMouseDown={(e) => e.target === e.currentTarget && onClose()}>
        <div className="inv-drawer inv-drawer-wide inv-podetail">
          <div className="inv-drawer-h">
            <div><h3>{po.number}</h3><span className="inv-muted">Ref {po.reference || "—"} · {sup ? sup.name : po.supplierName}</span></div>
            <div style={{ display: "flex", gap: 8, alignItems: "center" }}>
              <button className="btn secondary sm" onClick={() => setPdf((v) => !v)}><Icon name="file-text" size={14} /> {pdf ? "Hide PDF view" : "Show PDF view"}</button>
              <button className="btn secondary sm" onClick={printPdf}><Icon name="printer" size={14} /> Print / PDF</button>
              {po.status === "draft" && <button className="btn secondary sm" onClick={() => onEdit(po)}><Icon name="pencil" size={14} /> Edit</button>}
              <button className="inv-x" onClick={onClose}><Icon name="x" size={18} /></button>
            </div>
          </div>
          <div className="inv-drawer-b">
            {nextAction && <div className="inv-po-next"><div><Icon name="info" size={15} /> <b>What's next?</b> This PO is <span className="inv-pill info">{po.status.replace(/_/g, " ")}</span></div><button className="btn primary sm" onClick={() => { PO.setPOStatus(po.id, nextAction.to); try { window.__toast && window.__toast("PO " + po.number + " → " + nextAction.to.replace(/_/g, " ")); } catch (e) {} }}><Icon name={nextAction.ic} size={14} /> {nextAction.label}</button></div>}
            {["approved", "sent", "acknowledged", "partially_received"].includes(po.status) && openLines.length > 0 && <div className="inv-po-next recv"><div><Icon name="download" size={15} /> <b>{openLines.length} line(s)</b> awaiting goods receipt</div><button className="btn primary sm" onClick={doReceive}><Icon name="download" size={14} /> Receive next line</button></div>}

            {pdf ? (
              <div className="inv-pdf-frame" dangerouslySetInnerHTML={{ __html: poPdfHTML(po) }} />
            ) : (
              <React.Fragment>
                <div className="inv-po-metagrid">
                  <div><span className="inv-lbl">Vendor</span><b>{sup ? sup.name : po.supplierName}</b></div>
                  <div><span className="inv-lbl">Deliver to</span><b>{po.deliverTo || "—"}</b></div>
                  <div><span className="inv-lbl">Order date</span><b>{po.orderDate || "—"}</b></div>
                  <div><span className="inv-lbl">Expected</span><b>{po.expected || "—"}</b></div>
                  <div><span className="inv-lbl">Payment terms</span><b>{po.paymentTerms || "—"}</b></div>
                  <div><span className="inv-lbl">Warehouse</span><b>{(INV.warehouses().find((w) => w.id === po.warehouseId) || {}).name || "—"}</b></div>
                </div>
                <div className="inv-po-people">
                  <div><span className="inv-lbl">Submitted by</span><b>{po.submittedBy || "—"}</b><em>{po.submittedAt ? new Date(po.submittedAt).toLocaleDateString() : ""}</em></div>
                  <div><span className="inv-lbl">Approved by</span><b>{po.approvedBy || "Pending"}</b><em>{po.approvedAt ? new Date(po.approvedAt).toLocaleDateString() : ""}</em></div>
                </div>
                <div className="inv-table-wrap" style={{ marginTop: 14 }}><table className="inv-table">
                  <thead><tr><th>Item</th><th>Ordered</th><th>Received</th><th>Rate</th><th>Amount</th></tr></thead>
                  <tbody>{(po.lines || []).map((l) => <tr key={l.id}><td><b>{l.itemName}</b></td><td>{l.qty} {l.unit}</td><td className={((Number(l.received) || 0) >= l.qty) ? "" : "inv-muted"}>{l.received || 0} {l.unit}</td><td>{money(l.unitPrice)}</td><td>{money(l.qty * l.unitPrice)}</td></tr>)}</tbody>
                </table></div>
                <div className="inv-po-totals" style={{ marginLeft: "auto" }}>
                  <div className="inv-po-trow"><span>Subtotal</span><b>{money(PO.poSubtotal(po))}</b></div>
                  <div className="inv-po-trow"><span>Discount</span><b>−{money(PO.poDiscountAmt(po))}</b></div>
                  <div className="inv-po-trow"><span>Tax</span><b>{money(PO.poTaxAmt(po))}</b></div>
                  <div className="inv-po-trow grand"><span>Total</span><b>{money(PO.poGrand(po))}</b></div>
                </div>
                {po.notes && <div className="inv-po-block"><span className="inv-lbl">Notes</span><p>{po.notes}</p></div>}
                {(po.receives || []).length > 0 && (
                  <div className="inv-po-block"><span className="inv-lbl">Receives</span>
                    {po.receives.map((r) => <div key={r.id} className="inv-po-rcv"><Icon name="check-circle-2" size={14} /> <span>{r.qty} {r.unit} of <b>{r.itemName}</b> · lot {r.supplierLot || "—"}</span><em>{new Date(r.at).toLocaleDateString()} · {r.by}</em></div>)}
                  </div>
                )}
              </React.Fragment>
            )}
          </div>
        </div>
      </div>, document.body);
  }

  function TraceDrawer({ lotId, onClose }) {
    const t = INV.traceLot(lotId);
    if (!t) return null;
    return ReactDOM.createPortal(
      <div className="inv-scrim" onMouseDown={(e) => e.target === e.currentTarget && onClose()}>
        <div className="inv-drawer">
          <div className="inv-drawer-h"><b>Trace · {t.lot.internalLot}</b><button className="inv-x" onClick={onClose}><Icon name="x" size={18} /></button></div>
          <div className="inv-drawer-b">
            <div className="inv-trace-head">
              <div className="inv-trace-thumb"><Icon name="layers" size={20} /></div>
              <div><b>{t.lot.itemName}</b><span className="inv-muted">{t.lot.supplierLot ? "Supplier lot " + t.lot.supplierLot + " · " : ""}balance {t.balance} {t.lot.unit}</span></div>
              <LotStatus s={t.lot.status} />
            </div>
            <div className="inv-sec-h">Ledger events</div>
            <div className="inv-timeline">
              {t.events.map((e, i) => (
                <div key={i} className="inv-tl-row">
                  <span className="inv-tl-dot" />
                  <div><b>{e.type.replace(/_/g, " ")}</b><span className="inv-muted">{new Date(e.at).toLocaleString()} · {e.by}{e.ref ? " · " + e.ref : ""}</span></div>
                </div>
              ))}
            </div>
          </div>
        </div>
      </div>, document.body);
  }

  function InventoryWorkspace() {
    useInvTick();
    const app = (typeof useApp === "function") ? useApp() : { page: "inventory", role: "admin" };
    const page = app.page || "inventory";
    const [receiving, setReceiving] = iS(false);
    const [traceId, setTraceId] = iS(null);
    const [poOpen, setPoOpen] = iS(false);
    const [poEdit, setPoEdit] = iS(null);
    const [poDetail, setPoDetail] = iS(null);
    const [itemOpen, setItemOpen] = iS(null);
    const [plOpen, setPlOpen] = iS(null);
    const [supOpen, setSupOpen] = iS(null);
    const [runOpen, setRunOpen] = iS(null);
    const [query, setQuery] = iS("");
    const [invMetric, setInvMetric] = iS("value");
    const [invHover, setInvHover] = iS(null);
    const [statusF, setStatusF] = iS("all");
    const exportPDF = () => {
      const win = window.open("", "_blank"); if (!win) return;
      const rows = INV.items().map((it) => "<tr><td>" + it.name + "</td><td>" + it.type + "</td><td>" + INV.onHand(it.id) + " " + it.unit + "</td><td>" + INV.available(it.id) + "</td><td>$" + (it.cost || 0) + "</td><td>$" + Math.round(INV.onHand(it.id) * (it.cost || 0)) + "</td></tr>").join("");
      const k2 = INV.kpis();
      win.document.write("<html><head><title>Inventory Report</title><style>body{font-family:-apple-system,Segoe UI,Roboto,sans-serif;padding:32px;color:#1a1a1a}h1{margin:0 0 4px}.sub{color:#666;margin-bottom:20px}.k{display:inline-block;margin-right:24px}.k b{font-size:22px;display:block;color:#2E7D32}.k span{font-size:11px;color:#888;text-transform:uppercase}table{width:100%;border-collapse:collapse;margin-top:18px;font-size:13px}th{text-align:left;background:#F3F7F4;padding:8px;border-bottom:2px solid #dCe7df}td{padding:8px;border-bottom:1px solid #eee}@media print{.noprint{display:none}}</style></head><body>" +
        "<h1>Inventory Report</h1><div class='sub'>NutriDMS · " + new Date().toLocaleString() + "</div>" +
        "<div class='k'><b>" + money(k2.totalValue) + "</b><span>Inventory value</span></div><div class='k'><b>" + k2.lotCount + "</b><span>Active lots</span></div><div class='k'><b>" + k2.belowReorder + "</b><span>Below reorder</span></div><div class='k'><b>" + k2.stockouts + "</b><span>Stockouts</span></div>" +
        "<table><thead><tr><th>Item</th><th>Type</th><th>On hand</th><th>Available</th><th>Unit cost</th><th>Value</th></tr></thead><tbody>" + rows + "</tbody></table>" +
        "<button class='noprint' onclick='window.print()' style='margin-top:20px;padding:9px 16px;border:0;border-radius:8px;background:#2E7D32;color:#fff;font-weight:700;cursor:pointer'>Print / Save as PDF</button>" +
        "</body></html>");
      win.document.close();
      try { window.auditPush && window.auditPush({ action: "Exported inventory report (PDF)", by: "inventory", severity: "low", target: "Inventory report" }); } catch (e) {}
    };
    const q = query.trim().toLowerCase();
    const matchItem = (it) => (!q || it.name.toLowerCase().indexOf(q) >= 0 || it.type.indexOf(q) >= 0) && (statusF === "all" || (statusF === "low" && it.reorderPoint && INV.available(it.id) < it.reorderPoint && INV.available(it.id) > 0) || (statusF === "out" && INV.available(it.id) <= 0) || (statusF === "ok" && INV.available(it.id) >= (it.reorderPoint || 0) && INV.available(it.id) > 0));
    iE(() => { if (INV) INV.seedIfEmpty(); }, []);
    if (!INV) return <div className="page"><div className="inv-empty">Inventory engine unavailable.</div></div>;

    const k = INV.kpis();
    const its = INV.items();
    const ls = INV.lots().filter((l) => INV.lotBalance(l.id) > 0);
    const sub = page === "inv-items" ? "items" : page === "inv-lots" ? "lots" : page === "inv-suppliers" ? "suppliers" : page === "inv-po" ? "po" : page === "inv-pricelists" ? "pricelists" : page === "inv-production" ? "production" : page === "inv-trace" ? "trace" : "overview";
    const PO = window.NutriInvPO; iE(() => { if (PO) PO.seedIfEmpty(); }, []);

    return (
      <div className="page inv-ws">
        <div className="page-head">
          <div><h1 className="page-title">Inventory &amp; Production</h1><p className="page-sub">Lots, immutable ledger, FIFO/FEFO allocation and traceability — tied to your verified ingredients.</p></div>
          <div style={{ display: "flex", gap: 8 }}>
            <button className="btn secondary" onClick={() => setTraceId((ls[0] || {}).id || null)} disabled={!ls.length}><Icon name="git-branch" size={15} /> Trace a lot</button>
            {(sub === "items" || sub === "overview") && <button className="btn secondary" onClick={() => setItemOpen({})}><Icon name="plus" size={15} /> New item</button>}
            {sub === "suppliers" && <button className="btn secondary" onClick={() => setSupOpen({})}><Icon name="plus" size={15} /> New supplier</button>}
            {sub === "po" && <button className="btn secondary" onClick={() => setPoOpen(true)}><Icon name="clipboard-list" size={15} /> New PO</button>}
            {sub === "pricelists" && <button className="btn secondary" onClick={() => setPlOpen({})}><Icon name="plus" size={15} /> New price list</button>}
            <button className="btn secondary" onClick={exportPDF}><Icon name="file-down" size={15} /> Export PDF</button>
            <button className="btn primary" onClick={() => setReceiving(true)}><Icon name="download" size={15} /> Receive</button>
          </div>
        </div>

        {(sub === "overview") && (() => {
          const its2 = INV.items();
          const COLORS = ["#6366F1", "#22C7D6", "#A855F7", "#F59E0B", "#10B981", "#EF4444"];
          const onHandUnits = its2.reduce((s, it) => s + INV.onHand(it.id), 0);
          const toReceive = (() => { try { return (window.NutriInvPO ? window.NutriInvPO.pos() : []).filter((p) => ["submitted", "approved", "sent", "partial"].includes(p.status)).reduce((s, p) => s + (p.lines || []).reduce((a, l) => a + (Number(l.qty) || 0), 0), 0); } catch (e) { return 0; } })();
          const active = its2.filter((it) => it.status !== "archived").length;
          const highStock = its2.filter((it) => { const av = INV.available(it.id); return it.reorderPoint ? av > it.reorderPoint * 2 : av > 50; }).length;
          const nearLow = its2.filter((it) => { const av = INV.available(it.id); return it.reorderPoint && av > it.reorderPoint && av <= it.reorderPoint * 2; }).length;
          const lowStock = its2.filter((it) => { const av = INV.available(it.id); return av <= (it.reorderPoint || 0); }).length;
          const sbMax = Math.max(1, highStock, nearLow, lowStock);
          const photo = (it) => it.frontImg || it.image || (it.canonicalId && (window.INGREDIENT_ITEMS || []).find((c) => c.id === it.canonicalId) || {}).image || "";
          const byVal = its2.map((it) => ({ it, v: INV.onHand(it.id) * (it.cost || 0), av: INV.available(it.id) })).sort((a, b) => b.v - a.v);
          const top = byVal.slice(0, 3);
          const turnover = 6.2;
          const KpiBig = ({ label, value, sub, tone }) => (
            <div className={"invx-kpi" + (tone ? " " + tone : "")}>
              <span className="invx-kpi-l">{label}</span>
              <span className="invx-kpi-v">{value} {sub && <em>{sub}</em>}</span>
            </div>
          );
          const Photo = ({ it, size }) => { const src = photo(it); const hue = COLORS[(it.name || "").length % COLORS.length]; return src ? <span className="invx-photo" style={{ backgroundImage: `url("${src}")`, width: size, height: size }} /> : <span className="invx-photo ph" style={{ width: size, height: size, background: hue + "1A", color: hue }}><Icon name={it.type === "packaging" ? "package" : it.type === "label" ? "tag" : "leaf"} size={size * 0.42} /></span>; };
          return (
            <div className="invx">
              <div className="invx-kpis">
                <KpiBig label="Inventory value" value={money(k.totalValue)} sub="on hand" tone="hero" />
                <KpiBig label="Units on hand" value={onHandUnits.toLocaleString()} sub="all items" />
                <KpiBig label="Below reorder" value={k.belowReorder} sub="items" tone={k.belowReorder ? "warn" : ""} />
                <KpiBig label="Turnover rate" value={turnover} sub="last 30 days" />
              </div>
              <div className="invx-grid">
                <div className="invx-card">
                  <div className="invx-h">Overview <span className="invx-muted">This week</span></div>
                  <div className="invx-ov">
                    <div className="invx-ov-row"><span>Total units in stock</span><b>{onHandUnits.toLocaleString()} <em className="up">▲ 10.5%</em></b></div>
                    <div className="invx-ov-row"><span>Active lots on hand</span><b>{k.lotCount} <em className="down">▼ 3.1%</em></b></div>
                    <div className="invx-ov-row"><span>Units to be received</span><b>{toReceive.toLocaleString()}</b></div>
                    <div className="invx-ov-row"><span>Quarantined units</span><b className={k.quarantinedQty ? "warn" : ""}>{Math.round(k.quarantinedQty)}</b></div>
                  </div>
                </div>
                <div className="invx-card">
                  <div className="invx-h">Stock info <a className="invx-link" onClick={() => setPage("inv-items")}>View items</a></div>
                  <div className="invx-stock">
                    <div className="invx-stock-lead"><span>Active items</span><b>{active.toLocaleString()}</b></div>
                    <div className="invx-stock-bars">
                      {[["High stock", highStock, "#6366F1"], ["Near-low", nearLow, "#22C7D6"], ["Low stock", lowStock, "#A855F7"]].map(([l, n, c]) => (
                        <div key={l} className="invx-sb"><b>{n}</b><div className="invx-sb-track"><div className="invx-sb-fill" style={{ height: (n / sbMax * 100) + "%", background: c }} /></div><span>{l}</span></div>
                      ))}
                    </div>
                  </div>
                </div>
                <div className="invx-card">
                  <div className="invx-h">Loraa insights <a className="invx-link" onClick={() => setPage("inv-po")}>View all</a></div>
                  <div className="invx-ai">
                    {top.slice(0, 2).map(({ it, av }) => (
                      <div key={it.id} className="invx-ai-item" onClick={() => setItemOpen(it)}>
                        <Photo it={it} size={104} />
                        <div className="invx-ai-cat">{it.type}</div>
                        <div className="invx-ai-nm">{it.name}</div>
                        <div className="invx-ai-meta">{av} available</div>
                      </div>
                    ))}
                  </div>
                </div>
              </div>
              <div className="invx-grid2">
                <div className="invx-card">
                  <div className="invx-h">Purchase pipeline</div>
                  <table className="invx-so"><thead><tr><th>Status</th><th>POs</th><th>Units</th><th>Value</th></tr></thead>
                    <tbody>{(() => { try { const pos = window.NutriInvPO ? window.NutriInvPO.pos() : []; const groups = ["draft", "submitted", "approved", "received"]; return groups.map((g) => { const gp = pos.filter((p) => p.status === g || (g === "received" && p.status === "partial")); const units = gp.reduce((s, p) => s + (p.lines || []).reduce((a, l) => a + (Number(l.qty) || 0), 0), 0); const val = gp.reduce((s, p) => s + (window.NutriInvPO.poGrand ? window.NutriInvPO.poGrand(p) : 0), 0); return <tr key={g}><td style={{ textTransform: "capitalize" }}>{g}</td><td>{gp.length}</td><td>{units.toLocaleString()}</td><td className="invx-muted">{money(val)}</td></tr>; }); } catch (e) { return <tr><td colSpan={4} className="invx-muted">No purchase orders yet.</td></tr>; } })()}</tbody>
                  </table>
                </div>
                <div className="invx-card">
                  <div className="invx-h">Top value items <a className="invx-link" onClick={() => setPage("inv-items")}>View items</a></div>
                  <div className="invx-top">
                    {top.map(({ it, av }) => { const low = av <= (it.reorderPoint || 0); return (
                      <div key={it.id} className="invx-top-row" onClick={() => setItemOpen(it)}>
                        <Photo it={it} size={44} />
                        <div className="invx-top-main"><b>{it.name}</b><span>{it.type} · {it.unit}</span></div>
                        <span className={"invx-stockpill" + (low ? " low" : "")}>{low ? "Low" : "In"} stock · {av} {it.unit}</span>
                      </div>
                    ); })}
                  </div>
                </div>
              </div>
            </div>
          );
        })()}

        {(sub === "overview") && (() => {
          const its2 = INV.items();
          const MO = ["J", "F", "M", "A", "M", "J", "J", "A", "S", "O", "N", "D"];
          const seed = (n) => { let x = Math.sin(n) * 10000; return x - Math.floor(x); };
          const series = (base, amp, s) => MO.map((_, i) => Math.round(base + Math.sin(i / 2 + s) * amp + (seed(i + s) - 0.5) * amp * 0.7));
          const totalVal = k.totalValue || 1;
          const onHandUnits = its2.reduce((a, it) => a + INV.onHand(it.id), 0);
          const avgCost = onHandUnits ? totalVal / onHandUnits : 0;
          const METRICS = [
            { id: "value", label: "Inventory value", val: money(totalVal), goal: null, tone: "#6366F1", data: series(totalVal / 1000, totalVal / 6000, 1).map((v) => v * 1000), fmt: (v) => money(v) },
            { id: "accuracy", label: "Inventory accuracy", val: "99.8%", goal: "100%", tone: "#10B981", data: series(99.8, 0.12, 2), fmt: (v) => v.toFixed(1) + "%" },
            { id: "turnover", label: "Inventory turnover", val: "6.2", goal: "6.5", tone: "#22C7D6", data: series(6, 1.4, 3), fmt: (v) => v.toFixed(1) },
            { id: "sku", label: "Active SKU count", val: its2.length.toLocaleString(), goal: null, tone: "#A855F7", data: series(its2.length, its2.length * 0.25, 4).map((v) => Math.max(0, v)), fmt: (v) => Math.round(v).toLocaleString() },
            { id: "unitcost", label: "Avg cost / unit", val: money(avgCost), goal: null, tone: "#F59E0B", data: series(avgCost || 12, (avgCost || 12) * 0.18, 5), fmt: (v) => money(v) },
            { id: "fill", label: "Order fill capability", val: "42%", goal: "95%", tone: "#EF4444", data: series(50, 10, 6), fmt: (v) => Math.round(v) + "%" },
            { id: "shrink", label: "Shrinkage", val: "147", goal: "0", tone: "#0EA5B7", data: series(140, 30, 7).map((v) => Math.max(0, v)), fmt: (v) => Math.round(v) },
            { id: "sellthru", label: "Sell-through rate", val: "45.3%", goal: "44.8%", tone: "#EC4899", data: series(45, 4, 8), fmt: (v) => v.toFixed(1) + "%" },
            { id: "perfectorder", label: "Perfect order rate", val: "96.1%", goal: "98%", tone: "#8B5CF6", data: series(96, 1.2, 9), fmt: (v) => v.toFixed(1) + "%" },
          ];
          // Snapshot KPI cards (carrying cost, shrinkage, dead stock, out-of-stocks, GM ROI, days of supply)
          const carrying = Math.round(totalVal * 0.2), dailyCarry = Math.round(carrying / 365 * 12.6), annualCarry = Math.round(carrying * 0.079);
          const deadCount = its2.filter((it) => INV.onHand(it.id) > 0 && INV.available(it.id) >= (it.reorderPoint || 0) * 3).length;
          const outStock = its2.filter((it) => INV.available(it.id) <= 0).length;
          const SNAP = [
            { l: "Carrying cost", v: money(carrying), sub: "20% of value", tone: "#6366F1", dir: null },
            { l: "Annual carrying", v: money(annualCarry), sub: "$" + dailyCarry.toLocaleString() + "/day", tone: "#22C7D6", dir: null },
            { l: "Shrinkage", v: "147", sub: ".52% of sales", tone: "#0EA5B7", dir: "down" },
            { l: "Dead stock", v: deadCount.toLocaleString(), sub: "goal 0%", tone: "#EF4444", dir: "down" },
            { l: "Out of stocks", v: outStock.toLocaleString(), sub: "goal 1.1%", tone: "#F59E0B", dir: outStock > 2 ? "down" : "up" },
            { l: "Gross margin ROI", v: "1.9", sub: "goal 1.7", tone: "#10B981", dir: "up" },
            { l: "Days of supply", v: "66.2", sub: "goal 76", tone: "#A855F7", dir: "down" },
            { l: "Lost sales", v: "33,449", sub: "units / yr", tone: "#B23320", dir: "down" },
          ];
          const sel = (invMetric && METRICS.find((m) => m.id === invMetric)) || METRICS[0];
          const W = 560, H = 150, pad = 24;
          const dmin = Math.min(...sel.data), dmax = Math.max(...sel.data), rng = (dmax - dmin) || 1;
          const px = (i) => pad + i * ((W - pad * 2) / 11);
          const py = (v) => H - pad - ((v - dmin) / rng) * (H - pad * 2);
          const line = sel.data.map((v, i) => (i ? "L" : "M") + px(i).toFixed(1) + " " + py(v).toFixed(1)).join(" ");
          const area = line + ` L${px(11).toFixed(1)} ${H - pad} L${px(0).toFixed(1)} ${H - pad} Z`;
          const [hi, setHi] = [invHover, setInvHover];
          const Gauge = ({ label, avg, goal, max }) => {
            const frac = Math.max(0, Math.min(1, avg / max));
            const ang = -90 + frac * 180, r = 46, cx = 60, cy = 60;
            const rad = (a) => (a * Math.PI) / 180;
            const arc = (a0, a1, col) => { const x0 = cx + r * Math.cos(rad(a0)), y0 = cy + r * Math.sin(rad(a0)), x1 = cx + r * Math.cos(rad(a1)), y1 = cy + r * Math.sin(rad(a1)); return <path d={`M${x0.toFixed(1)} ${y0.toFixed(1)} A${r} ${r} 0 0 1 ${x1.toFixed(1)} ${y1.toFixed(1)}`} fill="none" stroke={col} strokeWidth="12" strokeLinecap="round" />; };
            const gf = Math.max(0, Math.min(1, goal / max));
            return (
              <div className="invx-gauge">
                <div className="invx-gauge-h">{label}</div>
                <svg viewBox="0 0 120 76" className="invx-gauge-svg">
                  {arc(180, 180 + gf * 180, "#EF4444")}
                  {arc(180 + gf * 180, 360, "#10B981")}
                  <line x1="60" y1="60" x2={(60 + 40 * Math.cos(rad(ang))).toFixed(1)} y2={(60 + 40 * Math.sin(rad(ang))).toFixed(1)} stroke="#0F172A" strokeWidth="2.5" strokeLinecap="round" />
                  <circle cx="60" cy="60" r="4" fill="#0F172A" />
                </svg>
                <div className="invx-gauge-v"><b>{avg}</b><span>goal {goal}</span></div>
              </div>
            );
          };
          return (
            <div className="invx invx-analytics">
              <div className="invx-card invx-trend">
                <div className="invx-snap-band">
                  {SNAP.map((s, i) => (
                    <div key={i} className="invx-snap">
                      <span className="invx-snap-l">{s.l}</span>
                      <span className="invx-snap-v" style={{ color: s.tone }}>{s.v}{s.dir && <em className={s.dir}>{s.dir === "up" ? "▲" : "▼"}</em>}</span>
                      <span className="invx-snap-s">{s.sub}</span>
                    </div>
                  ))}
                </div>
                <div className="invx-h">Inventory analytics <span className="invx-muted">12-month trend</span></div>
                <div className="invx-metric-tabs">
                  {METRICS.map((m) => (
                    <button key={m.id} className={"invx-mtab" + (sel.id === m.id ? " on" : "")} onClick={() => setInvMetric(m.id)} style={sel.id === m.id ? { borderColor: m.tone, color: m.tone } : null}>
                      <span className="invx-mtab-l">{m.label}</span>
                      <span className="invx-mtab-v">{m.val}{m.goal && <em>/ {m.goal}</em>}</span>
                    </button>
                  ))}
                </div>
                <div className="invx-chart">
                  <svg viewBox={`0 0 ${W} ${H}`} preserveAspectRatio="none" className="invx-svg" onMouseLeave={() => setInvHover(null)}>
                    <defs><linearGradient id="invxg" x1="0" y1="0" x2="0" y2="1"><stop offset="0" stopColor={sel.tone} stopOpacity="0.28" /><stop offset="1" stopColor={sel.tone} stopOpacity="0" /></linearGradient></defs>
                    {[0, 0.5, 1].map((g) => <line key={g} x1={pad} y1={pad + g * (H - pad * 2)} x2={W - pad} y2={pad + g * (H - pad * 2)} stroke="#EEF1F6" strokeWidth="1" />)}
                    <path d={area} fill="url(#invxg)" />
                    <path d={line} fill="none" stroke={sel.tone} strokeWidth="2.5" strokeLinejoin="round" />
                    {sel.data.map((v, i) => <g key={i}><circle cx={px(i)} cy={py(v)} r={hi === i ? 5 : 3} fill="#fff" stroke={sel.tone} strokeWidth="2" /><rect x={px(i) - 22} y="0" width="44" height={H} fill="transparent" onMouseEnter={() => setInvHover(i)} /></g>)}
                    {hi != null && <g><line x1={px(hi)} y1={pad} x2={px(hi)} y2={H - pad} stroke={sel.tone} strokeWidth="1" strokeDasharray="3 3" /></g>}
                  </svg>
                  <div className="invx-xaxis">{MO.map((m, i) => <span key={i} className={hi === i ? "on" : ""}>{m}</span>)}</div>
                  {hi != null && <div className="invx-tip" style={{ left: (px(hi) / W * 100) + "%", borderColor: sel.tone }}><b>{sel.fmt(sel.data[hi])}</b><span>{["Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"][hi]}</span></div>}
                </div>
              </div>
              <div className="invx-gauges">
                <Gauge label="Inventory turns · COGS" avg={5} goal={5.1} max={15} />
                <Gauge label="Inventory turns · sales" avg={7.9} goal={8.1} max={15} />
                <Gauge label="Avg days to sell" avg={44} goal={44} max={120} />
              </div>
            </div>
          );
        })()}

        {false && (sub === "overview") && (() => {
          const its2 = INV.items();
          const typeRows = Object.keys(byType).map((t) => ({ label: t, value: Math.round(byType[t]) })).filter((r) => r.value > 0).sort((a, b) => b.value - a.value);
          const typeTotal = typeRows.reduce((s, r) => s + r.value, 0) || 1;
          const COLORS = ["#2E7D32", "#2748B0", "#C77700", "#8E44AD", "#0E8F9E", "#B23320", "#5B7083"];
          const whRows = INV.warehouses().map((w) => { let v = 0; INV.lots().forEach((l) => { if (l.warehouseId === w.id) v += INV.lotBalance(l.id) * (l.unitCost || 0); }); return { label: w.name, value: Math.round(v) }; }).filter((r) => r.value > 0);
          const whMax = Math.max(1, ...whRows.map((r) => r.value));
          const exp = window.NutriInvOps ? window.NutriInvOps.expirationReport() : null;
          const expRows = exp ? [["Expired", exp.buckets.expired.length, "#B23320"], ["≤7 days", exp.buckets.d7.length, "#C77700"], ["≤30 days", exp.buckets.d30.length, "#E0A800"], ["≤90 days", exp.buckets.d90.length, "#2748B0"], ["Healthy", exp.buckets.ok.length, "#2E7D32"]] : [];
          const expMax = Math.max(1, ...expRows.map((r) => r[1]));
          // Donut geometry
          let acc = 0; const R = 52, C = 2 * Math.PI * R;
          return (
            <div className="inv-charts">
              <div className="inv-card inv-chart-card">
                <div className="inv-card-h">Inventory value by type</div>
                <div className="inv-donut-wrap">
                  <svg viewBox="0 0 130 130" className="inv-donut">
                    {typeRows.map((r, i) => { const frac = r.value / typeTotal; const dash = frac * C; const seg = <circle key={i} cx="65" cy="65" r={R} fill="none" stroke={COLORS[i % COLORS.length]} strokeWidth="18" strokeDasharray={dash + " " + (C - dash)} strokeDashoffset={-acc * C} transform="rotate(-90 65 65)" />; acc += frac; return seg; })}
                    <text x="65" y="61" textAnchor="middle" className="inv-donut-v">{money(typeTotal)}</text>
                    <text x="65" y="77" textAnchor="middle" className="inv-donut-l">total value</text>
                  </svg>
                  <div className="inv-legend">{typeRows.map((r, i) => <div key={i} className="inv-legend-row"><span className="inv-dot" style={{ background: COLORS[i % COLORS.length] }} /><span className="inv-legend-lbl">{r.label}</span><b>{money(r.value)}</b></div>)}</div>
                </div>
              </div>
              <div className="inv-card inv-chart-card">
                <div className="inv-card-h">Value by warehouse</div>
                <div className="inv-bars">{whRows.map((r, i) => <div key={i} className="inv-bar-row"><span className="inv-bar-lbl">{r.label}</span><div className="inv-bar-track"><div className="inv-bar-fill" style={{ width: (r.value / whMax * 100) + "%", background: COLORS[i % COLORS.length] }} /></div><b>{money(r.value)}</b></div>)}</div>
              </div>
              <div className="inv-card inv-chart-card">
                <div className="inv-card-h">Expiry risk</div>
                <div className="inv-exp-bars">{expRows.map((r, i) => <div key={i} className="inv-exp-col"><div className="inv-exp-track"><div className="inv-exp-fill" style={{ height: (r[1] / expMax * 100) + "%", background: r[2] }} /></div><b>{r[1]}</b><span>{r[0]}</span></div>)}</div>
              </div>
            </div>
          );
        })()}

        {false && (sub === "overview") && (
          <div className="inv-kpis">
            <Kpi label="Inventory value" value={money(k.totalValue)} />
            <Kpi label="Active lots" value={k.lotCount} />
            <Kpi label="Items" value={k.itemCount} />
            <Kpi label="Below reorder" value={k.belowReorder} tone={k.belowReorder ? "warn" : ""} />
            <Kpi label="Stockouts" value={k.stockouts} tone={k.stockouts ? "block" : ""} />
            <Kpi label="Quarantined" value={Math.round(k.quarantinedQty)} tone={k.quarantinedQty ? "warn" : ""} />
            <Kpi label="Expiring ≤7d" value={k.expiring7} tone={k.expiring7 ? "block" : ""} />
            <Kpi label="Expiring ≤30d" value={k.expiring30} tone={k.expiring30 ? "warn" : ""} />
          </div>
        )}

        {(sub === "items") && (
          <div className="inv-card">
            <div className="inv-card-h">Items
              <div className="inv-filters">
                <div className="inv-search"><Icon name="search" size={14} /><input value={query} onChange={(e) => setQuery(e.target.value)} placeholder="Search items…" /></div>
                <select className="inv-filter-sel" value={statusF} onChange={(e) => setStatusF(e.target.value)}>
                  <option value="all">All statuses</option><option value="ok">In stock</option><option value="low">Low</option><option value="out">Stockout</option>
                </select>
              </div>
            </div>
            <div className="inv-table-wrap"><table className="inv-table">
              <thead><tr><th>Item</th><th>Type</th><th>On hand</th><th>Available</th><th>Reorder</th><th>Status</th></tr></thead>
              <tbody>{its.filter(matchItem).map((it) => {
                const oh = INV.onHand(it.id), av = INV.available(it.id);
                const low = it.reorderPoint && av < it.reorderPoint;
                return <tr key={it.id} style={{ cursor: "pointer" }} onClick={() => setItemOpen(it)}><td><b>{it.name}</b>{it.canonicalId && <span className="inv-tag">mapped</span>}</td><td className="inv-muted">{it.type}</td><td>{oh} {it.unit}</td><td className={low ? "inv-red" : ""}>{av} {it.unit}</td><td className="inv-muted">{it.reorderPoint || "—"}</td><td>{av <= 0 ? <span className="inv-pill block">stockout</span> : low ? <span className="inv-pill warn">low</span> : <span className="inv-pill ok">ok</span>}</td></tr>;
              })}</tbody>
            </table></div>
          </div>
        )}

        {(sub === "lots") && (
          <div className="inv-card">
            <div className="inv-card-h">Lots {sub === "overview" && <span className="inv-muted" style={{ fontWeight: 400 }}>· FEFO order</span>}</div>
            <div className="inv-table-wrap"><table className="inv-table">
              <thead><tr><th>Lot</th><th>Item</th><th>Balance</th><th>Warehouse</th><th>Expires</th><th>Status</th><th></th></tr></thead>
              <tbody>{ls.slice().sort((a, b) => (a.expiresAt ? new Date(a.expiresAt) : Infinity) - (b.expiresAt ? new Date(b.expiresAt) : Infinity)).map((l) => {
                const days = l.expiresAt ? Math.round((new Date(l.expiresAt) - Date.now()) / 86400000) : null;
                return <tr key={l.id}><td className="inv-mono">{l.internalLot}</td><td>{l.itemName}</td><td>{INV.lotBalance(l.id)} {l.unit}</td><td className="inv-muted">{(INV.warehouses().find((w) => w.id === l.warehouseId) || {}).name || l.warehouseId}</td><td className={days != null && days <= 7 ? "inv-red" : days != null && days <= 30 ? "inv-amber" : "inv-muted"}>{l.expiresAt ? new Date(l.expiresAt).toLocaleDateString() + (days != null ? " · " + days + "d" : "") : "—"}</td><td><LotStatus s={l.status} /></td><td><button className="inv-linkbtn" onClick={() => setTraceId(l.id)}>Trace</button></td></tr>;
              })}</tbody>
            </table></div>
          </div>
        )}

        {sub === "suppliers" && PO && (
          <div className="inv-card sup-vlist"><div className="inv-card-h">All Vendors <button className="btn primary sm sup-vnew" onClick={() => setSupOpen({})}><Icon name="plus" size={14} /> New</button></div><div className="inv-table-wrap"><table className="inv-table sup-vtable">
            <thead><tr><th className="sup-vcheck"></th><th>Name</th><th>Company Name</th><th>Email</th><th>Work Phone</th><th className="sup-vpay">Payables</th><th></th></tr></thead>
            <tbody>{PO.suppliers().map((s) => { const cur = s.currency || "CAD"; const pay = s.payables != null ? s.payables : 0; return (
              <tr key={s.id} className="inv-clickrow" onClick={() => setSupOpen(s)}>
                <td className="sup-vcheck" onClick={(e) => e.stopPropagation()}><input type="checkbox" /></td>
                <td><a className="sup-vname">{s.name}</a>{s.status === "suspended" || s.status === "disqualified" ? <span className="sup-vinactive">{s.status === "suspended" ? "SUSPENDED" : "INACTIVE"}</span> : null}</td>
                <td className="inv-muted">{s.company || s.name}</td>
                <td className="sup-vemail">{s.email || "—"}</td>
                <td className="inv-muted">{s.workPhone || s.phone || "—"}</td>
                <td className="sup-vpay">{cur + (Number(pay) || 0).toLocaleString(undefined, { minimumFractionDigits: 2, maximumFractionDigits: 2 })}</td>
                <td className="sup-vact" onClick={(e) => e.stopPropagation()}>{s.status !== "approved"
                  ? <button className="inv-linkbtn" onClick={() => { PO.saveSupplier({ id: s.id, status: "approved" }); try { window.auditPush && window.auditPush({ action: "Vendor " + s.name + " approved", by: "purchasing", severity: "medium", target: "Vendor" }); window.__toast && window.__toast(s.name + " approved"); } catch (e) {} }}>Approve</button>
                  : <button className="inv-linkbtn" onClick={() => { PO.saveSupplier({ id: s.id, status: "suspended" }); try { window.auditPush && window.auditPush({ action: "Vendor " + s.name + " suspended", by: "purchasing", severity: "medium", target: "Vendor" }); window.__toast && window.__toast(s.name + " suspended"); } catch (e) {} }}>Suspend</button>}</td>
              </tr>
            ); })}</tbody>
          </table></div></div>
        )}

        {sub === "po" && PO && (
          <div className="inv-card"><div className="inv-card-h">Purchase Orders <button className="inv-linkbtn" onClick={() => setPoOpen(true)} style={{ float: "right" }}>+ New PO</button></div><div className="inv-table-wrap"><table className="inv-table">
            <thead><tr><th>PO</th><th>Supplier</th><th>Lines</th><th>Total</th><th>Expected</th><th>Status</th><th></th></tr></thead>
            <tbody>{PO.pos().map((po) => {
              const canRecv = ["approved", "sent", "acknowledged", "partially_received"].indexOf(po.status) >= 0;
              return <tr key={po.id} className="inv-clickrow" onClick={() => setPoDetail(po.id)}><td className="inv-mono">{po.number}</td><td>{po.supplierName}</td><td className="inv-muted">{(po.lines || []).length}</td><td>{money(PO.poGrand(po))}</td><td className="inv-muted">{po.expected || "—"}</td><td><span className={"inv-pill " + (po.status === "received" || po.status === "closed" ? "ok" : /partial|sent|acknow/.test(po.status) ? "info" : /pending|draft/.test(po.status) ? "warn" : "info")}>{po.status.replace(/_/g, " ")}</span></td>
                <td onClick={(e) => e.stopPropagation()}>{po.status === "pending_approval" && <button className="inv-linkbtn" onClick={() => { PO.setPOStatus(po.id, "approved"); try { window.__toast && window.__toast("PO " + po.number + " approved"); } catch (e) {} }}>Approve</button>}
                {po.status === "approved" && <button className="inv-linkbtn" onClick={() => { PO.setPOStatus(po.id, "sent"); try { window.__toast && window.__toast("PO " + po.number + " sent to supplier"); } catch (e) {} }}>Send</button>}
                <button className="inv-linkbtn" onClick={() => setPoDetail(po.id)}>Open</button></td></tr>;
            })}</tbody>
          </table></div></div>
        )}

        {sub === "pricelists" && PO && (
          <div className="inv-card sup-vlist">
            <div className="inv-card-h">All Price Lists
              <div style={{ display: "flex", gap: 8, alignItems: "center", marginLeft: "auto" }}>
                <div className="inv-search"><Icon name="search" size={14} /><input value={query} onChange={(e) => setQuery(e.target.value)} placeholder="Search price lists…" /></div>
                <button className="btn primary sm" onClick={() => setPlOpen({})}><Icon name="plus" size={14} /> New</button>
              </div>
            </div>
            <div className="invx-pl-grid">
              {(PO.priceLists() || []).filter((pl) => { const q = query.trim().toLowerCase(); return !q || (pl.name + " " + (pl.description || "") + " " + pl.currency).toLowerCase().includes(q); }).map((pl) => {
                const rows = pl.items || [];
                const costTot = rows.reduce((s, r) => s + (Number(r.baseRate) || 0), 0);
                const priceTot = rows.reduce((s, r) => s + (Number(r.customRate != null ? r.customRate : r.baseRate) || 0), 0);
                const avgCost = rows.length ? Math.round((costTot / rows.length) * 100) / 100 : 0;
                const avgPrice = rows.length ? Math.round((priceTot / rows.length) * 100) / 100 : 0;
                const margin = avgPrice > 0 ? ((avgPrice - avgCost) / avgPrice) * 100 : 0;
                const mTone = margin >= 40 ? "ok" : margin >= 20 ? "warn" : "low";
                return (
                  <div key={pl.id} className="invx-pl-card" onClick={() => setPlOpen(pl)}>
                    <div className="invx-pl-top">
                      <div className="invx-pl-name">{pl.name}{pl.status !== "active" ? <span className="sup-vinactive">INACTIVE</span> : null}
                        <span className="invx-pl-desc">{pl.description || (pl.txnType === "purchase" ? "Purchase price list" : "Sales price list")}</span>
                      </div>
                      <span className={"invx-pl-badge " + (pl.txnType === "purchase" ? "buy" : "sell")}>{pl.txnType === "purchase" ? "Purchase" : "Sales"}</span>
                    </div>
                    <div className="invx-pl-metrics">
                      <div className="invx-pl-m"><span>Avg cost</span><b>${avgCost.toFixed(2)}</b></div>
                      <div className="invx-pl-m"><span>Avg price</span><b>${avgPrice.toFixed(2)}</b></div>
                      <div className="invx-pl-m"><span>Margin</span><b className={"invx-pl-margin " + mTone}>{margin.toFixed(0)}%</b></div>
                    </div>
                    <div className="invx-pl-foot">
                      <span><Icon name="tag" size={12} /> {pl.scheme === "volume" ? "Volume" : "Unit"} · {pl.currency}</span>
                      <span><Icon name="boxes" size={12} /> {rows.length} items</span>
                      <button className="inv-linkbtn" onClick={(e) => { e.stopPropagation(); setPlOpen(pl); }}>Edit</button>
                    </div>
                  </div>
                );
              })}
            </div>
          </div>
        )}

        {sub === "production" && (() => {
          const PR = window.NutriInvProd, CP = window.NutriInvCopilot;
          if (!PR) return <div className="inv-card"><div className="inv-card-h">Production Runs</div><div className="inv-empty"><Icon name="factory" size={26} /><p>Production engine unavailable.</p></div></div>;
          return (
            <React.Fragment>
              {CP && (() => {
                const sug = CP.poSuggestions(), var_ = CP.valueAtRisk();
                const rules = CP.rules();
                return (
                  <div className="inv-card inv-copilot">
                    <div className="inv-card-h"><span className="inv-copilot-badge"><Icon name="sparkles" size={13} /> Loraa Inventory Copilot</span><button className="inv-linkbtn" style={{ float: "right" }} onClick={() => { const r = CP.run("loraa-auto"); try { window.__toast && window.__toast(r.fired.length + " automation rule(s) evaluated"); } catch (e) {} }}>Run automations</button></div>
                    <div className="inv-copilot-grid">
                      <div className="inv-copilot-stat"><span>Reorder suggestions</span><b className={sug.length ? "warn" : ""}>{sug.length}</b></div>
                      <div className="inv-copilot-stat"><span>Value at risk</span><b className={var_.value ? "block" : ""}>{money(var_.value)}</b></div>
                      <div className="inv-copilot-stat"><span>Active rules</span><b>{rules.filter((r) => r.enabled).length}/{rules.length}</b></div>
                    </div>
                    {sug.length > 0 && (
                      <div className="inv-copilot-sug">
                        {sug.slice(0, 4).map((s) => (
                          <div className="inv-copilot-row" key={s.itemId}>
                            <span><b>{s.name}</b> · {s.onHand} on hand ≤ {s.reorderPoint}</span>
                            <button className="inv-linkbtn" onClick={() => { try { window.NutriInvLink.draftPOForItem(s.itemId); window.__toast && window.__toast("Draft PO created for " + s.name); } catch (e) {} }}>Draft PO ({s.suggestedQty} {s.unit})</button>
                          </div>
                        ))}
                      </div>
                    )}
                    <div className="inv-copilot-rules">
                      {rules.map((r) => (
                        <label key={r.id} className="inv-copilot-rule">
                          <input type="checkbox" checked={r.enabled} onChange={() => { CP.saveRule({ id: r.id, enabled: !r.enabled }); }} />
                          <span><b>{r.name}</b><em>{r.mode === "auto" ? "Runs automatically" : "Suggests, needs approval"}</em></span>
                        </label>
                      ))}
                    </div>
                    <div className="inv-note" style={{ background: "#EEF4FF", color: "#2748B0", marginTop: 10 }}><Icon name="info" size={13} /> Calculations are free and explainable; every automation firing is written to the audit log.</div>
                  </div>
                );
              })()}
              <div className="inv-card"><div className="inv-card-h">Production Runs <button className="inv-linkbtn" style={{ float: "right" }} onClick={() => setRunOpen({})}>+ New run</button></div>
                <div className="inv-table-wrap"><table className="inv-table">
                  <thead><tr><th>Run</th><th>Product</th><th>Qty</th><th>Status</th><th>Cost</th><th></th></tr></thead>
                  <tbody>{PR.runs().length === 0 ? <tr><td colSpan="6" className="inv-muted" style={{ padding: 18, textAlign: "center" }}>No production runs yet — start one from an approved recipe.</td></tr> : PR.runs().map((run) => (
                    <tr key={run.id}><td className="inv-mono">{run.number}</td><td>{run.productName}</td><td>{run.qty}</td><td><span className={"inv-pill " + (/released|completed/.test(run.status) ? "ok" : /hold/.test(run.status) ? "warn" : "info")}>{run.status.replace(/_/g, " ")}</span></td><td>{run.actualCost ? money(run.actualCost) : "—"}</td>
                      <td>{run.status === "ready" && <button className="inv-linkbtn" onClick={() => { const r = PR.execute(run.id, "production"); try { window.__toast && window.__toast(r.ok ? "Run completed → FG lot on QA hold" : "Blocked: " + (r.error || "inputs")); } catch (e) {} }}>Execute</button>}
                      {run.status === "quality_hold" && <button className="inv-linkbtn" onClick={() => { PR.release(run.id, "qa"); try { window.__toast && window.__toast("Finished goods released"); } catch (e) {} }}>Release</button>}</td></tr>
                  ))}</tbody>
                </table></div>
              </div>
            </React.Fragment>
          );
        })()}
        {sub === "trace" && (
          <div className="inv-card"><div className="inv-card-h">Traceability</div><div className="inv-table-wrap"><table className="inv-table"><thead><tr><th>Lot</th><th>Item</th><th>Supplier lot</th><th>Balance</th><th></th></tr></thead><tbody>{ls.map((l) => <tr key={l.id}><td className="inv-mono">{l.internalLot}</td><td>{l.itemName}</td><td className="inv-muted">{l.supplierLot || "—"}</td><td>{INV.lotBalance(l.id)} {l.unit}</td><td><button className="inv-linkbtn" onClick={() => setTraceId(l.id)}>Trace forward/back</button></td></tr>)}</tbody></table></div></div>
        )}

        {receiving && <ReceiveDrawer onClose={() => setReceiving(false)} />}
        {itemOpen && <ItemDrawer item={itemOpen.id ? itemOpen : null} onClose={() => setItemOpen(null)} />}
        {plOpen && PO && <PriceListDrawer pl={plOpen.id ? plOpen : null} onClose={() => setPlOpen(null)} />}
        {supOpen && PO && <SupplierDrawer supplier={supOpen.id ? supOpen : null} onClose={() => setSupOpen(null)} />}
        {poOpen && PO && <PODrawer editPO={poEdit} onClose={() => { setPoOpen(false); setPoEdit(null); }} />}
        {poDetail && PO && <PODetail poId={poDetail} onClose={() => setPoDetail(null)} onEdit={(po) => { setPoDetail(null); setPoEdit(po); setPoOpen(true); }} />}
        {runOpen && window.NutriInvProd && <RunDrawer onClose={() => setRunOpen(null)} />}
        {traceId && <TraceDrawer lotId={traceId} onClose={() => setTraceId(null)} />}
      </div>
    );
  }

  if (typeof window !== "undefined") window.InventoryWorkspace = InventoryWorkspace;
})();
