/* ============================================================
   ops.jsx — Inventory · Branches · Recipe (desktop, light)
   ============================================================ */

/* ---------------- INVENTORY ---------------- */
function Inventory() {
  const store = useContext(window.AppCtx);
  const D = window.POS_DATA, H = window.POS_HELP;
  const [bid, setBid] = useState(store.currentBranchId);
  const [filter, setFilter] = useState("all");
  const [receive, setReceive] = useState(null);
  const [produce, setProduce] = useState(null);
  const [ingEdit, setIngEdit] = useState(null); // ingredient row or {new:true}
  const canManage = store.access ? store.access.manageStock : false;
  const canRestock = store.access ? store.access.restockToPar : false;
  const inv = store.inventory[bid] || [];
  const branch = store.branches.find((b) => b.id === bid);

  function statusOf(it) {
    if (it.onHand <= it.reorder * 0.6) return "crit";
    if (it.onHand <= it.reorder) return "low";
    return "ok";
  }
  const decorated = inv.map((it) => ({ ...it, ing: store.ing(it.id), st: statusOf(it) })).filter((x) => x.ing);
  const lows = decorated.filter((x) => x.st !== "ok");
  const shown = decorated.filter((x) => filter === "all" || (filter === "low" && x.st !== "ok"));

  return (
    <div className="page">
      <div className="page-head">
        <div>
          <div className="page-eyebrow">คลังวัตถุดิบ</div>
          <h1 className="page-title">จัดการสต็อก</h1>
        </div>
        <div className="head-actions">
          <select className="select" value={bid} onChange={(e) => setBid(e.target.value)}>
            {(store.visibleBranches ? store.visibleBranches() : store.branches).map((b) => <option key={b.id} value={b.id}>สาขา{b.name} · {b.code}</option>)}
          </select>
          <div className="seg seg-sm">
            <button className={"seg-b" + (filter === "all" ? " on" : "")} onClick={() => setFilter("all")}>ทั้งหมด</button>
            <button className={"seg-b" + (filter === "low" ? " on" : "")} onClick={() => setFilter("low")}>ใกล้หมด {lows.length ? "(" + lows.length + ")" : ""}</button>
          </div>
          <button className="btn-ghost" disabled={shown.length === 0} onClick={() => exportStockPdf(branch, shown, store, filter)}><Icon name="report" size={16} /> ส่งออก PDF</button>
          {canManage && <button className="btn-primary" onClick={() => setIngEdit({ new: true })}><Icon name="plus" size={16} /> เพิ่มวัตถุดิบ</button>}
        </div>
      </div>

      {lows.length > 0 && (
        <div className="alert-banner">
          <span className="ab-ic"><Icon name="bell" size={18} /></span>
          <div className="ab-txt"><b>{lows.length} รายการต่ำกว่าจุดสั่งซื้อ</b> ที่สาขา{branch.name} — {lows.map((x) => x.ing.name).join(", ")}</div>
          {canRestock && <button className="ab-act" onClick={() => store.restockAll(bid)}>เติมทั้งหมดถึง par</button>}
        </div>
      )}

      <div className="card">
        <table className="tbl">
          <thead><tr><th>วัตถุดิบ</th><th>ประเภท</th><th className="r">คงเหลือ</th><th>ระดับสต็อก</th><th className="r">จุดสั่งซื้อ</th><th className="r">ต้นทุน/หน่วย</th><th className="c">จัดการ</th></tr></thead>
          <tbody>
            {shown.map((x) => {
              const pct = Math.min(100, Math.round(x.onHand / x.par * 100));
              const tone = x.st === "crit" ? "var(--clay)" : x.st === "low" ? "var(--amber)" : "var(--sage)";
              return (
                <tr key={x.id}>
                  <td><span className="tbl-strong">{x.ing.name}</span>{x.ing.kind === "mini" && <span className="mini-badge">มินิ</span>}</td>
                  <td className="tbl-dim">{x.ing.kind === "mini" ? "มินิโปรดัก" : typeLabel(x.ing.type)}</td>
                  <td className="r"><b>{x.onHand.toLocaleString()}</b> <span className="tbl-dim">{x.ing.unit}</span></td>
                  <td>
                    <div className="stock-bar"><div className="stock-fill" style={{ width: pct + "%", background: tone }} /></div>
                    <div className="stock-cap" style={{ color: tone }}>{x.st === "crit" ? "วิกฤต" : x.st === "low" ? "ใกล้หมด" : "ปกติ"} · {pct}%</div>
                  </td>
                  <td className="r tbl-dim">{x.reorder.toLocaleString()}</td>
                  <td className="r tbl-dim">{H.thb2(store.ingCost(x.id))}</td>
                  <td className="c">
                    <div className="row-actions">
                      {x.ing.kind === "mini"
                        ? <button className="btn-mini" onClick={() => setProduce(x)}><Icon name="plus" size={13} /> ผลิต</button>
                        : <button className="btn-mini" onClick={() => setReceive(x)}><Icon name="plus" size={13} /> รับเข้า</button>}
                      {canManage && <button className="btn-mini" onClick={() => setIngEdit(x)}>แก้ไข</button>}
                      {canManage && <button className="row-x" onClick={() => { if (confirm("ลบ \"" + x.ing.name + "\" ออกจากทุกสาขาและสูตรที่เกี่ยวข้อง?")) store.removeIngredient(x.id); }}><Icon name="close" size={14} /></button>}
                    </div>
                  </td>
                </tr>
              );
            })}
          </tbody>
        </table>
      </div>

      {filter === "all" && (
        <div className="rbac-note" style={{ marginTop: 14 }}>
          <Icon name="check" size={15} />
          <span><b>มินิโปรดัก</b> = ส่วนผสมกึ่งสำเร็จที่มีสต็อกของตัวเอง · กด <b>ผลิต</b> เพื่อทำแบตช์ (ตัดวัตถุดิบหลัก → เพิ่มสต็อกมินิ) · เมนูเครื่องดื่มหยิบมินิไปใช้ในสูตรได้จากหน้า เมนู &amp; สูตร</span>
        </div>
      )}

      <ReceiveModal item={receive} branch={branch} onClose={() => setReceive(null)}
        onReceive={(qty) => { store.receiveStock(bid, receive.id, qty); window.toast({ title: "รับวัตถุดิบเข้าแล้ว", msg: receive.ing.name + " +" + qty.toLocaleString() + " " + receive.ing.unit }); setReceive(null); }} />
      <ProduceModal item={produce} branch={branch} store={store} onClose={() => setProduce(null)}
        onProduce={(batches) => { store.produceMini(bid, produce.id, batches); setProduce(null); }} />
      <IngredientModal item={ingEdit} rawIngredients={store.ingredients.filter((g) => g.kind !== "mini")} ingCost={store.ingCost} onClose={() => setIngEdit(null)}
        onSave={(data) => {
          if (ingEdit && !ingEdit.new) { store.updateIngredient(ingEdit.id, data); window.toast({ title: "บันทึกรายการแล้ว", msg: data.name }); }
          else { store.addIngredient(data); }
          setIngEdit(null);
        }} />
    </div>
  );
}
function typeLabel(t) { return { bean: "เมล็ดกาแฟ", milk: "นม", syrup: "ไซรัป", powder: "ผง", cup: "บรรจุภัณฑ์", other: "อื่นๆ" }[t] || t; }

