// Minimal CSV parser supporting quoted fields with embedded commas and newlines.
function parseCSV(text) {
  const rows = []; let cur = []; let buf = ""; let inQ = false;
  for (let i = 0; i < text.length; i++) {
    const c = text[i];
    if (inQ) {
      if (c === '"' && text[i + 1] === '"') { buf += '"'; i++; }
      else if (c === '"') inQ = false;
      else buf += c;
    } else {
      if (c === '"') inQ = true;
      else if (c === ",") { cur.push(buf); buf = ""; }
      else if (c === "\n" || c === "\r") {
        if (c === "\r" && text[i + 1] === "\n") i++;
        cur.push(buf); rows.push(cur); cur = []; buf = "";
      } else buf += c;
    }
  }
  if (buf.length || cur.length) { cur.push(buf); rows.push(cur); }
  return rows.filter((r) => r.some((v) => v.trim().length));
}

// Admin — dashboard, products, pre-bookings, loyalty, users (all Firestore-backed)
function AdminScreen() {
  const [tab, setTab] = React.useState("dash");
  const tabs = [
    { id: "dash",     label: "Dashboard" },
    { id: "reports",  label: "Reports" },
    { id: "products", label: "Products" },
    { id: "loyalty",  label: "Loyalty" },
    { id: "prebook",  label: "Pre-bookings" },
    { id: "users",    label: "Users" },
    { id: "printer",  label: "Printer" },
  ];
  return (
    <div className="admin admin-stacked">
      <nav className="admin-topbar">
        <div className="admin-brand mono">ADMIN</div>
        <select className="admin-topbar-select mono" value={tab} onChange={(e) => setTab(e.target.value)}>
          {tabs.map((t) => <option key={t.id} value={t.id}>{t.label}</option>)}
        </select>
        <div className="admin-topbar-tabs">
          {tabs.map((t) => (
            <button key={t.id} className={"admin-tab" + (tab === t.id ? " active" : "")} onClick={() => setTab(t.id)}>
              {t.label}
            </button>
          ))}
        </div>
      </nav>
      <main className="admin-main">
        {tab === "dash"     && <AdminDash />}
        {tab === "reports"  && <AdminReports />}
        {tab === "products" && <AdminProducts />}
        {tab === "loyalty"  && <AdminLoyalty />}
        {tab === "prebook"  && <AdminPrebook />}
        {tab === "users"    && <AdminUsers />}
        {tab === "printer"  && <AdminPrinter />}
      </main>
    </div>
  );
}

function AdminDash() {
  const { orders } = usePOS();
  const open = orders.filter((o) => o.status !== "closed").length;
  const revenue = orders.reduce((s, o) => s + (o.total || 0), 0);
  const totalOrders = orders.length;
  const itemsSold = orders.reduce((s, o) => s + o.items.reduce((a, i) => a + i.qty, 0), 0);
  const avg = totalOrders ? Math.round(revenue / totalOrders) : 0;

  // Margin = sum of (price + modPrice - cogs) * qty across all order items
  const margin = orders.reduce((s, o) =>
    s + o.items.reduce((a, i) =>
      a + ((i.price + (i.modPrice || 0) - (i.cogs || 0)) * i.qty), 0), 0);
  const marginPct = revenue > 0 ? Math.round(margin / revenue * 100) : 0;

  // Top sellers + per-product margin
  const counts = {}, marginByName = {};
  orders.forEach((o) => o.items.forEach((i) => {
    counts[i.name] = (counts[i.name] || 0) + i.qty;
    marginByName[i.name] = (marginByName[i.name] || 0) + (i.price + (i.modPrice || 0) - (i.cogs || 0)) * i.qty;
  }));
  const top = Object.entries(counts).sort((a, b) => b[1] - a[1]).slice(0, 6);
  const max = top[0]?.[1] || 1;

  // Hourly buckets
  const hourly = Array.from({ length: 18 }, (_, h) => ({ h: String(h).padStart(2, "0"), orders: 0, revenue: 0 }));
  orders.forEach((o) => {
    const ts = o.createdAt?.toDate ? o.createdAt.toDate() : new Date();
    const h = ts.getHours();
    if (hourly[h]) { hourly[h].orders++; hourly[h].revenue += (o.total || 0); }
  });
  const hourlyShown = hourly.filter((h) => h.orders).length ? hourly.slice(6, 22) : hourly.slice(6, 18);

  return (
    <div className="admin-pane">
      <header className="pane-head">
        <div>
          <div className="eyebrow mono">DASHBOARD · {fmtDay()}</div>
          <h2>Today's overview</h2>
        </div>
        <div className="muted mono">Live · {fmtClock()}</div>
      </header>

      <div className="kpis">
        <KPI label="Revenue today" value={money(revenue)} delta={`${itemsSold} items sold`} />
        <KPI label="Orders" value={totalOrders} delta={`avg ${money(avg)}`} />
        <KPI label="Margin (gross)" value={money(margin)} delta={`${marginPct}% of revenue`} />
        <KPI label="Active now" value={open} delta="tickets in flight" accent />
      </div>

      <div className="dash-grid">
        <section className="panel-card">
          <h3>Hourly revenue</h3>
          {totalOrders === 0
            ? <div className="muted mono" style={{ padding: 20 }}>No orders yet today.</div>
            : <BarChart data={hourlyShown} />}
        </section>
        <section className="panel-card">
          <h3>Top sellers</h3>
          {top.length === 0
            ? <div className="muted mono" style={{ padding: 20 }}>—</div>
            : <ul className="top-list">
                {top.map(([name, qty], i) => (
                  <li key={name}>
                    <Mono className="rank">{String(i + 1).padStart(2, "0")}</Mono>
                    <span className="top-name">{name}</span>
                    <div className="top-bar"><div style={{ width: (qty / max * 100) + "%" }} /></div>
                    <Mono>{qty}</Mono>
                    <Mono className="muted" style={{ marginLeft: 12, minWidth: 80, textAlign: "right" }}>{moneyK(marginByName[name] || 0)}</Mono>
                  </li>
                ))}
              </ul>}
        </section>
      </div>
    </div>
  );
}

function KPI({ label, value, delta, accent }) {
  return (
    <div className={"kpi-card" + (accent ? " accent" : "")}>
      <div className="kpi-label mono">{label.toUpperCase()}</div>
      <Mono className="kpi-value">{value}</Mono>
      <div className="kpi-delta mono">{delta}</div>
    </div>
  );
}