/* ---- export the current stock view to a print-ready PDF (browser print → Save as PDF) ---- */
function exportStockPdf(branch, rows, store, filter) {
  const H = window.POS_HELP;
  const today = new Date().toLocaleDateString("th-TH", { day: "numeric", month: "long", year: "numeric" });
  const stText = { crit: "วิกฤต", low: "ใกล้หมด", ok: "ปกติ" };
  const stColor = { crit: "#b0573f", low: "#bb8a32", ok: "#5d7a5e" };
  const esc = (s) => String(s).replace(/[&<>]/g, (c) => ({ "&": "&amp;", "<": "&lt;", ">": "&gt;" }[c]));
  const body = rows.map((x) => {
    const pct = x.par ? Math.min(100, Math.round(x.onHand / x.par * 100)) : 0;
    return `<tr>
      <td><b>${esc(x.ing.name)}</b>${x.ing.kind === "mini" ? ' <span class="mini">มินิ</span>' : ""}</td>
      <td class="dim">${x.ing.kind === "mini" ? "มินิโปรดัก" : esc(typeLabel(x.ing.type))}</td>
      <td class="r">${x.onHand.toLocaleString()} ${esc(x.ing.unit)}</td>
      <td class="r dim">${x.reorder.toLocaleString()}</td>
      <td class="r dim">${x.par.toLocaleString()}</td>
      <td class="r dim">${H.thb2(store.ingCost(x.id))}</td>
      <td style="color:${stColor[x.st]};font-weight:600">${stText[x.st]} · ${pct}%</td>
    </tr>`;
  }).join("");
  const lowCount = rows.filter((x) => x.st !== "ok").length;
  const scope = filter === "low" ? "เฉพาะรายการใกล้หมด" : "ทุกรายการ";
  const html = `<!DOCTYPE html><html lang="th"><head><meta charset="utf-8"><title>รายงานสต็อก ${esc(branch.name)}</title>
    <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
    <link href="https://fonts.googleapis.com/css2?family=IBM+Plex+Sans+Thai:wght@400;500;600;700&display=swap" rel="stylesheet">
    <style>
      @page{margin:16mm;}
      *{box-sizing:border-box;-webkit-print-color-adjust:exact;print-color-adjust:exact;}
      body{font-family:'IBM Plex Sans Thai',sans-serif;color:#241c15;margin:0;}
      .brand{display:flex;align-items:center;gap:10px;margin-bottom:16px;}
      .logo{width:34px;height:34px;border-radius:9px;background:#b07d4e;color:#fff;display:flex;align-items:center;justify-content:center;font-size:18px;}
      .brand b{font-size:15px;}
      h1{font-size:21px;margin:0;letter-spacing:-.01em;}
      .sub{color:#8a7c6c;font-size:12.5px;margin:5px 0 18px;}
      table{width:100%;border-collapse:collapse;font-size:12px;}
      th{text-align:left;text-transform:uppercase;font-size:9.5px;letter-spacing:.05em;color:#8a7c6c;border-bottom:1.5px solid #e6dccd;padding:0 10px 8px;}
      th.r{text-align:right;}
      td{padding:8px 10px;border-bottom:1px solid #efe7da;vertical-align:middle;}
      td.r{text-align:right;font-variant-numeric:tabular-nums;}
      td.dim{color:#8a7c6c;}
      tr{break-inside:avoid;}
      .mini{font-size:9px;color:#4a6885;background:#e4ecf3;border-radius:4px;padding:1px 5px;}
      .foot{margin-top:20px;font-size:10.5px;color:#8a7c6c;border-top:1px solid #efe7da;padding-top:10px;display:flex;justify-content:space-between;}
    </style></head><body>
    <div class="brand"><span class="logo">◐</span><b>POS Coffee</b></div>
    <h1>รายงานสต็อกวัตถุดิบ · สาขา${esc(branch.name)}</h1>
    <div class="sub">${esc(branch.code)} · ณ ${today} · ${scope} ${rows.length} รายการ · ใกล้หมด ${lowCount} รายการ</div>
    <table><thead><tr><th>วัตถุดิบ</th><th>ประเภท</th><th class="r">คงเหลือ</th><th class="r">จุดสั่งซื้อ</th><th class="r">ระดับเต็ม</th><th class="r">ต้นทุน/หน่วย</th><th>สถานะ</th></tr></thead><tbody>${body}</tbody></table>
    <div class="foot"><span>สร้างโดยระบบ POS Coffee</span><span>เลือก “บันทึกเป็น PDF” ในหน้าต่างพิมพ์</span></div>
    </body></html>`;
  const iframe = document.createElement("iframe");
  iframe.setAttribute("aria-hidden", "true");
  iframe.style.cssText = "position:fixed;left:-9999px;top:0;width:800px;height:600px;border:0;";
  document.body.appendChild(iframe);
  const w = iframe.contentWindow;
  const doc = w.document;
  doc.open(); doc.write(html); doc.close();
  const cleanup = () => { if (iframe.parentNode) iframe.parentNode.removeChild(iframe); };
  const trigger = () => { try { w.focus(); w.print(); } catch (e) {} };
  w.onafterprint = cleanup;
  if (doc.fonts && doc.fonts.ready) doc.fonts.ready.then(() => setTimeout(trigger, 120));
  else setTimeout(trigger, 500);
  setTimeout(cleanup, 60000);
  window.toast({ title: "เตรียมไฟล์ PDF แล้ว", msg: "สาขา" + branch.name + " · เลือก “บันทึกเป็น PDF” ในหน้าต่างพิมพ์" });
}