function BarChart({ data }) {
  const max = Math.max(1, ...data.map((d) => d.revenue));
  return (
    <div className="bar-chart">
      {data.map((d) => (
        <div className="bar-col" key={d.h}>
          <div className="bar-wrap">
            <div className="bar" style={{ height: (d.revenue / max * 100) + "%" }} />
            <span className="bar-tip mono">{moneyK(d.revenue)}</span>
          </div>
          <Mono className="bar-label">{d.h}</Mono>
        </div>
      ))}
    </div>
  );
}

function AdminProducts() {
  const { products, db, showToast } = usePOS();
  const [editing, setEditing] = React.useState(null);
  const [selected, setSelected] = React.useState({});
  const [query, setQuery] = React.useState("");
  const [catFilter, setCatFilter] = React.useState("");
  const [stationFilter, setStationFilter] = React.useState("");
  const [activeFilter, setActiveFilter] = React.useState(""); // "", "active", "inactive"
  const [sort, setSort] = React.useState({ key: "name", dir: "asc" });
  const fileRef = React.useRef(null);

  const categories = React.useMemo(
    () => Array.from(new Set(products.map((p) => p.category).filter(Boolean))).sort(),
    [products]
  );

  const visibleProducts = React.useMemo(() => {
    const q = query.trim().toLowerCase();
    let list = products.filter((p) => {
      if (catFilter && p.category !== catFilter) return false;
      if (stationFilter && p.station !== stationFilter) return false;
      if (activeFilter === "active" && !p.active) return false;
      if (activeFilter === "inactive" && p.active) return false;
      if (q) {
        const hay = `${p.name || ""} ${p.sku || ""} ${p.category || ""} ${p.desc || ""}`.toLowerCase();
        if (!hay.includes(q)) return false;
      }
      return true;
    });
    const dir = sort.dir === "asc" ? 1 : -1;
    const getVal = (p) => {
      switch (sort.key) {
        case "sku":      return (p.sku || "").toLowerCase();
        case "name":     return (p.name || "").toLowerCase();
        case "category": return (p.category || "").toLowerCase();
        case "station":  return (p.station || "").toLowerCase();
        case "price":    return Number(p.price) || 0;
        case "cogs":     return Number(p.cogs) || 0;
        case "margin":   return (Number(p.price) || 0) - (Number(p.cogs) || 0);
        case "stock":    return Number(p.stock) || 0;
        case "active":   return p.active ? 1 : 0;
        default:         return 0;
      }
    };
    return list.slice().sort((a, b) => {
      const va = getVal(a), vb = getVal(b);
      if (va < vb) return -1 * dir;
      if (va > vb) return  1 * dir;
      return 0;
    });
  }, [products, query, catFilter, stationFilter, activeFilter, sort]);

  const toggleSort = (key) => setSort((s) =>
    s.key === key ? { key, dir: s.dir === "asc" ? "desc" : "asc" } : { key, dir: "asc" });
  const sortIndicator = (key) => sort.key === key ? (sort.dir === "asc" ? " ▲" : " ▼") : "";
  const SortTh = ({ k, children, style }) => (
    <th style={{ ...(style || {}), cursor: "pointer", userSelect: "none" }} onClick={() => toggleSort(k)}>
      {children}<span className="mono muted" style={{ fontSize: 10 }}>{sortIndicator(k)}</span>
    </th>
  );

  const selectedIds = Object.keys(selected).filter((k) => selected[k]);
  const allSelected = visibleProducts.length > 0
    && visibleProducts.every((p) => selected[p.id]);

  const toggleAll = () => {
    if (allSelected) {
      const next = { ...selected };
      visibleProducts.forEach((p) => { delete next[p.id]; });
      setSelected(next);
    } else {
      const next = { ...selected };
      visibleProducts.forEach((p) => { next[p.id] = true; });
      setSelected(next);
    }
  };
  const toggleOne = (id) => setSelected((s) => ({ ...s, [id]: !s[id] }));

  const bulkSetActive = async (active) => {
    if (!selectedIds.length) return;
    const batch = db.batch();
    selectedIds.forEach((id) => batch.update(db.collection("products").doc(id), { active }));
    await batch.commit();
    showToast(`${selectedIds.length} product${selectedIds.length === 1 ? "" : "s"} ${active ? "activated" : "deactivated"}`);
    setSelected({});
  };
  const bulkDelete = async () => {
    if (!selectedIds.length) return;
    if (!confirm(`Delete ${selectedIds.length} product${selectedIds.length === 1 ? "" : "s"}? This cannot be undone.`)) return;
    while (selectedIds.length) {
      const chunk = selectedIds.splice(0, 400);
      const batch = db.batch();
      chunk.forEach((id) => batch.delete(db.collection("products").doc(id)));
      await batch.commit();
    }
    showToast("Deleted");
    setSelected({});
  };

  const seed = async () => {
    if (!confirm(`Add ${window.SEED_PRODUCTS.length} demo products?`)) return;
    const batch = db.batch();
    window.SEED_PRODUCTS.forEach((p) => batch.set(db.collection("products").doc(), p));
    await batch.commit();
    showToast("Demo menu added");
  };

  const remove = async (id) => {
    if (!confirm("Delete product?")) return;
    await db.collection("products").doc(id).delete();
  };

  const importCSV = async (e) => {
    const file = e.target.files?.[0];
    if (!file) return;
    const text = await file.text();
    const rows = parseCSV(text);
    if (!rows.length) return alert("CSV is empty");
    const header = rows[0].map((h) => h.trim().toLowerCase());
    const required = ["name", "category", "station", "price"];
    const missing = required.filter((r) => !header.includes(r));
    if (missing.length) return alert("CSV is missing required columns: " + missing.join(", "));
    const items = [];
    for (let r = 1; r < rows.length; r++) {
      const row = rows[r]; if (!row.length || !row[0]) continue;
      const obj = {};
      header.forEach((h, i) => { obj[h] = (row[i] || "").trim(); });
      let modifiers = [];
      if (obj.modifiers) {
        try { modifiers = JSON.parse(obj.modifiers); } catch (_) { modifiers = []; }
      }
      items.push({
        sku:      obj.sku || "",
        name:     obj.name,
        category: obj.category,
        station:  obj.station || "bar",
        price:    Number(obj.price) || 0,
        cogs:     Number(obj.cogs) || 0,
        stock:    obj.stock === "" || obj.stock == null ? 999 : Number(obj.stock),
        desc:     obj.desc || "",
        swatch:   obj.swatch || "#a98558",
        active:   obj.active == null || obj.active === "" ? true : /^(true|1|yes|y)$/i.test(obj.active),
        modifiers,
      });
    }
    if (!items.length) return alert("No valid rows found");
    if (!confirm(`Import ${items.length} products?`)) { e.target.value = ""; return; }
    // Firestore batch max is 500 ops; we're well under, but split anyway for safety.
    while (items.length) {
      const chunk = items.splice(0, 400);
      const batch = db.batch();
      chunk.forEach((p) => batch.set(db.collection("products").doc(), p));
      await batch.commit();
    }
    showToast("Imported products");
    e.target.value = "";
  };

  const downloadTemplate = () => {
    const modSample = JSON.stringify([{ group: "Serve", type: "single", options: [{ id: "hot", label: "Hot", delta: 0 }, { id: "ice", label: "Ice", delta: 0 }] }]).replace(/"/g, '""');
    const csv = `sku,name,category,station,price,cogs,stock,desc,swatch,active,modifiers
P001,Americano,Espresso,bar,22000,10000,999,House blend,#3a2a1a,true,"${modSample}"
P002,Latte,Milk,bar,34000,15000,999,Espresso silky milk,#c8a585,true,
`;
    const blob = new Blob([csv], { type: "text/csv" });
    const a = document.createElement("a");
    a.href = URL.createObjectURL(blob); a.download = "products-template.csv"; a.click();
    URL.revokeObjectURL(a.href);
  };

  return (
    <div className="admin-pane">
      <header className="pane-head">
        <div>
          <div className="eyebrow mono">CATALOG</div>
          <h2>{products.length} products</h2>
        </div>
        <div className="row" style={{ gap: 8 }}>
          {products.length === 0 && <button className="btn-ghost" onClick={seed}>Install demo menu</button>}
          <button className="btn-ghost" onClick={downloadTemplate}>CSV template</button>
          <button className="btn-ghost" onClick={() => fileRef.current?.click()}>Import CSV</button>
          <input ref={fileRef} type="file" accept=".csv,text/csv" onChange={importCSV} style={{ display: "none" }} />
          <button className="btn-primary" onClick={() => setEditing({})}>+ Add product</button>
        </div>
      </header>
      <div className="row" style={{ gap: 8, flexWrap: "wrap", margin: "10px 0", alignItems: "flex-end" }}>
        <label className="field" style={{ flex: "1 1 240px" }}>
          <span className="field-label mono">Search</span>
          <input value={query} onChange={(e) => setQuery(e.target.value)} placeholder="Name, SKU, category…" />
        </label>
        <label className="field" style={{ flex: "0 0 160px" }}>
          <span className="field-label mono">Category</span>
          <select value={catFilter} onChange={(e) => setCatFilter(e.target.value)}>
            <option value="">All</option>
            {categories.map((c) => <option key={c} value={c}>{c}</option>)}
          </select>
        </label>
        <label className="field" style={{ flex: "0 0 140px" }}>
          <span className="field-label mono">Station</span>
          <select value={stationFilter} onChange={(e) => setStationFilter(e.target.value)}>
            <option value="">All</option>
            <option value="bar">bar</option>
            <option value="kitchen">kitchen</option>
          </select>
        </label>
        <label className="field" style={{ flex: "0 0 140px" }}>
          <span className="field-label mono">Status</span>
          <select value={activeFilter} onChange={(e) => setActiveFilter(e.target.value)}>
            <option value="">All</option>
            <option value="active">Active</option>
            <option value="inactive">Inactive</option>
          </select>
        </label>
        {(query || catFilter || stationFilter || activeFilter) && (
          <button className="btn-ghost-sm" onClick={() => { setQuery(""); setCatFilter(""); setStationFilter(""); setActiveFilter(""); }}>
            Clear filters
          </button>
        )}
        <div className="muted mono" style={{ fontSize: 12, marginLeft: "auto" }}>
          {visibleProducts.length} of {products.length}
        </div>
      </div>
      {selectedIds.length > 0 && (
        <div className="bulk-bar">
          <span className="mono">{selectedIds.length} selected</span>
          <button className="btn-ghost-sm" onClick={() => bulkSetActive(true)}>Activate</button>
          <button className="btn-ghost-sm" onClick={() => bulkSetActive(false)}>Deactivate</button>
          <button className="btn-ghost-sm danger" onClick={bulkDelete}>Delete</button>
          <button className="btn-ghost-sm" onClick={() => setSelected({})}>Clear</button>
        </div>
      )}
      <div className="panel-card no-pad">
        <table className="data-table">
          <thead>
            <tr>
              <th style={{ width: 32 }}><input type="checkbox" checked={allSelected} onChange={toggleAll} /></th>
              <th></th>
              <SortTh k="sku">SKU</SortTh>
              <SortTh k="name">Name</SortTh>
              <SortTh k="category">Category</SortTh>
              <SortTh k="station">Station</SortTh>
              <SortTh k="price">Price</SortTh>
              <SortTh k="cogs">COGS</SortTh>
              <SortTh k="margin">Margin</SortTh>
              <SortTh k="stock">Stock</SortTh>
              <th>Modifiers</th>
              <SortTh k="active">Active</SortTh>
              <th></th>
            </tr>
          </thead>
          <tbody>
            {visibleProducts.length === 0 && (
              <tr><td colSpan="13" className="muted mono" style={{ textAlign: "center", padding: 24 }}>
                {products.length === 0 ? "No products yet." : "No products match the filters."}
              </td></tr>
            )}
            {visibleProducts.map((p) => {
              const m = (p.price || 0) - (p.cogs || 0);
              const mp = p.price > 0 ? Math.round(m / p.price * 100) : 0;
              return (
                <tr key={p.id} className={selected[p.id] ? "row-selected" : ""}>
                  <td><input type="checkbox" checked={!!selected[p.id]} onChange={() => toggleOne(p.id)} /></td>
                  <td><ProductSwatch color={p.swatch || "#a98558"} label={p.name} size={36} /></td>
                  <td><Mono>{p.sku || "—"}</Mono></td>
                  <td><div>{p.name}</div><div className="muted mono">{p.desc}</div></td>
                  <td><Mono>{p.category}</Mono></td>
                  <td><span className={"chip-station chip-" + p.station}>{p.station}</span></td>
                  <td><Mono>{money(p.price)}</Mono></td>
                  <td><Mono className="muted">{money(p.cogs || 0)}</Mono></td>
                  <td><Mono className={mp < 30 ? "stock-low" : ""}>{money(m)} <span style={{ opacity: 0.6 }}>· {mp}%</span></Mono></td>
                  <td><Mono className={p.stock <= 20 ? "stock-low" : ""}>{p.stock >= 999 ? "∞" : p.stock}</Mono></td>
                  <td><Mono className="muted" style={{ fontSize: 11 }}>{
                    (p.modifiers && p.modifiers.length)
                      ? p.modifiers.map((g) => `${g.group}(${g.options.length})`).join(" · ")
                      : `[${p.category} default]`
                  }</Mono></td>
                  <td><Mono>{p.active ? "✓" : "—"}</Mono></td>
                  <td className="row-actions">
                    <button className="btn-ghost-sm" onClick={() => setEditing(p)}>Edit</button>
                    <button className="btn-ghost-sm" onClick={() => remove(p.id)}>Delete</button>
                  </td>
                </tr>
              );
            })}
          </tbody>
        </table>
      </div>
      {editing && <ProductEditor product={editing} onClose={() => setEditing(null)} />}
    </div>
  );
}

function ProductEditor({ product, onClose }) {
  const { db, products } = usePOS();
  const knownCats = Array.from(new Set([
    ...window.CATEGORIES.filter((c) => c !== "All"),
    ...products.map((x) => x.category).filter(Boolean),
  ])).sort();
  const [p, setP] = React.useState({
    sku: "", name: "", category: "Espresso", station: "bar", price: 0, cogs: 0, stock: 999,
    swatch: "#a98558", desc: "", active: true, modifiers: [], ...product,
  });
  // Modifier editing helpers
  const slug = (s) => (s || "").toLowerCase().replace(/[^a-z0-9]+/g, "").slice(0, 12) || ("o" + Math.random().toString(36).slice(2, 5));
  const updateGroups = (groups) => setP({ ...p, modifiers: groups });
  const addGroup = () => updateGroups([...(p.modifiers || []), { group: "Type", type: "single", options: [{ id: "opt1", label: "", delta: 0 }] }]);
  const setGroup = (gi, patch) => updateGroups(p.modifiers.map((g, i) => i === gi ? { ...g, ...patch } : g));
  const removeGroup = (gi) => updateGroups(p.modifiers.filter((_, i) => i !== gi));
  const addOpt = (gi) => setGroup(gi, { options: [...p.modifiers[gi].options, { id: "opt" + (p.modifiers[gi].options.length + 1), label: "", delta: 0 }] });
  const setOpt = (gi, oi, patch) => setGroup(gi, { options: p.modifiers[gi].options.map((o, i) => i === oi ? { ...o, ...patch } : o) });
  const removeOpt = (gi, oi) => setGroup(gi, { options: p.modifiers[gi].options.filter((_, i) => i !== oi) });
  const applyTemplate = (name) => {
    const T = {
      "hot-ice": [{ group: "Serve", type: "single", options: [{ id: "hot", label: "Hot", delta: 0 }, { id: "ice", label: "Ice", delta: 0 }] }],
      "size":    [{ group: "Size",  type: "single", options: [{ id: "r", label: "Regular", delta: 0 }, { id: "l", label: "Large", delta: 6000 }] }],
      "milk":    [{ group: "Milk",  type: "single", options: [{ id: "full", label: "Whole", delta: 0 }, { id: "oat", label: "Oat", delta: 7000 }, { id: "almond", label: "Almond", delta: 7000 }] }],
      "category": window.MODIFIERS[p.category] ? JSON.parse(JSON.stringify(window.MODIFIERS[p.category])) : [],
    };
    updateGroups([...(p.modifiers || []), ...T[name]]);
  };

  const save = async () => {
    // Clean modifiers — drop empty groups/options and auto-generate ids from labels
    const modifiers = (p.modifiers || [])
      .map((g) => ({
        group: (g.group || "").trim() || "Option",
        type: g.type === "multi" ? "multi" : "single",
        options: (g.options || [])
          .filter((o) => (o.label || "").trim().length)
          .map((o) => ({ id: o.id || slug(o.label), label: o.label.trim(), delta: Number(o.delta) || 0 })),
      }))
      .filter((g) => g.options.length);

    const payload = {
      sku: p.sku || "", name: p.name, category: p.category, station: p.station,
      price: Number(p.price), cogs: Number(p.cogs) || 0, stock: Number(p.stock),
      swatch: p.swatch, desc: p.desc || "", active: !!p.active, modifiers,
    };
    if (product.id) await db.collection("products").doc(product.id).update(payload);
    else await db.collection("products").add(payload);
    onClose();
  };
  return (
    <div className="sheet-wrap" onMouseDown={onClose}>
      <div className="sheet" onMouseDown={(e) => e.stopPropagation()}>
        <header className="sheet-head">
          <div><div className="eyebrow mono">PRODUCT</div><h3>{product.id ? "Edit" : "Add"} product</h3></div>
          <button className="icon-x" onClick={onClose}>×</button>
        </header>
        <div className="sheet-body">
          <div className="row" style={{ gap: 8 }}>
            <label className="field" style={{ flex: "0 0 140px" }}><span className="field-label mono">SKU</span>
              <input value={p.sku || ""} onChange={(e) => setP({ ...p, sku: e.target.value })} placeholder="P001" />
            </label>
            <label className="field" style={{ flex: 1 }}><span className="field-label mono">Name</span>
              <input value={p.name} onChange={(e) => setP({ ...p, name: e.target.value })} />
            </label>
          </div>
          <label className="field"><span className="field-label mono">Description</span>
            <input value={p.desc} onChange={(e) => setP({ ...p, desc: e.target.value })} />
          </label>
          <div className="row" style={{ gap: 8 }}>
            <label className="field"><span className="field-label mono">Category</span>
              <input list="cat-options" value={p.category} onChange={(e) => setP({ ...p, category: e.target.value })} placeholder="Coffee / Food / Tea …" />
              <datalist id="cat-options">{knownCats.map((c) => <option key={c} value={c} />)}</datalist>
            </label>
            <label className="field"><span className="field-label mono">Station</span>
              <select value={p.station} onChange={(e) => setP({ ...p, station: e.target.value })}>
                <option value="bar">bar</option>
                <option value="kitchen">kitchen</option>
              </select>
            </label>
          </div>
          <div className="row" style={{ gap: 8 }}>
            <label className="field"><span className="field-label mono">Price (Rp)</span>
              <input type="number" value={p.price} onChange={(e) => setP({ ...p, price: e.target.value })} />
            </label>
            <label className="field"><span className="field-label mono">COGS (Rp)</span>
              <input type="number" value={p.cogs || 0} onChange={(e) => setP({ ...p, cogs: e.target.value })} />
            </label>
            <label className="field"><span className="field-label mono">Stock</span>
              <input type="number" value={p.stock} onChange={(e) => setP({ ...p, stock: e.target.value })} />
            </label>
            <label className="field"><span className="field-label mono">Swatch</span>
              <input type="color" value={p.swatch} onChange={(e) => setP({ ...p, swatch: e.target.value })} />
            </label>
          </div>
          <div className="muted mono" style={{ fontSize: 12, marginTop: 8 }}>
            Margin: {money(Math.max(0, Number(p.price || 0) - Number(p.cogs || 0)))} {p.price > 0 && `· ${Math.round((p.price - (p.cogs || 0)) / p.price * 100)}%`}
          </div>
          <div className="mod-editor" style={{ marginTop: 18, paddingTop: 14, borderTop: "1px solid var(--line)" }}>
            <div className="row" style={{ justifyContent: "space-between", marginBottom: 8 }}>
              <div>
                <div className="eyebrow mono">MODIFIER GROUPS</div>
                <div className="muted mono" style={{ fontSize: 11 }}>
                  Shown to the cashier when this product is selected. Leave empty to use the {p.category} category defaults.
                </div>
              </div>
              <div className="row" style={{ gap: 6 }}>
                <button type="button" className="btn-ghost-sm" onClick={() => applyTemplate("hot-ice")}>+ Hot/Ice</button>
                <button type="button" className="btn-ghost-sm" onClick={() => applyTemplate("size")}>+ Size</button>
                <button type="button" className="btn-ghost-sm" onClick={() => applyTemplate("milk")}>+ Milk</button>
                <button type="button" className="btn-ghost-sm" onClick={addGroup}>+ Empty group</button>
              </div>
            </div>

            {(p.modifiers || []).length === 0 && (
              <div className="muted mono" style={{ fontSize: 12, padding: "10px 0" }}>No custom modifiers. Cashier will see the {p.category} defaults.</div>
            )}

            {(p.modifiers || []).map((g, gi) => (
              <div key={gi} className="mod-group-edit">
                <div className="row" style={{ gap: 8, alignItems: "flex-end" }}>
                  <label className="field" style={{ flex: 1 }}>
                    <span className="field-label mono">Group name</span>
                    <input value={g.group} onChange={(e) => setGroup(gi, { group: e.target.value })} placeholder="Type / Size / Milk" />
                  </label>
                  <label className="field" style={{ flex: "0 0 140px" }}>
                    <span className="field-label mono">Choose</span>
                    <select value={g.type} onChange={(e) => setGroup(gi, { type: e.target.value })}>
                      <option value="single">Pick one</option>
                      <option value="multi">Pick multiple</option>
                    </select>
                  </label>
                  <button type="button" className="btn-ghost-sm danger" onClick={() => removeGroup(gi)}>Remove group</button>
                </div>
                <div className="mod-opts-edit">
                  {g.options.map((o, oi) => (
                    <div key={oi} className="row" style={{ gap: 6, marginTop: 6 }}>
                      <input style={{ flex: 1 }} value={o.label} onChange={(e) => setOpt(gi, oi, { label: e.target.value })} placeholder="e.g. Hot, Ice, Large" />
                      <input type="number" style={{ flex: "0 0 120px" }} value={o.delta} onChange={(e) => setOpt(gi, oi, { delta: e.target.value })} placeholder="Δ price" />
                      <button type="button" className="btn-ghost-sm" onClick={() => removeOpt(gi, oi)}>×</button>
                    </div>
                  ))}
                  <button type="button" className="btn-ghost-sm" style={{ marginTop: 6 }} onClick={() => addOpt(gi)}>+ Option</button>
                </div>
              </div>
            ))}
          </div>

          <label className="row" style={{ gap: 8, marginTop: 14 }}>
            <input type="checkbox" checked={p.active} onChange={(e) => setP({ ...p, active: e.target.checked })} />
            <span className="mono">Active</span>
          </label>
        </div>
        <footer className="sheet-foot">
          <button className="btn-ghost" onClick={onClose}>Cancel</button>
          <button className="btn-primary" onClick={save}>Save</button>
        </footer>
      </div>
    </div>
  );
}

function AdminLoyalty() {
  const { customers } = usePOS();
  const tierOf = (spent) => spent > 2000000 ? "Golden" : spent > 500000 ? "Regular" : "New";
  return (
    <div className="admin-pane">
      <header className="pane-head">
        <div>
          <div className="eyebrow mono">LOYALTY</div>
          <h2>Regulars · {customers.length}</h2>
        </div>
        <div className="muted mono">Earn 1 point per Rp 10.000 spent</div>
      </header>
      {customers.length === 0
        ? <div className="panel-card muted mono" style={{ padding: 24 }}>No customer data yet. Customers appear after their first named order.</div>
        : <div className="loyalty-grid">
            {customers.map((c) => {
              const tier = tierOf(c.totalSpent || 0);
              return (
                <article className="loyalty-card" key={c.id}>
                  <header>
                    <div className="loyalty-avatar mono">{(c.name || "??").split(" ").map((w) => w[0]).slice(0, 2).join("")}</div>
                    <div>
                      <div className="loyalty-name">{c.name}</div>
                      <div className="muted mono">id · {c.id}</div>
                    </div>
                    <span className={"tier tier-" + tier.toLowerCase()}>{tier}</span>
                  </header>
                  <div className="loyalty-stats">
                    <div><span className="muted mono">VISITS</span><Mono>{c.visits || 0}</Mono></div>
                    <div><span className="muted mono">SPENT</span><Mono>{money(c.totalSpent || 0)}</Mono></div>
                    <div><span className="muted mono">POINTS</span><Mono>{c.points || 0}</Mono></div>
                  </div>
                  <footer>
                    <div className="muted mono">Last visit · {c.lastVisit?.toDate ? c.lastVisit.toDate().toLocaleString("en-GB") : "—"}</div>
                  </footer>
                </article>
              );
            })}
          </div>}
    </div>
  );
}

function AdminPrebook() {
  const { prebookings, verifyPrebooking, db, showToast, user } = usePOS();
  const [detail, setDetail] = React.useState(null);
  const [notifyOpen, setNotifyOpen] = React.useState(false);
  const cancel = async (id) => { if (confirm("Cancel booking?")) await db.collection("prebookings").doc(id).update({ status: "cancelled" }); };

  // Push a booking straight to the kitchen — creates an unpaid order from the
  // pre-booking items, mirroring what the cashier does on check-in.
  const sendToKitchen = async (pb) => {
    if (!confirm(`Send ${pb.customerName}'s booking to the kitchen now?`)) return;
    const shortId = "P" + Math.random().toString(36).slice(2, 5).toUpperCase();
    const hasKitchen = (pb.items || []).some((i) => i.station === "kitchen");
    const hasBar = (pb.items || []).some((i) => i.station === "bar");
    await db.collection("orders").add({
      shortId,
      table: pb.table || "PRE",
      customer: pb.customerName,
      items: (pb.items || []).map((i) => ({
        id: i.id || "", sku: i.sku || "", name: i.name, price: i.price, qty: i.qty,
        station: i.station || "kitchen", mods: i.mods || [], modPrice: i.modPrice || 0,
        cogs: i.cogs || 0, notes: i.notes || "",
      })),
      subtotal: pb.subtotal || 0,
      depositApplied: pb.depositPaid || 0,
      uniqueCode: 0,
      total: Math.max(0, (pb.subtotal || 0) - (pb.depositPaid || 0)),
      tip: 0, payments: [], paymentMethod: null,
      status: "open", paid: false,
      barStatus: hasBar ? "new" : null,
      kitchenStatus: hasKitchen ? "new" : null,
      prebookingId: pb.id,
      cashierUid: user?.uid || null, cashierEmail: user?.email || null,
      dateKey: new Date().toISOString().slice(0, 10),
      createdAt: firebase.firestore.FieldValue.serverTimestamp(),
    });
    await db.collection("prebookings").doc(pb.id).update({ status: "checked_in" });
    showToast("Sent to kitchen");
    setDetail(null);
  };

  return (
    <div className="admin-pane">
      <header className="pane-head">
        <div>
          <div className="eyebrow mono">PRE-BOOKINGS</div>
          <h2>{prebookings.length} on the books</h2>
        </div>
        <button className="btn-ghost" onClick={() => setNotifyOpen(true)}>Email notifications</button>
      </header>
      <div className="panel-card no-pad">
        <table className="data-table">
          <thead><tr><th>Date</th><th>Customer</th><th>Phone</th><th>Items</th><th>Total</th><th>Deposit</th><th>Status</th><th></th></tr></thead>
          <tbody>
            {prebookings.map((p) => (
              <tr key={p.id}>
                <td><Mono>{p.visitDate}{p.visitTime ? " · " + p.visitTime : ""}</Mono></td>
                <td>{p.customerName}</td>
                <td className="mono muted">{p.customerPhone}</td>
                <td><Mono>{(p.items || []).reduce((a, i) => a + i.qty, 0)}</Mono></td>
                <td><Mono>{money(p.subtotal)}</Mono></td>
                <td><Mono>{money(p.depositPaid || 0)}/{money(p.depositRequired || 0)}</Mono></td>
                <td><StatusPill status={p.status}>{p.status}</StatusPill></td>
                <td className="row-actions">
                  <button className="btn-ghost-sm" onClick={() => setDetail(p)}>Details</button>
                  {p.status === "paid_deposit" && <button className="btn-ghost-sm" onClick={() => verifyPrebooking(p.id)}>Verify</button>}
                  <button className="btn-ghost-sm" onClick={() => cancel(p.id)}>Cancel</button>
                </td>
              </tr>
            ))}
            {prebookings.length === 0 && <tr><td colSpan="8" className="muted mono" style={{ textAlign: "center", padding: 24 }}>No pre-bookings yet.</td></tr>}
          </tbody>
        </table>
      </div>

      {detail && (
        <PrebookDetailSheet
          pb={detail}
          onClose={() => setDetail(null)}
          onSendToKitchen={() => sendToKitchen(detail)}
        />
      )}
      {notifyOpen && <NotificationSettingsSheet onClose={() => setNotifyOpen(false)} />}
    </div>
  );
}

function PrebookDetailSheet({ pb, onClose, onSendToKitchen }) {
  const [settings] = usePrinterSettings();
  const items = pb.items || [];
  const qty = items.reduce((a, i) => a + i.qty, 0);
  const waOpen = () => {
    const phone = (pb.customerPhone || "").replace(/\D/g, "");
    if (!phone) return alert("No phone number on file");
    const msg = encodeURIComponent(
      `Halo ${pb.customerName}, terima kasih sudah pre-book di Kedai Oma Nana untuk ${pb.visitDate}${pb.visitTime ? " jam " + pb.visitTime : ""}. Total Rp ${(pb.subtotal || 0).toLocaleString("id-ID")}, deposit Rp ${(pb.depositPaid || 0).toLocaleString("id-ID")}.`
    );
    const num = phone.startsWith("0") ? "62" + phone.slice(1) : phone;
    window.open(`https://wa.me/${num}?text=${msg}`, "_blank");
  };
  const print = () => {
    const root = document.createElement("div");
    root.className = "printable";
    root.innerHTML = `
      <div class="pr-brand pr-center">Kedai Oma Nana</div>
      <div class="pr-sub pr-center"><em>* kon.cafe — Surabaya *</em></div>
      <div class="pr-sub pr-center">PRE-BOOKING · ${pb.visitDate}${pb.visitTime ? " · " + pb.visitTime : ""}</div>
      <div class="pr-rule"></div>
      <div class="pr-row"><span>Customer</span><span>${pb.customerName}</span></div>
      <div class="pr-row"><span>WhatsApp</span><span>${pb.customerPhone || "—"}</span></div>
      ${pb.partySize ? `<div class="pr-row"><span>People</span><span>${pb.partySize}</span></div>` : ""}
      <div class="pr-rule"></div>
      <table class="pr-items"><tbody>
        ${items.map((it) => `
          <tr><td>${it.qty}× ${it.name}${it.sku ? " (" + it.sku + ")" : ""}</td><td class="r">Rp ${(((it.price || 0) + (it.modPrice || 0)) * it.qty).toLocaleString("id-ID")}</td></tr>
          ${it.mods && it.mods.length ? `<tr><td class="pr-mod" colSpan="2">${it.mods.join(" · ")}</td></tr>` : ""}
          ${it.notes ? `<tr><td class="pr-note" colSpan="2">* ${it.notes}</td></tr>` : ""}
        `).join("")}
      </tbody></table>
      <div class="pr-rule"></div>
      <div class="pr-row"><span>Subtotal</span><span>Rp ${(pb.subtotal || 0).toLocaleString("id-ID")}</span></div>
      <div class="pr-row"><span>Deposit paid</span><span>Rp ${(pb.depositPaid || 0).toLocaleString("id-ID")}</span></div>
      <div class="pr-row pr-total"><span>BALANCE DUE</span><span>Rp ${Math.max(0, (pb.subtotal || 0) - (pb.depositPaid || 0)).toLocaleString("id-ID")}</span></div>
      <div class="pr-rule"></div>
      <div class="pr-center" style="font-size:10px">Printed ${new Date().toLocaleString("en-GB", { timeZone: "Asia/Jakarta" })} WIB</div>
    `;
    document.body.appendChild(root);
    printPaper(settings.paperWidth);
    setTimeout(() => root.remove(), 800);
  };

  return (
    <div className="sheet-wrap" onMouseDown={onClose}>
      <div className="sheet sheet-wide" onMouseDown={(e) => e.stopPropagation()}>
        <header className="sheet-head">
          <div>
            <div className="eyebrow mono">PRE-BOOKING</div>
            <h3>{pb.customerName}</h3>
          </div>
          <button className="icon-x" onClick={onClose}>×</button>
        </header>
        <div className="sheet-body">
          <div className="pb-detail-grid">
            <div><span className="muted mono">VISIT DATE</span><div><Mono>{pb.visitDate}{pb.visitTime ? " · " + pb.visitTime : ""}</Mono></div></div>
            <div><span className="muted mono">PEOPLE</span><div><Mono>{pb.partySize || "—"}</Mono></div></div>
            <div><span className="muted mono">WHATSAPP</span><div><Mono>{pb.customerPhone || "—"}</Mono></div></div>
            <div><span className="muted mono">TABLE</span><div><Mono>{pb.table || "—"}</Mono></div></div>
            <div><span className="muted mono">STATUS</span><div><StatusPill status={pb.status}>{pb.status}</StatusPill></div></div>
            <div><span className="muted mono">CREATED</span><div><Mono>{pb.createdAt?.toDate ? pb.createdAt.toDate().toLocaleString("en-GB", { timeZone: "Asia/Jakarta" }) + " WIB" : "—"}</Mono></div></div>
          </div>

          <div className="panel-card no-pad" style={{ marginTop: 18 }}>
            <table className="data-table">
              <thead><tr><th>Qty</th><th>Item</th><th>Modifiers</th><th>Notes</th><th style={{ textAlign: "right" }}>Line total</th></tr></thead>
              <tbody>
                {items.map((it, i) => (
                  <tr key={i}>
                    <td><Mono>{it.qty}×</Mono></td>
                    <td>{it.name}{it.sku ? <span className="muted mono"> ({it.sku})</span> : null}</td>
                    <td className="mono muted">{(it.mods || []).join(" · ") || "—"}</td>
                    <td className="muted">{it.notes || "—"}</td>
                    <td style={{ textAlign: "right" }}><Mono>{money(((it.price || 0) + (it.modPrice || 0)) * it.qty)}</Mono></td>
                  </tr>
                ))}
              </tbody>
            </table>
          </div>

          <div className="panel-card" style={{ marginTop: 14 }}>
            <div className="reco">
              <div className="reco-row"><span>Items</span><Mono>{qty}</Mono></div>
              <div className="reco-row"><span>Subtotal</span><Mono>{money(pb.subtotal || 0)}</Mono></div>
              <div className="reco-row"><span>Deposit required</span><Mono>{money(pb.depositRequired || 0)}</Mono></div>
              <div className="reco-row"><span>Deposit paid</span><Mono>{money(pb.depositPaid || 0)}</Mono></div>
              <div className="reco-row reco-total"><span>Balance due on arrival</span><Mono>{money(Math.max(0, (pb.subtotal || 0) - (pb.depositPaid || 0)))}</Mono></div>
            </div>
          </div>
        </div>
        <footer className="sheet-foot">
          <button className="btn-ghost" onClick={onClose}>Close</button>
          <button className="btn-ghost" onClick={waOpen}>WhatsApp customer</button>
          <button className="btn-ghost" onClick={print}>Print</button>
          <button className="btn-primary" onClick={onSendToKitchen}>Send to kitchen now</button>
        </footer>
      </div>
    </div>
  );
}

function NotificationSettingsSheet({ onClose }) {
  return (
    <div className="sheet-wrap" onMouseDown={onClose}>
      <div className="sheet" onMouseDown={(e) => e.stopPropagation()}>
        <header className="sheet-head">
          <div><div className="eyebrow mono">SETTINGS</div><h3>Pre-booking email notifications</h3></div>
          <button className="icon-x" onClick={onClose}>×</button>
        </header>
        <div className="sheet-body">
          <p className="muted">
            New pre-bookings are POSTed to <code>/api/notify-prebook</code>, which
            sends an email via Mailgun. Configure these environment variables in
            Firebase App Hosting → Backend → Settings → Environment and redeploy:
          </p>
          <pre className="mono" style={{ background: "var(--paper-soft)", padding: 12, borderRadius: 6, fontSize: 12, marginTop: 12, overflow: "auto" }}>
{`MAILGUN_API_KEY      = your-mailgun-private-key
MAILGUN_DOMAIN       = mg.kon.cafe        (or your sandbox domain)
MAILGUN_REGION       = us                 (or 'eu' if your account is EU)
NOTIFY_FROM_EMAIL    = postmaster@mg.kon.cafe
NOTIFY_FROM_NAME     = Kedai Oma Nana
NOTIFY_TO_EMAILS     = owner@kon.cafe, manager@kon.cafe`}
          </pre>
          <p className="muted mono" style={{ fontSize: 12, marginTop: 10 }}>
            Mailgun free tier sends ~100 emails/day for the first 3 months. If
            <code> MAILGUN_API_KEY</code> is unset, prebookings still succeed —
            only the notification email is skipped. On Mailgun's sandbox domain
            you must add each recipient as an "authorized recipient" first.
          </p>
        </div>
        <footer className="sheet-foot">
          <button className="btn-primary" onClick={onClose}>OK</button>
        </footer>
      </div>
    </div>
  );
}

function AdminUsers() {
  const { db } = usePOS();
  const [users, setUsers] = React.useState([]);
  const [email, setEmail] = React.useState("");
  const [pw, setPw] = React.useState("");
  const [role, setRole] = React.useState("cashier");
  const [msg, setMsg] = React.useState("");

  React.useEffect(() => db.collection("users").onSnapshot((s) =>
    setUsers(s.docs.map((d) => ({ id: d.id, ...d.data() })))), []);

  const create = async (e) => {
    e.preventDefault(); setMsg("");
    try {
      const secondary = firebase.initializeApp(window.FIREBASE_CONFIG, "secondary-" + Date.now());
      const cred = await secondary.auth().createUserWithEmailAndPassword(email, pw);
      await db.collection("users").doc(cred.user.uid).set({ email, role });
      await secondary.auth().signOut(); await secondary.delete();
      setEmail(""); setPw(""); setRole("cashier");
      setMsg("Created " + email);
    } catch (ex) { setMsg(ex.message); }
  };

  const setUserRole = (uid, r) => db.collection("users").doc(uid).set({ role: r }, { merge: true });
  const remove = (uid) => { if (confirm("Remove role doc? (Auth user remains — delete in Firebase console)")) db.collection("users").doc(uid).delete(); };

  return (
    <div className="admin-pane">
      <header className="pane-head">
        <div>
          <div className="eyebrow mono">USERS · ROLES</div>
          <h2>{users.length} staff</h2>
        </div>
      </header>
      <div className="panel-card">
        <h3>Create employee</h3>
        <form className="row" style={{ gap: 8, flexWrap: "wrap", alignItems: "flex-end" }} onSubmit={create}>
          <label className="field" style={{ flex: "1 1 220px" }}><span className="field-label mono">Email</span>
            <input type="email" required value={email} onChange={(e) => setEmail(e.target.value)} />
          </label>
          <label className="field" style={{ flex: "1 1 160px" }}><span className="field-label mono">Initial password</span>
            <input type="password" required value={pw} onChange={(e) => setPw(e.target.value)} />
          </label>
          <label className="field" style={{ flex: "0 0 160px" }}><span className="field-label mono">Role</span>
            <select value={role} onChange={(e) => setRole(e.target.value)}>
              {["cashier", "kitchen", "waitress", "display", "admin"].map((r) => <option key={r}>{r}</option>)}
            </select>
          </label>
          <button className="btn-primary" type="submit">Create</button>
        </form>
        {msg && <div className="muted mono" style={{ marginTop: 8 }}>{msg}</div>}
      </div>
      <div className="panel-card no-pad" style={{ marginTop: 16 }}>
        <table className="data-table">
          <thead><tr><th>Email</th><th>Role</th><th></th></tr></thead>
          <tbody>
            {users.map((u) => (
              <tr key={u.id}>
                <td>{u.email || u.id}</td>
                <td>
                  <select value={u.role || ""} onChange={(e) => setUserRole(u.id, e.target.value)}>
                    {["cashier", "kitchen", "waitress", "display", "admin"].map((r) => <option key={r}>{r}</option>)}
                  </select>
                </td>
                <td className="row-actions"><button className="btn-ghost-sm" onClick={() => remove(u.id)}>Remove</button></td>
              </tr>
            ))}
          </tbody>
        </table>
      </div>
    </div>
  );
}

function AdminPrinter() {
  const [s, update] = usePrinterSettings();

  const sampleOrder = {
    id: "test", shortId: "TEST", table: "5", customer: "Test Receipt",
    paymentMethod: "qris", total: 134000, subtotal: 134000, depositApplied: 0, tip: 0,
    items: [
      { qty: 1, name: "Latte",            sku: "P005", price: 34000, modPrice: 13000, mods: ["Large", "Oat"], notes: "" },
      { qty: 2, name: "Butter Croissant", sku: "P017", price: 28000, modPrice: 0,     mods: ["Warmed"],        notes: "" },
    ],
  };
  const testReceipt = () => {
    const root = document.createElement("div");
    root.className = "printable";
    root.innerHTML = `
      <div class="pr-brand pr-center">Kedai Oma Nana</div>
      <div class="pr-sub pr-center"><em>* kon.cafe — Surabaya *</em></div>
      <div class="pr-sub pr-center">Test print · ${new Date().toLocaleString("en-GB", { timeZone: "Asia/Jakarta" })} WIB</div>
      <div class="pr-rule"></div>
      <div class="pr-row"><span>Order TEST</span><span>Table 5</span></div>
      <div class="pr-rule"></div>
      <table class="pr-items"><tbody>
        ${sampleOrder.items.map((it) => `
          <tr><td>${it.qty}× ${it.name}</td><td class="r">${money((it.price + it.modPrice) * it.qty)}</td></tr>
          ${it.mods.length ? `<tr><td class="pr-mod" colSpan="2">${it.mods.join(" · ")}</td></tr>` : ""}
        `).join("")}
      </tbody></table>
      <div class="pr-rule"></div>
      <div class="pr-row pr-total"><span>TOTAL</span><span>${money(sampleOrder.total)}</span></div>
    `;
    document.body.appendChild(root);
    printPaper(s.paperWidth);
    setTimeout(() => root.remove(), 800);
  };

  return (
    <div className="admin-pane">
      <header className="pane-head">
        <div>
          <div className="eyebrow mono">PRINTER</div>
          <h2>Local thermal printer</h2>
        </div>
        <button className="btn-ghost" onClick={testReceipt}>Print test receipt</button>
      </header>

      <div className="panel-card">
        <h3>Settings</h3>
        <p className="muted mono" style={{ fontSize: 12 }}>
          The browser's print dialog is used — the receipt will go to whichever printer you choose there.
          Install your thermal printer with the manufacturer's driver (Windows / macOS / Linux / Android),
          set the paper width below, then print once and tick "remember settings" in the print dialog.
        </p>

        <label className="field" style={{ maxWidth: 220, marginTop: 14 }}>
          <span className="field-label mono">Paper width</span>
          <select value={s.paperWidth} onChange={(e) => update({ paperWidth: e.target.value })}>
            <option value="80">80 mm</option>
            <option value="58">58 mm</option>
          </select>
        </label>

        <label className="row" style={{ gap: 8, marginTop: 14 }}>
          <input type="checkbox" checked={!!s.autoPrintReceipt}
            onChange={(e) => update({ autoPrintReceipt: e.target.checked })} />
          <span className="mono">Auto-print receipt after checkout</span>
        </label>

        <label className="row" style={{ gap: 8, marginTop: 8 }}>
          <input type="checkbox" checked={!!s.autoPrintKitchen}
            onChange={(e) => update({ autoPrintKitchen: e.target.checked })} />
          <span className="mono">Show "Print" button on kitchen tickets</span>
        </label>

        <div className="muted mono" style={{ fontSize: 12, marginTop: 16 }}>
          Settings are stored per device — each terminal (cashier station, kitchen
          screen) can have its own paper width and auto-print preference.
        </div>
      </div>
    </div>
  );
}

Object.assign(window, { AdminScreen });