function ReceiveModal({ item, branch, onClose, onReceive }) {
  const [qty, setQty] = useState(0);
  const H = window.POS_HELP;
  useEffect(() => { if (item) setQty(Math.max(0, item.par - item.onHand)); }, [item]);
  if (!item) return null;
  return (
    <Modal open={!!item} onClose={onClose} title={"รับเข้า · " + item.ing.name} subtitle={"สาขา" + branch.name + " · คงเหลือ " + item.onHand.toLocaleString() + " " + item.ing.unit} width={420}>
      <div className="rcv-row">
        <button className="rcv-step" onClick={() => setQty((q) => Math.max(0, q - 100))}><Icon name="minus" size={16} /></button>
        <div className="rcv-val"><input type="number" value={qty} onChange={(e) => setQty(Math.max(0, +e.target.value || 0))} /><span>{item.ing.unit}</span></div>
        <button className="rcv-step" onClick={() => setQty((q) => q + 100)}><Icon name="plus" size={16} /></button>
      </div>
      <div className="rcv-quick">{[100, 500, 1000, item.par - item.onHand].map((q, i) => q > 0 && <button key={i} onClick={() => setQty(q)}>{i === 3 ? "ถึง par" : "+" + q}</button>)}</div>
      <div className="rcv-after"><span>คงเหลือหลังรับเข้า</span><b>{(item.onHand + qty).toLocaleString()} {item.ing.unit}</b></div>
      <div className="rcv-cost"><span>มูลค่าโดยประมาณ</span><b>{H.thb(qty * item.ing.cost)}</b></div>
      <button className="opt-add" disabled={qty <= 0} onClick={() => onReceive(qty)}>ยืนยันรับเข้า</button>
    </Modal>
  );
}

function ProduceModal({ item, branch, store, onClose, onProduce }) {
  const [batches, setBatches] = useState(1);
  const H = window.POS_HELP;
  useEffect(() => { if (item) setBatches(1); }, [item]);
  if (!item) return null;
  const m = item.ing;
  const yieldQty = (m.batchYield || 0) * batches;
  const inv = store.inventory[branch.id] || [];
  const onHandOf = (id) => { const r = inv.find((x) => x.id === id); return r ? r.onHand : 0; };
  const comps = (m.components || []).map((c) => { const g = store.ing(c.i); return { g, need: c.q * batches, have: onHandOf(c.i) }; }).filter((c) => c.g);
  const shortage = comps.some((c) => c.need > c.have);
  return (
    <Modal open={!!item} onClose={onClose} title={"ผลิต · " + m.name} subtitle={"สาขา" + branch.name + " · คงเหลือ " + item.onHand.toLocaleString() + " " + m.unit} width={440}>
      <div className="rcv-row">
        <button className="rcv-step" onClick={() => setBatches((b) => Math.max(1, b - 1))}><Icon name="minus" size={16} /></button>
        <div className="rcv-val"><input type="number" value={batches} onChange={(e) => setBatches(Math.max(1, +e.target.value || 1))} /><span>แบตช์</span></div>
        <button className="rcv-step" onClick={() => setBatches((b) => b + 1)}><Icon name="plus" size={16} /></button>
      </div>
      <div className="rcv-after"><span>ผลิตได้</span><b>+{yieldQty.toLocaleString()} {m.unit}</b></div>
      <div className="produce-comp">
        <div className="mini-comp-h">ตัดวัตถุดิบหลัก</div>
        {comps.map((c) => (
          <div className="mini-row" key={c.g.id}>
            <span className="mini-n">{c.g.name}</span>
            <span className={"produce-need" + (c.need > c.have ? " short" : "")}>−{c.need.toLocaleString()} {c.g.unit}</span>
            <span className="mini-c">คงเหลือ {c.have.toLocaleString()}</span>
          </div>
        ))}
      </div>
      {shortage && <div className="pin-err" style={{ textAlign: "left", marginTop: 8 }}>วัตถุดิบหลักไม่พอ — จะถูกตัดเท่าที่มี</div>}
      <button className="opt-add" onClick={() => onProduce(batches)}>ยืนยันการผลิต</button>
    </Modal>
  );
}

function IngredientModal({ item, rawIngredients, ingCost, onClose, onSave }) {
  const isNew = item && item.new;
  const H = window.POS_HELP;
  const TYPES = [["bean", "เมล็ดกาแฟ"], ["milk", "นม"], ["syrup", "ไซรัป"], ["powder", "ผง"], ["cup", "บรรจุภัณฑ์"], ["other", "อื่นๆ"]];
  const UNITS = ["g", "ml", "pcs"];
  const [kind, setKind] = useState("raw");
  const [name, setName] = useState("");
  const [type, setType] = useState("bean");
  const [unit, setUnit] = useState("g");
  const [cost, setCost] = useState(0);
  const [reorder, setReorder] = useState(0);
  const [par, setPar] = useState(0);
  const [initial, setInitial] = useState(0);
  const [munit, setMunit] = useState("ที่");
  const [batchYield, setBatchYield] = useState(0);
  const [comps, setComps] = useState([]); // [{i, q}]
  useEffect(() => {
    if (item) {
      const ing = item.ing || {};
      setKind(isNew ? "raw" : (ing.kind === "mini" ? "mini" : "raw"));
      setName(isNew ? "" : ing.name);
      setType(isNew ? "bean" : ing.type);
      setUnit(isNew ? "g" : ing.unit);
      setCost(isNew ? 0 : (ing.cost || 0));
      setReorder(isNew ? 0 : (item.reorder || 0));
      setPar(isNew ? 0 : (item.par || 0));
      setInitial(0);
      setMunit(isNew ? "ml" : (ing.unit || "ml"));
      setBatchYield(isNew ? 0 : (ing.batchYield || 0));
      setComps(isNew ? [] : (ing.components ? ing.components.map((c) => ({ ...c })) : []));
    }
  }, [item]);
  if (!item) return null;

  const usedIds = comps.map((c) => c.i);
  const availRaw = (rawIngredients || []).filter((g) => !usedIds.includes(g.id));
  const miniCost = comps.reduce((s, c) => { const g = (rawIngredients || []).find((x) => x.id === c.i); return s + (g ? g.cost * c.q : 0); }, 0);
  const cstep = (u) => (u === "pcs" ? 1 : u === "g" ? 5 : 10);
  const validRaw = name.trim() && par > 0;
  const validMini = name.trim() && comps.length > 0 && batchYield > 0 && par > 0;
  const valid = kind === "mini" ? validMini : validRaw;

  function setComp(id, delta) {
    setComps((cs) => {
      const idx = cs.findIndex((c) => c.i === id);
      if (idx >= 0) { const nq = Math.max(0, Math.round((cs[idx].q + delta) * 100) / 100); const next = [...cs]; if (nq === 0) next.splice(idx, 1); else next[idx] = { ...next[idx], q: nq }; return next; }
      if (delta > 0) return [...cs, { i: id, q: delta }];
      return cs;
    });
  }

  function save() {
    if (kind === "mini") onSave({ kind: "mini", type: "mini", name: name.trim(), unit: munit.trim() || "ml", batchYield, components: comps, reorder, par, initial });
    else onSave({ kind: "raw", name: name.trim(), type, unit, cost, reorder, par, initial });
  }

  return (
    <Modal open={!!item} onClose={onClose} title={isNew ? "เพิ่มรายการใหม่" : (kind === "mini" ? "แก้ไขมินิโปรดัก" : "แก้ไขวัตถุดิบ")} subtitle={isNew ? "วัตถุดิบหลัก หรือ มินิโปรดัก (ใช้เป็นส่วนผสมของเมนูได้)" : (item.ing ? item.ing.name : "")} width={520}>
      {isNew && (
        <div className="fld" style={{ marginBottom: 14 }}><span>ชนิด</span>
          <div className="seg" style={{ width: "100%" }}>
            <button className={"seg-b" + (kind === "raw" ? " on" : "")} style={{ flex: 1 }} onClick={() => setKind("raw")}>วัตถุดิบหลัก</button>
            <button className={"seg-b" + (kind === "mini" ? " on" : "")} style={{ flex: 1 }} onClick={() => setKind("mini")}>มินิโปรดัก</button>
          </div>
        </div>
      )}

      {kind === "raw" ? (
        <div className="form-grid">
          <label className="fld wide"><span>ชื่อวัตถุดิบ *</span><input value={name} onChange={(e) => setName(e.target.value)} placeholder="เช่น ไซรัปเฮเซลนัท" /></label>
          <label className="fld"><span>ประเภท</span>
            <select className="select" value={type} onChange={(e) => setType(e.target.value)}>{TYPES.map(([v, l]) => <option key={v} value={v}>{l}</option>)}</select>
          </label>
          <label className="fld"><span>หน่วยฐาน</span>
            <select className="select" value={unit} onChange={(e) => setUnit(e.target.value)} disabled={!isNew}>{UNITS.map((u) => <option key={u} value={u}>{u}</option>)}</select>
          </label>
          <label className="fld"><span>ต้นทุน/หน่วย (฿)</span><input type="number" step="0.001" value={cost} onChange={(e) => setCost(Math.max(0, +e.target.value || 0))} /></label>
          <label className="fld"><span>จุดสั่งซื้อ (reorder)</span><input type="number" value={reorder} onChange={(e) => setReorder(Math.max(0, +e.target.value || 0))} /></label>
          <label className="fld"><span>ระดับเต็ม (par)</span><input type="number" value={par} onChange={(e) => setPar(Math.max(0, +e.target.value || 0))} /></label>
          {isNew && <label className="fld"><span>จำนวนตั้งต้น/สาขา</span><input type="number" value={initial} onChange={(e) => setInitial(Math.max(0, +e.target.value || 0))} /></label>}
        </div>
      ) : (
        <div>
          <div className="form-grid">
            <label className="fld wide"><span>ชื่อมินิโปรดัก *</span><input value={name} onChange={(e) => setName(e.target.value)} placeholder="เช่น น้ำชาไทยเข้มข้น" /></label>
            <label className="fld"><span>หน่วยสต็อก</span>
              <select className="select" value={munit} onChange={(e) => setMunit(e.target.value)}>{["ml", "g", "ที่", "ช็อต"].map((u) => <option key={u} value={u}>{u}</option>)}</select>
            </label>
            <label className="fld"><span>ผลิตได้/แบตช์ ({munit}) *</span><input type="number" value={batchYield} onChange={(e) => setBatchYield(Math.max(0, +e.target.value || 0))} placeholder="เช่น 700" /></label>
            <label className="fld"><span>จุดสั่งซื้อ (reorder)</span><input type="number" value={reorder} onChange={(e) => setReorder(Math.max(0, +e.target.value || 0))} /></label>
            <label className="fld"><span>ระดับเต็ม (par) *</span><input type="number" value={par} onChange={(e) => setPar(Math.max(0, +e.target.value || 0))} /></label>
            {isNew && <label className="fld"><span>สต็อกตั้งต้น/สาขา</span><input type="number" value={initial} onChange={(e) => setInitial(Math.max(0, +e.target.value || 0))} /></label>}
          </div>
          <div className="mini-comp">
            <div className="mini-comp-h">วัตถุดิบหลักต่อ 1 แบตช์ (ผลิตได้ {batchYield || 0} {munit}) <b>{H.thb2(miniCost)}/แบตช์ · {H.thb2(batchYield ? miniCost / batchYield : 0)}/{munit}</b></div>
            {comps.length === 0 && <div className="mini-empty">ยังไม่มีส่วนประกอบ — เลือกวัตถุดิบด้านล่าง</div>}
            {comps.map((c) => {
              const g = (rawIngredients || []).find((x) => x.id === c.i);
              if (!g) return null;
              return (
                <div className="mini-row" key={c.i}>
                  <span className="mini-n">{g.name}</span>
                  <div className="qstep">
                    <button onClick={() => setComp(c.i, -cstep(g.unit))}><Icon name="minus" size={13} /></button>
                    <span>{c.q} {g.unit}</span>
                    <button onClick={() => setComp(c.i, cstep(g.unit))}><Icon name="plus" size={13} /></button>
                  </div>
                  <span className="mini-c">{H.thb2(g.cost * c.q)}</span>
                  <button className="row-x" onClick={() => setComp(c.i, -9999)}><Icon name="close" size={13} /></button>
                </div>
              );
            })}
            {availRaw.length > 0 && (
              <div className="recipe-add" style={{ borderTop: "none", padding: "12px 0 0" }}>
                <span className="ra-l">เพิ่มวัตถุดิบ:</span>
                <div className="ra-chips">
                  {availRaw.slice(0, 8).map((g) => <button key={g.id} onClick={() => setComp(g.id, cstep(g.unit))}><Icon name="plus" size={12} /> {g.name}</button>)}
                </div>
              </div>
            )}
          </div>
        </div>
      )}

      <div className="form-note"><Icon name="check" size={14} /> {kind === "mini" ? "มินิโปรดักมีสต็อกของตัวเอง — กด “ผลิต” เพื่อทำทีละแบตช์ (ตัดวัตถุดิบหลักตามสูตร) และเมนูเครื่องดื่มหยิบไปใช้ในสูตรได้" : (isNew ? "เพิ่มวัตถุดิบเข้าคลังทุกสาขา พร้อมค่า reorder/par เดียวกัน" : "reorder/par อัปเดตทุกสาขา · ยอดคงเหลือไม่เปลี่ยน")}</div>
      <button className="opt-add" disabled={!valid} onClick={save}>{isNew ? (kind === "mini" ? "เพิ่มมินิโปรดัก" : "เพิ่มวัตถุดิบ") : "บันทึก"}</button>
    </Modal>
  );
}

/* ---------------- BRANCHES ---------------- */
function Branches() {
  const store = useContext(window.AppCtx);
  const H = window.POS_HELP;
  const [add, setAdd] = useState(false);
  const session = store.sessionByBranch();
  return (
    <div className="page">
      <div className="page-head">
        <div>
          <div className="page-eyebrow">โครงสร้างองค์กร · HQ</div>
          <h1 className="page-title">จัดการสาขา</h1>
        </div>
        <button className="btn-primary" onClick={() => setAdd(true)}><Icon name="plus" size={16} /> เพิ่มสาขาใหม่</button>
      </div>

      <div className="branch-grid">
        {store.branches.map((b) => {
          const s = session[b.id] || { sales: 0, orders: 0 };
          return (
            <div className="branch-card" key={b.id}>
              <div className="bc-head">
                <div className="bc-code">{b.code}</div>
                <Pill tone="sage">เปิดอยู่</Pill>
              </div>
              <div className="bc-name">สาขา{b.name}</div>
              <div className="bc-mgr"><Icon name="user" size={14} /> {b.manager}</div>
              <div className="bc-stats">
                <div><span>ยอดขายวันนี้</span><b>{H.thb(b.salesToday + s.sales)}</b></div>
                <div><span>พนักงาน</span><b>{b.staff} คน</b></div>
                <div><span>เปิดเมื่อ</span><b>{new Date(b.opened).toLocaleDateString("th-TH", { month: "short", year: "2-digit" })}</b></div>
              </div>
              <button className="bc-open" onClick={() => { store.setBranch(b.id); store.go("pos"); }}>เปิดหน้าขาย POS <Icon name="arrow" size={15} /></button>
            </div>
          );
        })}
        <button className="branch-add" onClick={() => setAdd(true)}>
          <span className="ba-plus"><Icon name="plus" size={26} /></span>
          <span className="ba-t">เพิ่มสาขาใหม่</span>
          <span className="ba-s">HQ สร้างสาขาและออก branch_id ได้เอง</span>
        </button>
      </div>

      <AddBranchModal open={add} onClose={() => setAdd(false)} existing={store.branches}
        onAdd={(b) => { store.addBranch(b); setAdd(false); window.toast({ title: "เพิ่มสาขาสำเร็จ", msg: "สาขา" + b.name + " · " + b.code + " พร้อมใช้งานทุกหน้า" }); }} />
    </div>
  );
}

function AddBranchModal({ open, onClose, onAdd, existing }) {
  const [name, setName] = useState("");
  const [code, setCode] = useState("");
  const [codeTouched, setCodeTouched] = useState(false);
  const [manager, setManager] = useState("");
  const [staff, setStaff] = useState(5);
  const [taxId, setTaxId] = useState("");
  const suggested = "BKK-" + String(existing.length + 1).padStart(2, "0");
  useEffect(() => { if (open) { setName(""); setCode(suggested); setCodeTouched(false); setManager(""); setStaff(5); setTaxId(""); } }, [open]);
  const codeUp = code.trim().toUpperCase();
  const dup = existing.some((b) => b.code.toUpperCase() === codeUp);
  const valid = name.trim() && manager.trim() && codeUp && !dup;
  return (
    <Modal open={open} onClose={onClose} title="เพิ่มสาขาใหม่" subtitle="กำหนดรหัสสาขาได้เอง · ต้องไม่ซ้ำกับสาขาเดิม" width={480}>
      <div className="form-grid">
        <label className="fld"><span>ชื่อสาขา *</span><input value={name} onChange={(e) => setName(e.target.value)} placeholder="เช่น เอกมัย" /></label>
        <label className="fld"><span>รหัสสาขา *</span>
          <input className={dup ? "fld-err" : ""} value={code} onChange={(e) => { setCode(e.target.value); setCodeTouched(true); }} placeholder="เช่น BKK-05" />
          {dup ? <em className="fld-hint err">รหัสนี้ถูกใช้แล้ว</em> : <em className="fld-hint">{codeTouched ? "กำหนดเอง" : "แนะนำ · แก้ไขได้"}</em>}
        </label>
        <label className="fld wide"><span>ผู้จัดการสาขา *</span><input value={manager} onChange={(e) => setManager(e.target.value)} placeholder="ชื่อ-นามสกุล" /></label>
        <label className="fld"><span>จำนวนพนักงาน</span><input type="number" value={staff} onChange={(e) => setStaff(Math.max(1, +e.target.value || 1))} /></label>
        <label className="fld"><span>เลขผู้เสียภาษี</span><input value={taxId} onChange={(e) => setTaxId(e.target.value)} placeholder="13 หลัก" /></label>
      </div>
      <div className="form-note"><Icon name="check" size={14} /> ระบบจะผูกคลังสต็อกเริ่มต้น สร้างบัญชีผู้จัดการสาขา และซิงก์เมนู/สูตรจาก HQ อัตโนมัติ</div>
      <button className="opt-add" disabled={!valid} onClick={() => onAdd({ name: name.trim(), code: codeUp, manager: manager.trim(), staff, taxId })}>สร้างสาขา</button>
    </Modal>
  );
}

/* ---------------- RECIPE ---------------- */
function Recipe() {
  const store = useContext(window.AppCtx);
  const D = window.POS_DATA, H = window.POS_HELP;
  const [pid, setPid] = useState("p_latte");
  const product = store.product(pid) || store.products[0];
  const pidEff = product ? product.id : null;
  const recipe = store.recipes[product.id] || [];
  const cost = recipe.reduce((s, r) => s + store.ingCost(r.i) * r.q, 0);
  const margin = product.price ? Math.round((product.price - cost) / product.price * 100) : 0;
  const usedIds = recipe.map((r) => r.i);
  const avail = store.ingredients.filter((i) => !usedIds.includes(i.id))
    .sort((a, b) => (b.kind === "mini" ? 1 : 0) - (a.kind === "mini" ? 1 : 0));
  const canEdit = store.access ? store.access.editRecipe : true;
  const canCatalog = store.access ? store.access.manageCatalog : false;
  const [prodEdit, setProdEdit] = useState(null);
  const [catOpen, setCatOpen] = useState(false);

  return (
    <div className="page">
      <div className="page-head">
        <div>
          <div className="page-eyebrow">เมนู & สูตร · กำหนดที่ HQ</div>
          <h1 className="page-title">จัดการสูตร (Recipe)</h1>
        </div>
        <div className="head-actions">
          {canCatalog && <button className="btn-ghost" onClick={() => setCatOpen(true)}><Icon name="list" size={16} /> จัดการหมวดหมู่</button>}
          {canCatalog ? <button className="btn-primary" onClick={() => setProdEdit({ new: true })}><Icon name="plus" size={16} /> เพิ่มเมนู</button> : (canEdit ? <Pill tone="amber">ซิงก์ทุกสาขาอัตโนมัติ</Pill> : <Pill tone="neutral">ดูอย่างเดียว (View only)</Pill>)}
        </div>
      </div>

      <div className="recipe-layout">
        <div className="card recipe-list">
          <div className="card-head"><div className="card-title">เมนูทั้งหมด</div></div>
          <div className="rl-scroll">
            {store.categories.map((c) => (
              <div key={c.id}>
                <div className="rl-cat">{c.name}</div>
                {store.products.filter((p) => p.cat === c.id).map((p) => {
                  const rc = (store.recipes[p.id] || []).reduce((s, r) => s + store.ingCost(r.i) * r.q, 0);
                  return (
                    <button key={p.id} className={"rl-item" + (pid === p.id ? " on" : "")} onClick={() => setPid(p.id)}>
                      <span className="rl-tone" style={{ background: p.tone }} />
                      <span className="rl-n">{p.name}</span>
                      <span className="rl-c">{rc > 0 ? H.thb(rc) : "—"}</span>
                    </button>
                  );
                })}
              </div>
            ))}
          </div>
        </div>

        <div className="card recipe-edit">
          <div className="recipe-hero">
            <div className="rh-thumb" style={{ background: product.tone }}>{product.en[0]}</div>
            <div className="rh-info">
              <div className="rh-name">{product.name}</div>
              <div className="rh-en">{product.en}</div>
              <div className="rh-price">ราคาขาย {H.thb(product.price)}</div>
            </div>
            <div className="rh-metrics">
              <div className="rhm"><span>ต้นทุนวัตถุดิบ</span><b>{H.thb2(cost)}</b></div>
              <div className="rhm"><span>กำไร/แก้ว</span><b style={{ color: "var(--sage)" }}>{H.thb2(product.price - cost)}</b></div>
              <div className="rhm"><span>Margin</span><b style={{ color: margin > 60 ? "var(--sage)" : "var(--amber)" }}>{margin}%</b></div>
            </div>
            {canCatalog && (
              <div className="rh-actions">
                <button className="btn-mini" onClick={() => setProdEdit(product)}>แก้ไขเมนู</button>
                <button className="row-x" onClick={() => { if (confirm("ลบเมนู \"" + product.name + "\" และสูตรของมัน?")) { const others = store.products.filter((p) => p.id !== product.id); store.removeProduct(product.id); if (others[0]) setPid(others[0].id); } }}><Icon name="close" size={14} /></button>
              </div>
            )}
          </div>

          {recipe.length === 0 ? (
            <div className="recipe-empty">เมนูนี้ไม่มีสูตรวัตถุดิบ (เช่น เบเกอรี่รับมาขาย)</div>
          ) : (
            <table className="tbl recipe-tbl">
              <thead><tr><th>วัตถุดิบ</th><th>ประเภท</th><th className="c">ปริมาณ</th><th className="r">ต้นทุน</th><th className="c"></th></tr></thead>
              <tbody>
                {recipe.map((r) => {
                  const ig = store.ing(r.i);
                  if (!ig) return null;
                  return (
                    <tr key={r.i}>
                      <td><span className="tbl-strong">{ig.name}</span>{ig.kind === "mini" && <span className="mini-badge">มินิ</span>}</td>
                      <td className="tbl-dim">{ig.kind === "mini" ? "มินิโปรดัก" : typeLabel(ig.type)}</td>
                      <td className="c">
                        {canEdit ? (
                          <div className="qstep">
                            <button onClick={() => store.updateRecipe(pidEff, r.i, -step(ig.unit))}><Icon name="minus" size={13} /></button>
                            <span>{r.q} {ig.unit}</span>
                            <button onClick={() => store.updateRecipe(pidEff, r.i, step(ig.unit))}><Icon name="plus" size={13} /></button>
                          </div>
                        ) : <span className="tbl-strong">{r.q} {ig.unit}</span>}
                      </td>
                      <td className="r tbl-dim">{H.thb2(store.ingCost(r.i) * r.q)}</td>
                      <td className="c">{canEdit && <button className="row-x" onClick={() => store.removeRecipeItem(pidEff, r.i)}><Icon name="close" size={14} /></button>}</td>
                    </tr>
                  );
                })}
              </tbody>
            </table>
          )}

          {avail.length > 0 && canEdit && (
            <div className="recipe-add">
              <span className="ra-l">เพิ่มส่วนผสม:</span>
              <div className="ra-chips">
                {avail.map((i) => (
                  <button key={i.id} className={i.kind === "mini" ? "chip-mini" : ""} onClick={() => store.updateRecipe(pidEff, i.id, step(i.unit))}>
                    <Icon name="plus" size={12} /> {i.name}{i.kind === "mini" && <span className="mini-badge">มินิ</span>}
                  </button>
                ))}
              </div>
            </div>
          )}
        </div>
      </div>

      <ProductModal item={prodEdit} categories={store.categories} onClose={() => setProdEdit(null)}
        onSave={async (data) => {
          if (prodEdit && !prodEdit.new) { store.updateProduct(prodEdit.id, data); window.toast({ title: "บันทึกเมนูแล้ว", msg: data.name }); }
          else { const nid = await store.addProduct(data); if (nid) setPid(nid); }
          setProdEdit(null);
        }} />
      <CategoryModal open={catOpen} categories={store.categories} products={store.products} onClose={() => setCatOpen(false)} store={store} />
    </div>
  );
}
function step(unit) { return unit === "pcs" ? 1 : unit === "g" ? 5 : 10; }

const PROD_TONES = ["#6b4a35", "#b07d4e", "#7a8a52", "#c08543", "#5e4631", "#a9824f", "#8a6543", "#b05a45"];

function ProductModal({ item, categories, onClose, onSave }) {
  const isNew = item && item.new;
  const H = window.POS_HELP;
  const [name, setName] = useState("");
  const [en, setEn] = useState("");
  const [cat, setCat] = useState(categories[0] ? categories[0].id : "");
  const [price, setPrice] = useState(0);
  const [tone, setTone] = useState(PROD_TONES[0]);
  useEffect(() => {
    if (item) {
      setName(isNew ? "" : item.name);
      setEn(isNew ? "" : item.en);
      setCat(isNew ? (categories[0] ? categories[0].id : "") : item.cat);
      setPrice(isNew ? 0 : item.price);
      setTone(isNew ? PROD_TONES[Math.floor(Math.random() * PROD_TONES.length)] : item.tone);
    }
  }, [item]);
  if (!item) return null;
  const valid = name.trim() && en.trim() && cat && price > 0;
  return (
    <Modal open={!!item} onClose={onClose} title={isNew ? "เพิ่มเมนูใหม่" : "แก้ไขเมนู"} subtitle={isNew ? "เมนูจะถูกซิงก์ไปทุกสาขา" : item.name} width={480}>
      <div className="form-grid">
        <label className="fld"><span>ชื่อเมนู (ไทย) *</span><input value={name} onChange={(e) => setName(e.target.value)} placeholder="เช่น ลาเต้" /></label>
        <label className="fld"><span>ชื่อเมนู (Eng) *</span><input value={en} onChange={(e) => setEn(e.target.value)} placeholder="Latte" /></label>
        <label className="fld"><span>หมวดหมู่ *</span>
          <select className="select" value={cat} onChange={(e) => setCat(e.target.value)}>{categories.map((c) => <option key={c.id} value={c.id}>{c.name}</option>)}</select>
        </label>
        <label className="fld"><span>ราคาขาย (฿) *</span><input type="number" value={price} onChange={(e) => setPrice(Math.max(0, +e.target.value || 0))} /></label>
        <div className="fld wide"><span>สีประจำเมนู</span>
          <div className="tone-row">{PROD_TONES.map((t) => <button key={t} type="button" className={"tone-sw" + (tone === t ? " on" : "")} style={{ background: t }} onClick={() => setTone(t)} />)}</div>
        </div>
      </div>
      <div className="form-note"><Icon name="check" size={14} /> {isNew ? "หลังเพิ่มเมนู สามารถกำหนดสูตรวัตถุดิบได้ทันที" : "การแก้ไขมีผลกับการแสดงผลและราคาขายทุกสาขา"}</div>
      <button className="opt-add" disabled={!valid} onClick={() => onSave({ name: name.trim(), en: en.trim(), cat, price, tone })}>{isNew ? "เพิ่มเมนู" : "บันทึก"}</button>
    </Modal>
  );
}

function CategoryModal({ open, categories, products, onClose, store }) {
  const [adding, setAdding] = useState("");
  const [editId, setEditId] = useState(null);
  const [editName, setEditName] = useState("");
  return (
    <Modal open={open} onClose={onClose} title="จัดการหมวดหมู่" subtitle="หมวดหมู่ใช้จัดกลุ่มเมนูในหน้าขายและหน้าสูตร" width={440}>
      <div className="cat-list">
        {categories.map((c) => {
          const count = products.filter((p) => p.cat === c.id).length;
          return (
            <div className="cat-row" key={c.id}>
              {editId === c.id ? (
                <input className="cat-input" value={editName} autoFocus onChange={(e) => setEditName(e.target.value)}
                  onKeyDown={(e) => { if (e.key === "Enter" && editName.trim()) { store.updateCategory(c.id, editName.trim()); setEditId(null); } }} />
              ) : (
                <div className="cat-name">{c.name} <span className="cat-count">{count} เมนู</span></div>
              )}
              <div className="row-actions">
                {editId === c.id ? (
                  <button className="btn-mini" onClick={() => { if (editName.trim()) store.updateCategory(c.id, editName.trim()); setEditId(null); }}>บันทึก</button>
                ) : (
                  <button className="btn-mini" onClick={() => { setEditId(c.id); setEditName(c.name); }}>แก้ไข</button>
                )}
                <button className="row-x" onClick={() => store.removeCategory(c.id)}><Icon name="close" size={14} /></button>
              </div>
            </div>
          );
        })}
      </div>
      <div className="cat-add">
        <input value={adding} onChange={(e) => setAdding(e.target.value)} placeholder="ชื่อหมวดหมู่ใหม่"
          onKeyDown={(e) => { if (e.key === "Enter" && adding.trim()) { store.addCategory(adding.trim()); setAdding(""); } }} />
        <button className="btn-primary" disabled={!adding.trim()} onClick={() => { store.addCategory(adding.trim()); setAdding(""); }}><Icon name="plus" size={15} /> เพิ่ม</button>
      </div>
    </Modal>
  );
}

/* ---------------- USERS (RBAC management) ---------------- */
function Users() {
  const store = useContext(window.AppCtx);
  const [roleF, setRoleF] = useState("all");
  const [branchF, setBranchF] = useState("all");
  const [edit, setEdit] = useState(null); // user object or {new:true}
  const branchName = (id) => { const b = store.branches.find((x) => x.id === id); return b ? "สาขา" + b.name : "ทุกสาขา (HQ)"; };
  const acc = store.access || {}; const me = store.currentUser;
  const ownBranchOnly = acc.allBranches === false && me;
  // what this role is allowed to see
  const scoped = ownBranchOnly ? store.users.filter((u) => u.branchId === me.branchId) : store.users;

  const users = scoped.filter((u) =>
    (roleF === "all" || u.role === roleF) &&
    (branchF === "all" || u.branchId === branchF || (branchF === "hq" && !u.branchId)));
  const counts = {
    hq_manager: scoped.filter((u) => u.role === "hq_manager").length,
    manager: scoped.filter((u) => u.role === "manager").length,
    staff: scoped.filter((u) => u.role === "staff").length,
    disabled: scoped.filter((u) => u.status === "disabled").length,
  };
  const roleTone = { admin: "gold", hq_manager: "blue", manager: "amber", staff: "neutral" };
  const roleLabel = { admin: "Admin", hq_manager: "HQ Manager", manager: "Manager", staff: "Staff" };

  return (
    <div className="page">
      <div className="page-head">
        <div>
          <div className="page-eyebrow">สิทธิ์ผู้ใช้งาน · {ownBranchOnly ? "สาขา" + (store.branches.find((b) => b.id === me.branchId) || {}).name : "HQ"}</div>
          <h1 className="page-title">จัดการผู้ใช้งาน</h1>
        </div>
        <button className="btn-primary" onClick={() => setEdit({ new: true })}><Icon name="plus" size={16} /> เพิ่มผู้ใช้</button>
      </div>

      <div className="kpi-row" style={{ gridTemplateColumns: ownBranchOnly ? "repeat(3,1fr)" : "repeat(5,1fr)" }}>
        <Stat label="ผู้ใช้ในขอบเขต" value={scoped.length} sub={ownBranchOnly ? "ในสาขานี้" : "ทุกบทบาท"} accent />
        {!ownBranchOnly && <Stat label="HQ Manager" value={counts.hq_manager} sub="ดูได้ทุกสาขา" />}
        {!ownBranchOnly && <Stat label="ผู้จัดการสาขา" value={counts.manager} sub="Manager" />}
        <Stat label="พนักงานสาขา" value={counts.staff} sub="Staff" />
        <Stat label="ปิดการใช้งาน" value={counts.disabled} sub="Disabled" tone={counts.disabled ? "var(--clay)" : "var(--sage)"} />
      </div>

      <div className="card">
        <div className="card-head">
          <div className="card-title">รายชื่อผู้ใช้</div>
          <div className="head-actions">
            <div className="seg seg-sm">
              {[["all", "ทั้งหมด"], ["hq_manager", "HQ Manager"], ["manager", "Manager"], ["staff", "Staff"]].filter(([id]) => !ownBranchOnly || (id !== "hq_manager" && id !== "manager")).map(([id, l]) => (
                <button key={id} className={"seg-b" + (roleF === id ? " on" : "")} onClick={() => setRoleF(id)}>{l}</button>
              ))}
            </div>
            {!ownBranchOnly && (
              <select className="select" value={branchF} onChange={(e) => setBranchF(e.target.value)}>
                <option value="all">ทุกสาขา</option>
                <option value="hq">HQ</option>
                {store.branches.map((b) => <option key={b.id} value={b.id}>สาขา{b.name}</option>)}
              </select>
            )}
          </div>
        </div>
        <table className="tbl">
          <thead><tr><th>ชื่อ</th><th>บทบาท</th><th>สาขา</th><th>รหัสพนักงาน</th><th>PIN</th><th>เบอร์โทร</th><th className="c">สถานะ</th><th className="c">จัดการ</th></tr></thead>
          <tbody>
            {users.map((u) => (
              <tr key={u.id}>
                <td><span className="user-cell"><span className="user-av">{u.name[0]}</span><span className="tbl-strong">{u.name}</span></span></td>
                <td><Pill tone={roleTone[u.role]}>{roleLabel[u.role]}</Pill></td>
                <td className="tbl-dim">{branchName(u.branchId)}</td>
                <td className="tbl-dim mono-cell">{u.code}</td>
                <td className="mono-cell"><button className="btn-mini" onClick={() => { if (confirm("ออก PIN ใหม่ให้ \"" + u.name + "\"? PIN เดิมจะใช้ไม่ได้ทันที")) store.resetUserPin(u.id); }}>ตั้ง PIN ใหม่</button></td>
                <td className="tbl-dim">{u.phone}</td>
                <td className="c">
                  <button className={"status-toggle" + (u.status === "active" ? " on" : "")} disabled={u.role === "admin"}
                    onClick={() => store.toggleUserStatus(u.id)} title={u.status === "active" ? "ใช้งานอยู่" : "ปิดอยู่"}>
                    <span /></button>
                </td>
                <td className="c">
                  <div className="row-actions">
                    <button className="btn-mini" onClick={() => setEdit(u)} disabled={u.role === "admin"}>แก้ไข</button>
                    <button className="row-x" onClick={() => { if (u.role !== "admin") store.removeUser(u.id); }} disabled={u.role === "admin"}><Icon name="close" size={14} /></button>
                  </div>
                </td>
              </tr>
            ))}
            {users.length === 0 && <tr><td colSpan={8} style={{ textAlign: "center", color: "var(--ink-soft)", padding: 30 }}>ไม่พบผู้ใช้ตามเงื่อนไข</td></tr>}
          </tbody>
        </table>
      </div>

      <div className="rbac-note">
        <Icon name="user" size={15} />
        <span><b>Admin</b> จัดการได้ทุกสาขา + ตั้งค่าระบบ · <b>HQ Manager</b> สิทธิ์เท่า Manager แต่ดูได้ทุกสาขา · <b>Manager</b> เห็นเฉพาะสาขาตน · <b>Staff</b> ใช้งานเฉพาะหน้าขาย POS ของสาขาตน</span>
      </div>

      <UserModal user={edit} branches={ownBranchOnly ? store.branches.filter((b) => b.id === me.branchId) : store.branches}
        existing={store.users} lockStaff={ownBranchOnly} onClose={() => setEdit(null)}
        onSave={(data) => {
          if (edit && !edit.new) { store.updateUser(edit.id, data); window.toast({ title: "บันทึกผู้ใช้แล้ว", msg: data.name }); }
          else { store.addUser(data); }
          setEdit(null);
        }} />
    </div>
  );
}

function UserModal({ user, branches, existing, onClose, onSave, lockStaff }) {
  const isNew = user && user.new;
  const [name, setName] = useState("");
  const [role, setRole] = useState("staff");
  const [branchId, setBranchId] = useState(branches[0] ? branches[0].id : "");
  const [code, setCode] = useState("");
  const [phone, setPhone] = useState("");
  useEffect(() => {
    if (user) {
      setName(isNew ? "" : user.name);
      setRole(isNew ? (lockStaff ? "staff" : "staff") : user.role);
      setBranchId(isNew ? (branches[0] ? branches[0].id : "") : (user.branchId || (branches[0] ? branches[0].id : "")));
      setCode(isNew ? "EMP-" + String(existing.length + 1).padStart(3, "0") : user.code);
      setPhone(isNew ? "" : user.phone);
    }
  }, [user]);
  if (!user) return null;
  const isHQ = role === "hq_manager";
  const valid = name.trim() && code.trim() && (isHQ || branchId);
  return (
    <Modal open={!!user} onClose={onClose} title={isNew ? "เพิ่มผู้ใช้งาน" : "แก้ไขผู้ใช้งาน"} subtitle="กำหนดบทบาทและสาขาที่สังกัด" width={480}>
      <div className="form-grid">
        <label className="fld wide"><span>ชื่อ-นามสกุล *</span><input value={name} onChange={(e) => setName(e.target.value)} placeholder="ชื่อพนักงาน" /></label>
        <div className="fld wide"><span>บทบาท *</span>
          <div className="seg" style={{ width: "100%" }}>
            {!lockStaff && <button className={"seg-b" + (role === "hq_manager" ? " on" : "")} style={{ flex: 1 }} onClick={() => setRole("hq_manager")}>HQ Manager</button>}
            {!lockStaff && <button className={"seg-b" + (role === "manager" ? " on" : "")} style={{ flex: 1 }} onClick={() => setRole("manager")}>Manager</button>}
            <button className={"seg-b" + (role === "staff" ? " on" : "")} style={{ flex: 1 }} onClick={() => setRole("staff")}>Staff</button>
          </div>
        </div>
        <label className="fld"><span>สาขาที่สังกัด {isHQ ? "" : "*"}</span>
          {isHQ ? (
            <input value="ทุกสาขา (HQ)" disabled />
          ) : (
            <select className="select" value={branchId} onChange={(e) => setBranchId(e.target.value)}>
              {branches.map((b) => <option key={b.id} value={b.id}>สาขา{b.name} · {b.code}</option>)}
            </select>
          )}
        </label>
        <label className="fld"><span>รหัสพนักงาน *</span><input value={code} onChange={(e) => setCode(e.target.value)} placeholder="EMP-000" /></label>
        <label className="fld wide"><span>เบอร์โทร</span><input value={phone} onChange={(e) => setPhone(e.target.value)} placeholder="08x-xxx-xxxx" /></label>
      </div>
      <div className="form-note"><Icon name="check" size={14} /> {isHQ ? "สิทธิ์เทียบเท่า Manager — ดูรายงาน/สต็อก/พนักงานได้ทุกสาขา แต่ไม่แก้ไขระบบส่วนกลาง" : role === "manager" ? "ผู้จัดการดูรายงาน/สต็อก/พนักงานได้เฉพาะสาขานี้" : "พนักงานใช้งานได้เฉพาะหน้าขาย POS ของสาขานี้"}</div>
      <button className="opt-add" disabled={!valid} onClick={() => onSave({ name: name.trim(), role, branchId: isHQ ? null : branchId, code: code.trim(), phone: phone.trim() })}>{isNew ? "สร้างผู้ใช้" : "บันทึก"}</button>
    </Modal>
  );
}

Object.assign(window, { Inventory, Branches, Recipe, Users });
