/* NutriDMS — Restaurant Menu Builder screen (dashboard + multi-step builder). */
(function () {
  const R = React, { useState: uS, useMemo: uM } = React;
  const RM = () => window.RestaurantMenus;
  const I = (n, s, st) => <Icon name={n} size={s || 15} stroke={st || 2} />;

  /* ── Dashboard ── */
  function RmDashboard() {
    const { toast } = useApp();
    const [, bump] = uS(0);
    R.useEffect(() => { const h = () => bump((n) => n + 1); window.addEventListener("nutridms-rmenus", h); return () => window.removeEventListener("nutridms-rmenus", h); }, []);
    const menus0 = RM().load();
    const [builder, setBuilder] = uS(null); // dashboard first; open builder on demand
    const [preview, setPreview] = uS(null); // menu being previewed
    const [history, setHistory] = uS(null); // menu whose version history is open
    const [qr, setQr] = uS(null); // menu whose QR/analytics is open
    const menus = RM().load();

    if (builder) return <RmBuilder menu={builder === "new" ? null : builder} allMenus={menus} onPick={(m) => setBuilder(m)} onClose={() => setBuilder(null)} toast={toast} />;

    const typeColor = { breakfast: "#F59E0B", brunch: "#F97316", lunch: "#16A34A", dinner: "#7C3AED", "all-day": "#0EA5B7", kids: "#EC4899", drinks: "#0891B2", dessert: "#DB2777", seasonal: "#CA8A04", catering: "#2563EB", custom: "#64748B" };
    const kpi = [
      { label: "Total menus", value: menus.length, icon: "book-open", c: "#2563EB" },
      { label: "Published", value: menus.filter((m) => m.status === "published").length, icon: "globe", c: "#16A34A" },
      { label: "Draft", value: menus.filter((m) => m.status === "draft").length, icon: "file-pen", c: "#F59E0B" },
      { label: "Total items", value: menus.reduce((s, m) => s + (m.items || []).length, 0), icon: "utensils-crossed", c: "#7C3AED" },
    ];

    return (
      <div className="page rm-page">
        <div className="page-head">
          <div><h1 className="page-title">Restaurant Menus</h1><p className="page-sub">Build customer-facing menus from approved offerings. Nutrition, allergens & pricing stay linked to source.</p></div>
          <button className="btn primary rm-buildnew" onClick={() => setBuilder("new")}>{I("plus", 16)} Build new menu</button>
        </div>
        <div className="rm-kpis">
          {kpi.map((k) => <div key={k.label} className="rm-kpi2" style={{ "--kc": k.c }}><span className="rm-kpi2-ic">{I(k.icon, 18)}</span><div><b>{k.value}</b><span>{k.label}</span></div></div>)}
        </div>
        {menus.length === 0 ? (
          <div className="rm-empty">{I("book-open", 30, 1.6)}<h3>No menus yet</h3><p>Create your first restaurant menu from approved offerings.</p><button className="btn primary" onClick={() => setBuilder("new")}>{I("plus", 15)} Build new menu</button></div>
        ) : (
          <div className="rm-menu-grid">
            {menus.map((m) => { const tc = typeColor[m.menuType] || "#64748B"; const imgs = (m.items || []).map((it) => RM().snapshot(it.offeringId).image).filter(Boolean).slice(0, 3);
              const up = m.status === "published" && RM().checkUpdates(m).updated;
              return (
              <div key={m.id} className="rm-mcard" onClick={() => setBuilder(m)}>
                <div className="rm-mcard-cover" style={{ background: "linear-gradient(135deg, " + tc + "26, " + tc + "0D)" }}>
                  <span className="rm-mcard-type" style={{ background: tc }}>{(RM().MENU_TYPES.find((t) => t.id === m.menuType) || {}).label || m.menuType}</span>
                  <span className={"rm-mcard-status " + m.status}>{m.status === "published" ? "Published" : "Draft"}</span>
                  <div className="rm-mcard-imgs">{imgs.length ? imgs.map((im, i) => <span key={i} style={{ backgroundImage: 'url("' + im + '")' }} />) : <span className="rm-mcard-noimg" style={{ color: tc }}>{I("utensils-crossed", 26)}</span>}</div>
                </div>
                <div className="rm-mcard-body">
                  <b>{m.name}</b>
                  <span className="rm-mcard-sub">{(m.items || []).length} items · {(m.categories || []).length} categories</span>
                  {up && <span className="rm-mcard-upd">{I("alert-triangle", 11)} Update available</span>}
                  <div className="rm-mcard-foot">
                    <span className="rm-mcard-cur">{m.currency}</span>
                    <div className="rm-mcard-acts" onClick={(e) => e.stopPropagation()}>
                      <button className="rm-iconbtn" title="Preview" onClick={() => setPreview(m)}>{I("smartphone", 15)}</button>
                      {m.status === "published" && <button className="rm-iconbtn" title="QR" onClick={() => setQr(m)}>{I("qr-code", 15)}</button>}
                      <button className="rm-iconbtn" title="Edit" onClick={() => setBuilder(m)}>{I("pencil", 15)}</button>
                      <button className="rm-iconbtn" title="Duplicate" onClick={() => { RM().duplicate(m.id); toast("Duplicated"); }}>{I("copy", 15)}</button>
                      <button className="rm-iconbtn danger" title="Delete" onClick={() => { if (confirm("Delete “" + m.name + "”?")) { RM().delete(m.id); toast("Deleted"); } }}>{I("trash-2", 15)}</button>
                    </div>
                  </div>
                </div>
              </div>
            ); })}
          </div>
        )}
        <div className="rm-table-card" style={{ display: "none" }}>
          {menus.length === 0 ? (
            <div className="rm-empty">{I("book-open", 30, 1.6)}<h3>No menus yet</h3><p>Create your first restaurant menu from approved offerings.</p><button className="btn primary" onClick={() => setBuilder("new")}>{I("plus", 15)} Create Restaurant Menu</button></div>
          ) : (
            <table className="rm-table">
              <thead><tr><th>Menu</th><th>Type</th><th>Items</th><th>Status</th><th>Updated</th><th></th></tr></thead>
              <tbody>
                {menus.map((m) => (
                  <tr key={m.id}>
                    <td><b>{m.name}</b><span className="rm-td-sub">{m.publicTitle}</span></td>
                    <td><span className="rm-type-pill">{(RM().MENU_TYPES.find((t) => t.id === m.menuType) || {}).label || m.menuType}</span></td>
                    <td>{(m.items || []).length}</td>
                    <td><span className={"rm-status " + m.status}>{m.status === "published" ? "Published" : m.status === "draft" ? "Draft" : m.status}</span>
                      {m.status === "published" && RM().checkUpdates(m).updated && <span className="rm-update-badge" title="A linked recipe or offering changed since publish">{I("alert-triangle", 11)} Update available</span>}
                    </td>
                    <td className="rm-td-muted">{m.updatedAt ? new Date(m.updatedAt).toLocaleDateString() : "—"}</td>
                    <td className="rm-row-actions">
                      <button className="rm-iconbtn" title="Preview mobile" onClick={() => setPreview(m)}>{I("smartphone", 15)}</button>
                      {m.status === "published" && <button className="rm-iconbtn" title="QR & analytics" onClick={() => setQr(m)}>{I("qr-code", 15)}</button>}
                      {m.status === "published" && RM().checkUpdates(m).updated && <button className="rm-iconbtn warn" title="Republish with latest source data" onClick={() => { const res = RM().publish(m); if (res.ok) toast("Republished with latest data"); }}>{I("refresh-cw", 15)}</button>}
                      {(m.versions || []).length > 0 && <button className="rm-iconbtn" title="Version history" onClick={() => setHistory(m)}>{I("history", 15)}</button>}
                      <button className="rm-iconbtn" title="Edit" onClick={() => setBuilder(m)}>{I("pencil", 15)}</button>
                      <button className="rm-iconbtn" title="Duplicate" onClick={() => { RM().duplicate(m.id); toast("Menu duplicated"); }}>{I("copy", 15)}</button>
                      <button className="rm-iconbtn danger" title="Delete" onClick={() => { if (confirm("Delete “" + m.name + "”?")) { RM().delete(m.id); toast("Menu deleted"); } }}>{I("trash-2", 15)}</button>
                    </td>
                  </tr>
                ))}
              </tbody>
            </table>
          )}
        </div>
        {preview && <RmMobilePreview menu={preview} onClose={() => setPreview(null)} />}
        {qr && <RmQrPanel menu={qr} onClose={() => setQr(null)} />}
        {history && (
          <React.Fragment>
            <div className="rm-drawer-scrim" onMouseDown={(e) => { if (e.target === e.currentTarget) setHistory(null); }} />
            <div className="rm-drawer">
              <div className="rm-drawer-h"><div><b>Version history</b><span>{history.name}</span></div><button className="rm-iconbtn" onClick={() => setHistory(null)}>{I("x", 18)}</button></div>
              <div className="rm-drawer-list">
                {RM().checkUpdates(history).updated && (
                  <div className="rm-ver-alert">{I("alert-triangle", 15)}<div><b>Update available</b><span>{RM().checkUpdates(history).changes.map((c) => c.name).join(", ")} changed at source.</span></div>
                    <button className="btn primary sm" onClick={() => { RM().publish(history); toast("Republished"); setHistory(null); }}>Republish</button></div>
                )}
                {(history.versions || []).slice().reverse().map((v) => (
                  <div key={v.v} className="rm-ver-row">
                    <div className="rm-ver-info"><b>Version {v.v}</b><span>{new Date(v.at).toLocaleString()} · {v.items} items · {v.by}</span></div>
                    {v.v !== history.publishedVersion && <button className="btn secondary sm" onClick={() => { if (confirm("Roll back to version " + v.v + "?")) { RM().rollback(history, v.v); toast("Rolled back to v" + v.v); setHistory(null); } }}>{I("rotate-ccw", 13)} Roll back</button>}
                    {v.v === history.publishedVersion && <span className="rm-ver-current">Current</span>}
                  </div>
                ))}
              </div>
            </div>
          </React.Fragment>
        )}
      </div>
    );
  }

  /* ── Three-panel workspace builder ── */
  function RmBuilder({ menu, onClose, toast, allMenus, onPick }) {
    const [libOpen, setLibOpen] = uS(false);
    const [preview, setPreview] = uS(false);
    const [histOpen, setHistOpen] = uS(false);
    const [view, setView] = uS("cards"); // cards | table
    const [q, setQ] = uS("");
    const [activeCat, setActiveCat] = uS("all");
    const [selId, setSelId] = uS(null); // inspector item id
    const [insTab, setInsTab] = uS("overview");
    const [sel, setSel] = uS(() => new Set()); // bulk select
    const [dragItem, setDragItem] = uS(null);
    const [dragCat, setDragCat] = uS(null);
    const [menuPick, setMenuPick] = uS(false);
    const [mgLib, setMgLib] = uS(false);
    const [d, setD] = uS(() => menu ? JSON.parse(JSON.stringify(menu)) : {
      id: RM().newId(), name: "New menu", publicTitle: "", menuType: "dinner", description: "",
      status: "draft", currency: "CAD", locations: [], schedules: [{ days: [0,1,2,3,4,5,6], start: "16:00", end: "22:00" }], categories: [], items: [], publishedVersion: 0,
    });
    const set = (k, v) => setD((x) => Object.assign({}, x, { [k]: v }));
    const persist = (silent) => { RM().save(d); if (!silent) toast("Menu saved"); };
    const val = uM(() => RM().validate(d), [d]);
    const cats = (d.categories || []).slice().sort((a, b) => (a.order || 0) - (b.order || 0));
    const selItem = (d.items || []).find((it) => it.id === selId) || null;

    const addOffering = (o) => {
      if ((d.items || []).some((it) => it.offeringId === o.id)) return;
      const snap = RM().snapshot(o.id);
      const id = "it-" + Math.random().toString(36).slice(2, 8);
      setD((x) => Object.assign({}, x, { items: (x.items || []).concat([{
        id, offeringId: o.id, name: snap.name, category: activeCat !== "all" ? activeCat : (x.categories[0] || {}).id || "",
        price: null, priceLabel: "", portion: snap.serving || "", showPrice: true, featured: false, soldOut: false, orderingEnabled: false, order: (x.items || []).length,
      }]) }));
      setSelId(id);
    };
    const rmItem = (id) => setD((x) => Object.assign({}, x, { items: x.items.filter((it) => it.id !== id) }));
    const setItem = (id, patch) => setD((x) => Object.assign({}, x, { items: x.items.map((it) => it.id === id ? Object.assign({}, it, patch) : it) }));
    const addCategory = (name) => { const id = "c-" + Math.random().toString(36).slice(2, 7); setD((x) => Object.assign({}, x, { categories: x.categories.concat([{ id, name, order: x.categories.length }]) })); };
    const renameCat = (id, name) => setD((x) => Object.assign({}, x, { categories: x.categories.map((c) => c.id === id ? Object.assign({}, c, { name }) : c) }));
    const rmCat = (id) => setD((x) => Object.assign({}, x, { categories: x.categories.filter((c) => c.id !== id), items: x.items.map((it) => it.category === id ? Object.assign({}, it, { category: "" }) : it) }));
    // drag reorder categories
    const dropCat = (targetId) => { if (!dragCat || dragCat === targetId) return; setD((x) => { const cs = x.categories.slice().sort((a,b)=>(a.order||0)-(b.order||0)); const from = cs.findIndex(c=>c.id===dragCat); const to = cs.findIndex(c=>c.id===targetId); const [m] = cs.splice(from,1); cs.splice(to,0,m); cs.forEach((c,i)=>c.order=i); return Object.assign({}, x, { categories: cs }); }); setDragCat(null); };
    // drag reorder items
    const dropItem = (targetId) => { if (!dragItem || dragItem === targetId) return; setD((x) => { const its = x.items.slice(); const from = its.findIndex(i=>i.id===dragItem); const to = its.findIndex(i=>i.id===targetId); const [m] = its.splice(from,1); its.splice(to,0,m); its.forEach((i,k)=>i.order=k); return Object.assign({}, x, { items: its }); }); setDragItem(null); };
    const toggleSel = (id) => setSel((s) => { const n = new Set(s); n.has(id) ? n.delete(id) : n.add(id); return n; });
    const bulkAvail = (soldOut) => { setD((x) => Object.assign({}, x, { items: x.items.map((it) => sel.has(it.id) ? Object.assign({}, it, { soldOut }) : it) })); toast(sel.size + " item(s) updated"); setSel(new Set()); };

    const shown = (d.items || []).filter((it) => (activeCat === "all" || it.category === activeCat) && (!q || it.name.toLowerCase().includes(q.toLowerCase())));

    return (
      <div className="page rm-ws-page">
        {/* Sticky header */}
        <div className="rm-ws-header">
          <button className="rm-back" onClick={onClose}>{I("arrow-left", 18)}</button>
          <div className="rm-ws-title">
            <input className="rm-ws-name" value={d.name} onChange={(e) => set("name", e.target.value)} placeholder="Menu name" />
            <div className="rm-ws-meta"><Icon name="building-2" size={12} /> Acme Foods · {d.locations && d.locations.length ? d.locations.length + " locations" : "All locations"} <span className={"rm-status " + d.status}>{d.status === "published" ? "Published" : "Draft"}</span></div>
          </div>
          <span className="grow" />
          <select className="rm-ws-type" value={d.menuType} onChange={(e) => set("menuType", e.target.value)}>{RM().MENU_TYPES.map((t) => <option key={t.id} value={t.id}>{t.label}</option>)}</select>
          {(d.versions || []).length > 0 && <button className="btn ghost sm" onClick={() => setHistOpen(true)}>{I("history", 14)} Versions</button>}
          <button className="btn ghost sm" onClick={() => setPreview(true)}>{I("smartphone", 14)} Preview</button>
          <button className="btn secondary sm" onClick={() => persist()}>{I("save", 14)} Save draft</button>
          <button className="btn ghost sm" title="Brand this menu & expose it via QR in the Customer Portal" onClick={() => { persist(true); try { window.__cpHubTab = "preview"; window.__setPage && window.__setPage("customer-portal"); } catch (e) {} }}>{I("qr-code", 14)} Publish to QR</button>
          <button className="btn primary sm" disabled={!val.ready} title={val.ready ? "" : (val.errors[0] || "")} onClick={() => { const res = RM().publish(d); if (res.ok) { toast("Menu published"); onClose(); } else toast(res.errors[0]); }}>{I("globe", 14)} Publish</button>
        </div>

        {!val.ready && val.errors.length > 0 && <div className="rm-ws-warnbar">{I("alert-triangle", 14)} {val.errors.length} issue(s) to resolve before publishing: {val.errors.slice(0, 2).join(" · ")}</div>}

        <div className="rm-ws-grid">
          {/* LEFT: categories */}
          <aside className="rm-ws-left">
            <div className="rm-left-top">
              <div className="rm-menu-picker">
                <span className="rm-menu-sel" onClick={() => setMenuPick((v) => !v)}>{d.name} {I("chevron-down", 14)}</span>
                {menuPick && (
                  <div className="rm-menu-dd">
                    {(allMenus || []).map((mm) => <button key={mm.id} className={"rm-menu-ddrow" + (mm.id === d.id ? " on" : "")} onClick={() => { setMenuPick(false); onPick && onPick(mm); }}>{mm.name}<em>{(mm.items || []).length}</em></button>)}
                    <button className="rm-menu-ddnew" onClick={() => { setMenuPick(false); onPick && onPick("new"); }}>{I("plus", 13)} New menu</button>
                  </div>
                )}
              </div>
              <button className="rm-iconbtn" title="Menu options">{I("more-horizontal", 16)}</button>
            </div>
            <div className="rm-left-edited">Last edited: {d.updatedAt ? new Date(d.updatedAt).toLocaleString([], { hour: "numeric", minute: "2-digit" }) : "just now"}</div>
            <div className="rm-cat-head"><span>Categories</span><button className="rm-addcat" onClick={() => addCategory("New category")}>{I("plus", 13)} Add category</button></div>
            <button className={"rm-catrow2" + (activeCat === "all" ? " on" : "")} onClick={() => setActiveCat("all")}>
              <span className="rm-cat-ic">{I("list", 15)}</span><span className="rm-cat-nm">All items</span><em className="rm-cat-cnt">{(d.items || []).length}</em>
            </button>
            {cats.map((c) => (
              <div key={c.id} className={"rm-catrow2 drag" + (activeCat === c.id ? " on" : "") + (dragCat === c.id ? " dragging" : "")} draggable onDragStart={() => setDragCat(c.id)} onDragOver={(e) => e.preventDefault()} onDrop={() => dropCat(c.id)} onClick={() => setActiveCat(c.id)}>
                <span className="rm-cat-grip">{I("grip-vertical", 13)}</span>
                {I("chevron-right", 13)}
                <span className="rm-cat-ic">{I("utensils-crossed", 14)}</span>
                <input className="rm-cat-nm2" value={c.name} onClick={(e) => e.stopPropagation()} onChange={(e) => renameCat(c.id, e.target.value)} />
                <em className="rm-cat-cnt">{(d.items || []).filter((it) => it.category === c.id).length}</em>
                <button className="rm-iconbtn xs" title="Remove category" onClick={(e) => { e.stopPropagation(); rmCat(c.id); }}>{I("more-horizontal", 14)}</button>
              </div>
            ))}
            <div className="rm-left-foot"><span>Total items</span><b>{(d.items || []).length}</b></div>
          </aside>

          {/* CENTER: items */}
          <section className="rm-ws-center">
            <div className="rm-center-head"><b>{activeCat === "all" ? "All items" : (cats.find((c) => c.id === activeCat) || {}).name}</b><span className="rm-center-count">{shown.length} items</span></div>
            <div className="rm-ws-toolbar">
              <div className="rm-ws-search">{I("search", 15)}<input value={q} onChange={(e) => setQ(e.target.value)} placeholder="Search items…" /></div>
              <button className="rm-tbtn">{I("filter", 14)} Filter</button>
              <button className="rm-tbtn">{I("arrow-up-down", 14)}</button>
            </div>
            {sel.size > 0 && <div className="rm-bulkbar"><b>{sel.size} selected</b><button className="btn ghost sm" onClick={() => bulkAvail(false)}>Mark available</button><button className="btn ghost sm" onClick={() => bulkAvail(true)}>Mark sold out</button><button className="rm-iconbtn" onClick={() => setSel(new Set())}>{I("x", 15)}</button></div>}

            {shown.length === 0 ? (
              <div className="rm-empty sm">{I("utensils-crossed", 26, 1.6)}<p>{(d.items || []).length === 0 ? "No items yet. Add approved offerings — nutrition & allergens link automatically." : "No items in this category."}</p></div>
            ) : (
              <div className="rm-items-list">
                {shown.map((it) => { const s = RM().snapshot(it.offeringId); return (
                  <div key={it.id} className={"rm-item2" + (selId === it.id ? " active" : "") + (dragItem === it.id ? " dragging" : "")} draggable onDragStart={() => setDragItem(it.id)} onDragOver={(e) => e.preventDefault()} onDrop={() => dropItem(it.id)} onClick={() => setSelId(it.id)}>
                    <span className="rm-item2-grip" onClick={(e) => e.stopPropagation()}>{I("grip-vertical", 15)}</span>
                    <span className="rm-item2-thumb">{s.image ? <img src={s.image} alt="" /> : I("utensils-crossed", 22)}</span>
                    <div className="rm-item2-body">
                      <b>{it.name}</b>
                      <span className="rm-item2-sku">SKU: {s.sku}{s.recipeCode ? "  ·  Recipe: " + s.recipeCode : ""}</span>
                      <span className="rm-item2-price">{it.price != null ? RM().money(it.price, d.currency) : (it.priceLabel || "—")}</span>
                      <span className="rm-wscard-tags">
                        {it.soldOut ? <span className="rm-badge2 sold">Sold out</span> : <span className="rm-badge2 ok">Available</span>}
                        {s.compliant ? <span className="rm-badge2 comp">Compliant</span> : <span className="rm-badge2 warn">Review</span>}
                        {s.calories != null ? <span className="rm-badge2 nutr">Nutrition OK</span> : null}
                        {it.featured ? <span className="rm-badge2 feat">Featured</span> : null}
                        {(s.dietary || []).slice(0, 1).map((x) => <span key={x} className="rm-badge2 diet">{x}</span>)}
                      </span>
                    </div>
                    <button className="rm-iconbtn" onClick={(e) => { e.stopPropagation(); rmItem(it.id); if (selId === it.id) setSelId(null); }} title="Remove">{I("more-horizontal", 16)}</button>
                  </div>
                ); })}
              </div>
            )}
            <button className="rm-additem" onClick={() => setLibOpen(true)}>{I("plus", 16)} Add item</button>
          </section>

          {/* RIGHT: inspector */}
          <aside className="rm-ws-right">
            {!selItem ? (
              <div className="rm-insp-empty">{I("mouse-pointer-click", 26, 1.6)}<p>Select a menu item to edit its price, portion, availability and see its linked nutrition & allergens.</p></div>
            ) : (() => { const s = RM().snapshot(selItem.offeringId); const cn = (cats.find((c) => c.id === selItem.category) || {}).name || "Uncategorized";
              const PERIODS = [["breakfast", "Breakfast"], ["lunch", "Lunch"], ["dinner", "Dinner"], ["late", "Late Night"]];
              const CHANS = [["dinein", "Dine In"], ["takeout", "Takeout"], ["delivery", "Delivery"], ["online", "Online Ordering"]];
              const periods = selItem.periods || { lunch: true, dinner: true };
              const chans = selItem.channels || { dinein: true, takeout: true, delivery: true, online: true };
              const tags = selItem.tags || (s.dietary || []).slice(0, 3);
              const togP = (k) => setItem(selItem.id, { periods: Object.assign({}, periods, { [k]: !periods[k] }) });
              const togC = (k) => setItem(selItem.id, { channels: Object.assign({}, chans, { [k]: !chans[k] }) });
              return (
              <div className="rm-insp2">
                <div className="rm-insp2-top">
                  <span className="rm-insp2-thumb">{s.image ? <img src={s.image} alt="" /> : I("utensils-crossed", 22)}</span>
                  <div className="rm-insp2-hd">
                    <b>{selItem.name}</b>
                    <span className="rm-insp2-sku">SKU: {s.sku}{s.recipeCode ? " · Recipe: " + s.recipeCode : ""}</span>
                    <select className="rm-avail-sel" value={selItem.soldOut ? "sold" : "avail"} onChange={(e) => setItem(selItem.id, { soldOut: e.target.value === "sold" })}><option value="avail">● Available</option><option value="sold">● Sold out</option></select>
                  </div>
                  <button className="rm-iconbtn" onClick={() => setSelId(null)}>{I("x", 16)}</button>
                </div>
                <div className="rm-insp2-tabs">{["Overview", "Nutrition", "Allergens", "Pricing", "Availability", "Modifiers"].map((t) => <button key={t} className={insTab === t.toLowerCase() ? "on" : ""} onClick={() => setInsTab(t.toLowerCase())}>{t}</button>)}</div>

                <div className="rm-insp2-body">
                  <div className="rm-i2-row"><div className="rm-i2-fld grow"><span>Description</span><p>{s.dietary && s.dietary.length ? selItem.name + " — " + s.dietary.join(", ") + "." : "Linked to the approved recipe; edit source to change ingredients."}</p></div>
                    <div className="rm-i2-fld"><span>Category</span><b>{I("utensils-crossed", 12)} {cn}</b></div></div>

                  <div className="rm-i2-cards">
                    <div className="rm-i2-card"><span>Price</span><b>{selItem.price != null ? RM().money(selItem.price, d.currency) : "—"}</b>{I("pencil", 12)}</div>
                    <div className="rm-i2-card"><span>Status</span><b className="ok">● {selItem.soldOut ? "Sold out" : "Available"}</b></div>
                    <div className={"rm-i2-card " + (s.compliant ? "" : "warn")}><span>Compliance</span><b className={s.compliant ? "ok" : "warn"}>{I(s.compliant ? "shield-check" : "alert-triangle", 12)} {s.compliant ? "Compliant" : "Review"}</b></div>
                  </div>

                  <div className="rm-i2-sec">Nutrition <em>(per serving)</em></div>
                  <div className="rm-i2-nutr">{[["kcal", s.calories, ""], ["Protein", s.protein, "g"], ["Carbs", s.carbs, "g"], ["Fat", s.fat, "g"], ["Fiber", s.fiber, "g"], ["Sodium", s.sodium, "mg"]].map(([l, v, u]) => <div key={l}><b>{v != null ? v + (u ? " " + u : "") : "—"}</b><span>{l}</span></div>)}</div>

                  <div className="rm-i2-sec">Allergens</div>
                  <div className="rm-i2-alg">{(s.allergens || []).length ? s.allergens.map((a) => <span key={a} className="rm-badge2 alg">{I("alert-triangle", 10)} {a}</span>) : <span className="rm-td-muted">None declared</span>}</div>

                  <div className="rm-i2-sec">Service Period</div>
                  <div className="rm-i2-checks">{PERIODS.map(([k, l]) => <label key={k} className={"rm-chk" + (periods[k] ? " on" : "")} onClick={() => togP(k)}>{I(periods[k] ? "check-square" : "square", 15)} {l}</label>)}</div>

                  <div className="rm-i2-sec">Channels</div>
                  <div className="rm-i2-checks">{CHANS.map(([k, l]) => <label key={k} className={"rm-chk" + (chans[k] ? " on" : "")} onClick={() => togC(k)}>{I(chans[k] ? "check-square" : "square", 15)} {l}</label>)}</div>

                  <div className="rm-i2-sec">Tags</div>
                  <div className="rm-i2-alg">{tags.map((t) => <span key={t} className="rm-badge2 tag">{t}</span>)}<button className="rm-tag-add" onClick={() => { const t = prompt("Add tag"); if (t) setItem(selItem.id, { tags: tags.concat([t]) }); }}>{I("plus", 12)}</button></div>

                  <div className="rm-i2-sec">Modifier groups {I("layers", 12)}</div>
                  <div className="rm-mods">
                    {(selItem.modifierGroups || []).map((ref, i) => { const g = RM().mgGet(ref.groupId || ref); if (!g) return null; const kind = (RM().MG_KINDS.find((k) => k.id === g.kind) || {}); return (
                      <div key={i} className="rm-mod-row"><span className="rm-mod-ic">{I(kind.icon || "layers", 12)}</span><span className="rm-mod-nm">{g.publicName || g.name}<em className="rm-mod-sub"> · {(g.options || []).length} options{g.required ? " · required" : ""}</em></span><button className="rm-iconbtn xs" onClick={() => setItem(selItem.id, { modifierGroups: (selItem.modifierGroups || []).filter((_, j) => j !== i) })}>{I("x", 12)}</button></div>
                    ); })}
                    <select className="rm-mod-add" value="" onChange={(e) => { if (!e.target.value) return; const cur = (selItem.modifierGroups || []); if (cur.some((r) => (r.groupId || r) === e.target.value)) return; setItem(selItem.id, { modifierGroups: cur.concat([{ groupId: e.target.value }]) }); }}>
                      <option value="">+ Attach a modifier group…</option>
                      {RM().mgLoad().map((g) => <option key={g.id} value={g.id}>{g.name} ({(RM().MG_KINDS.find((k) => k.id === g.kind) || {}).label || g.kind})</option>)}
                    </select>
                    <button className="rm-mod-manage" onClick={() => setMgLib(true)}>{I("settings", 12)} Manage groups</button>
                  </div>

                  <div className="rm-i2-toggles">
                    <label className="rm-toggle"><input type="checkbox" checked={selItem.showPrice !== false} onChange={(e) => setItem(selItem.id, { showPrice: e.target.checked })} /> Show price on menu</label>
                    <label className="rm-toggle"><input type="checkbox" checked={!!selItem.featured} onChange={(e) => setItem(selItem.id, { featured: e.target.checked })} /> Featured item</label>
                    <label className="rm-toggle"><input type="checkbox" checked={!!selItem.orderingEnabled} onChange={(e) => setItem(selItem.id, { orderingEnabled: e.target.checked })} /> Ordering enabled</label>
                  </div>
                  <button className="btn primary" style={{ width: "100%", marginTop: 12 }} onClick={() => persist()}>{I("check", 14)} Save changes</button>
                </div>
              </div>
            ); })()}
          </aside>
        </div>

        {libOpen && <RmOfferingLibrary currency={d.currency} added={(d.items || []).map((it) => it.offeringId)} onAdd={addOffering} onClose={() => setLibOpen(false)} />}
        {mgLib && <RmModifierLibrary onClose={() => setMgLib(false)} toast={toast} />}
        {preview && <RmMobilePreview menu={d} onClose={() => setPreview(false)} />}
        {histOpen && (
          <React.Fragment>
            <div className="rm-drawer-scrim" onMouseDown={(e) => { if (e.target === e.currentTarget) setHistOpen(false); }} />
            <div className="rm-drawer">
              <div className="rm-drawer-h"><div><b>Version history</b><span>{d.name}</span></div><button className="rm-iconbtn" onClick={() => setHistOpen(false)}>{I("x", 18)}</button></div>
              <div className="rm-drawer-list">
                {(d.versions || []).slice().reverse().map((v) => (
                  <div key={v.v} className="rm-ver-row"><div className="rm-ver-info"><b>Version {v.v}</b><span>{new Date(v.at).toLocaleString()} · {v.items} items · {v.by}</span></div>{v.v === d.publishedVersion ? <span className="rm-ver-current">Current</span> : <button className="btn secondary sm" onClick={() => { RM().rollback(d, v.v); toast("Rolled back to v" + v.v); setHistOpen(false); }}>{I("rotate-ccw", 13)} Roll back</button>}</div>
                ))}
                {(d.versions || []).length === 0 && <div className="rm-empty sm">{I("history", 22, 1.6)}<p>No published versions yet.</p></div>}
              </div>
            </div>
          </React.Fragment>
        )}
      </div>
    );
  }

  /* ── Approved Offering Library drawer ── */
  function RmModifierLibrary({ onClose, toast }) {
    const [, bump] = uS(0);
    const groups = RM().mgLoad();
    const [edit, setEdit] = uS(null);
    const refresh = () => bump((n) => n + 1);
    const newGroup = () => setEdit({ id: RM().mgNewId(), name: "New group", publicName: "", kind: "side", required: false, min: 0, max: 1, options: [], active: true });
    if (edit) return (
      <React.Fragment>
        <div className="rm-drawer-scrim" onMouseDown={(e) => { if (e.target === e.currentTarget) setEdit(null); }} />
        <div className="rm-drawer">
          <div className="rm-drawer-h"><div><b>{edit.name || "Group"}</b><span>Reusable modifier group</span></div><button className="rm-iconbtn" onClick={() => setEdit(null)}>{I("x", 18)}</button></div>
          <div className="rm-drawer-list">
            <label className="rm-fld"><span>Internal name</span><input value={edit.name} onChange={(e) => setEdit(Object.assign({}, edit, { name: e.target.value }))} /></label>
            <label className="rm-fld"><span>Customer-facing name</span><input value={edit.publicName} onChange={(e) => setEdit(Object.assign({}, edit, { publicName: e.target.value }))} placeholder="e.g. Choose a side" /></label>
            <div className="rm-fld-row">
              <label className="rm-fld"><span>Kind</span><select value={edit.kind} onChange={(e) => setEdit(Object.assign({}, edit, { kind: e.target.value }))}>{RM().MG_KINDS.map((k) => <option key={k.id} value={k.id}>{k.label}</option>)}</select></label>
              <label className="rm-fld"><span>Selection</span><select value={edit.required ? "req" : "opt"} onChange={(e) => setEdit(Object.assign({}, edit, { required: e.target.value === "req" }))}><option value="opt">Optional</option><option value="req">Required</option></select></label>
            </div>
            <div className="rm-fld-row">
              <label className="rm-fld"><span>Min selections</span><input type="number" value={edit.min} onChange={(e) => setEdit(Object.assign({}, edit, { min: Number(e.target.value) }))} /></label>
              <label className="rm-fld"><span>Max selections</span><input type="number" value={edit.max} onChange={(e) => setEdit(Object.assign({}, edit, { max: Number(e.target.value) }))} /></label>
            </div>
            <div className="rm-i2-sec">Options</div>
            {(edit.options || []).map((op, i) => (
              <div key={op.id} className="rm-mopt">
                <input className="rm-mopt-nm" value={op.name} onChange={(e) => { const o = edit.options.slice(); o[i] = Object.assign({}, op, { name: e.target.value }); setEdit(Object.assign({}, edit, { options: o })); }} placeholder="Option name" />
                <select className="rm-mopt-of" value={op.offeringId || ""} onChange={(e) => { const o = edit.options.slice(); o[i] = Object.assign({}, op, { offeringId: e.target.value || null }); setEdit(Object.assign({}, edit, { options: o })); }}><option value="">no recipe link</option>{RM().eligibleOfferings().filter((r) => r.eligible).map((r) => <option key={r.offering.id} value={r.offering.id}>{r.offering.name}</option>)}</select>
                <div className="rm-mopt-pr"><span>+</span><input type="number" value={op.priceAdj} onChange={(e) => { const o = edit.options.slice(); o[i] = Object.assign({}, op, { priceAdj: Number(e.target.value) }); setEdit(Object.assign({}, edit, { options: o })); }} /></div>
                <button className="rm-iconbtn xs" title={op.isDefault ? "Default" : "Set default"} onClick={() => { const o = edit.options.map((x, j) => Object.assign({}, x, { isDefault: j === i })); setEdit(Object.assign({}, edit, { options: o })); }}>{I(op.isDefault ? "check-circle" : "circle", 14)}</button>
                <button className="rm-iconbtn xs danger" onClick={() => setEdit(Object.assign({}, edit, { options: edit.options.filter((_, j) => j !== i) }))}>{I("x", 13)}</button>
              </div>
            ))}
            <button className="rm-mod-add" onClick={() => setEdit(Object.assign({}, edit, { options: (edit.options || []).concat([{ id: "o" + Date.now(), name: "New option", offeringId: null, priceAdj: 0, isDefault: false }]) }))}>{I("plus", 13)} Add option</button>
          </div>
          <div className="rm-drawer-foot"><button className="btn ghost sm" onClick={() => setEdit(null)}>Cancel</button><button className="btn primary sm" onClick={() => { RM().mgSave(edit); toast("Group saved"); setEdit(null); refresh(); }}>{I("check", 14)} Save group</button></div>
        </div>
      </React.Fragment>
    );
    return (
      <React.Fragment>
        <div className="rm-drawer-scrim" onMouseDown={(e) => { if (e.target === e.currentTarget) onClose(); }} />
        <div className="rm-drawer">
          <div className="rm-drawer-h"><div><b>Modifier groups</b><span>Reusable across every menu</span></div><button className="rm-iconbtn" onClick={onClose}>{I("x", 18)}</button></div>
          <div className="rm-drawer-list">
            {groups.map((g) => { const k = RM().MG_KINDS.find((x) => x.id === g.kind) || {}; return (
              <div key={g.id} className="rm-lib-card" onClick={() => setEdit(JSON.parse(JSON.stringify(g)))}>
                <span className="rm-lib-thumb">{I(k.icon || "layers", 18)}</span>
                <div className="rm-lib-body"><b>{g.name}</b><span>{k.label} · {(g.options || []).length} options{g.required ? " · required" : ""}</span></div>
                <button className="rm-iconbtn danger" onClick={(e) => { e.stopPropagation(); if (confirm("Delete group?")) { RM().mgDelete(g.id); refresh(); } }}>{I("trash-2", 15)}</button>
              </div>
            ); })}
          </div>
          <div className="rm-drawer-foot"><button className="btn primary sm" onClick={newGroup} style={{ width: "100%" }}>{I("plus", 14)} New modifier group</button></div>
        </div>
      </React.Fragment>
    );
  }

  /* ── Approved Offering Library drawer ── */
  function RmOfferingLibrary({ currency, added, onAdd, onClose }) {
    const [q, setQ] = uS("");
    const rows = uM(() => RM().eligibleOfferings(), []);
    const filtered = rows.filter((r) => !q || (r.offering.name || "").toLowerCase().includes(q.toLowerCase()));
    return (
      <React.Fragment>
        <div className="rm-drawer-scrim" onMouseDown={(e) => { if (e.target === e.currentTarget) onClose(); }} />
        <div className="rm-drawer">
          <div className="rm-drawer-h"><div><b>Approved Offerings</b><span>Only published offerings backed by approved recipes</span></div><button className="rm-iconbtn" onClick={onClose}>{I("x", 18)}</button></div>
          <div className="rm-drawer-search">{I("search", 16)}<input value={q} onChange={(e) => setQ(e.target.value)} placeholder="Search offerings…" autoFocus /></div>
          <div className="rm-drawer-list">
            {filtered.length === 0 ? <div className="rm-empty sm">{I("search-x", 22, 1.6)}<p>No eligible offerings found.</p></div>
              : filtered.map((r) => { const o = r.offering; const s = RM().snapshot(o.id); const isAdded = added.includes(o.id); return (
                <div key={o.id} className={"rm-lib-card" + (r.eligible ? "" : " ineligible")}>
                  <span className="rm-lib-thumb">{s.image ? <img src={s.image} alt="" /> : I("utensils-crossed", 18)}</span>
                  <div className="rm-lib-body">
                    <b>{o.name}</b>
                    <span>{o.type || "offering"} · {s.calories != null ? s.calories + " kcal" : "nutrition linked"}{(s.allergens || []).length ? " · " + s.allergens.slice(0, 2).join(", ") : ""}</span>
                    {!r.eligible && <span className="rm-lib-err">{I("alert-triangle", 11)} {r.errors[0]}</span>}
                  </div>
                  {r.eligible ? (isAdded ? <span className="rm-lib-added">{I("check", 14)} Added</span> : <button className="btn primary sm" onClick={() => onAdd(o)}>{I("plus", 13)} Add</button>) : <span className="rm-lib-blocked">Blocked</span>}
                </div>
              ); })}
          </div>
        </div>
      </React.Fragment>
    );
  }

  window.RestaurantMenuBuilder = RmDashboard;

  /* ── Public mobile render: phone frame → categorized menu → item detail.
     Same source-of-truth snapshots the public QR page uses. ── */
  function RmMobilePreview({ menu, onClose }) {
    const [openItem, setOpenItem] = uS(null);
    const cur = menu.currency || "CAD";
    const cats = (menu.categories || []).slice().sort((a, b) => (a.order || 0) - (b.order || 0));
    const uncat = (menu.items || []).filter((it) => !it.category || !cats.some((c) => c.id === it.category));
    const inCat = (cid) => (menu.items || []).filter((it) => it.category === cid);
    const snap = (it) => RM().snapshot(it.offeringId);

    const ItemCard = ({ it }) => {
      const s = snap(it);
      return (
        <button className="rmp-card" onClick={() => setOpenItem(it)}>
          <span className="rmp-card-thumb">{s.image ? <img src={s.image} alt="" /> : I("utensils-crossed", 20)}</span>
          <span className="rmp-card-body">
            <span className="rmp-card-top"><b>{it.name}</b>{it.showPrice !== false && <em>{(it.priceLabel ? it.priceLabel + " " : "") + (it.price != null ? RM().money(it.price, cur) : "")}</em>}</span>
            <span className="rmp-card-meta">{s.calories != null ? s.calories + " kcal" : ""}{s.protein != null ? " · " + s.protein + "g protein" : ""}</span>
            <span className="rmp-card-tags">
              {it.featured && <span className="rmp-tag feat">Featured</span>}
              {it.soldOut && <span className="rmp-tag sold">Sold out</span>}
              {(s.allergens || []).slice(0, 2).map((a) => <span key={a} className="rmp-tag alg">{a}</span>)}
            </span>
          </span>
        </button>
      );
    };

    const detail = openItem ? snap(openItem) : null;

    return (
      <React.Fragment>
        <div className="rm-drawer-scrim" onMouseDown={(e) => { if (e.target === e.currentTarget) onClose(); }} />
        <div className="rmp-wrap">
          <div className="rmp-phone">
            <div className="rmp-notch" />
            <div className="rmp-screen">
              {!openItem ? (
                <div className="rmp-menu">
                  <div className="rmp-hero"><b>{menu.publicTitle || menu.name}</b><span>{(RM().MENU_TYPES.find((t) => t.id === menu.menuType) || {}).label} menu</span></div>
                  {cats.map((c) => inCat(c.id).length > 0 && (
                    <div key={c.id} className="rmp-cat"><div className="rmp-cat-h">{c.name}</div>{inCat(c.id).map((it) => <ItemCard key={it.id} it={it} />)}</div>
                  ))}
                  {uncat.length > 0 && <div className="rmp-cat"><div className="rmp-cat-h">More</div>{uncat.map((it) => <ItemCard key={it.id} it={it} />)}</div>}
                  {(menu.items || []).length === 0 && <div className="rmp-empty">No items on this menu yet.</div>}
                  <div className="rmp-foot">Powered by NutriDMS</div>
                </div>
              ) : (
                <div className="rmp-detail">
                  <button className="rmp-back" onClick={() => setOpenItem(null)}>{I("arrow-left", 16)} Menu</button>
                  <div className="rmp-detail-img">{detail.image ? <img src={detail.image} alt="" /> : I("utensils-crossed", 30)}</div>
                  <h3>{openItem.name}</h3>
                  {openItem.showPrice !== false && openItem.price != null && <div className="rmp-detail-price">{(openItem.priceLabel ? openItem.priceLabel + " " : "") + RM().money(openItem.price, cur)}</div>}
                  <div className="rmp-nutr">
                    {[["Calories", detail.calories, ""], ["Protein", detail.protein, "g"], ["Carbs", detail.carbs, "g"], ["Fat", detail.fat, "g"]].map(([l, v, u]) => <div key={l} className="rmp-nutr-cell"><b>{v != null ? v + u : "—"}</b><span>{l}</span></div>)}
                  </div>
                  {(detail.allergens || []).length > 0 && <div className="rmp-sec"><div className="rmp-sec-h">Allergens</div><div className="rmp-alg-row">{detail.allergens.map((a) => <span key={a} className="rmp-tag alg">Contains {a}</span>)}</div></div>}
                  {(detail.dietary || []).length > 0 && <div className="rmp-sec"><div className="rmp-sec-h">Dietary</div><div className="rmp-alg-row">{detail.dietary.map((d) => <span key={d} className="rmp-tag diet">{d}</span>)}</div></div>}
                  <div className="rmp-disc">{I("info", 11)} Nutrition from the approved recipe. Confirm allergens with staff before ordering.</div>
                </div>
              )}
            </div>
          </div>
          <button className="rmp-close" onClick={onClose}>{I("x", 18)} Close preview</button>
        </div>
      </React.Fragment>
    );
  }
  window.RmMobilePreview = RmMobilePreview;

  /* ── QR code + simulated scan analytics per menu ── */
  function rmSeededCount(seed, min, max) { var h = 0; for (var i = 0; i < seed.length; i++) h = (h * 31 + seed.charCodeAt(i)) & 0xffff; return min + (h % (max - min + 1)); }
  function RmQrPanel({ menu, onClose }) {
    const QRc = window.QR;
    const url = "https://menu.nutridms.com/m/" + menu.id;
    const scans = rmSeededCount(menu.id, 240, 3200);
    const uniq = Math.round(scans * 0.72);
    const reorders = Math.round(scans * 0.14);
    const days = [["Mon", 0.7], ["Tue", 0.5], ["Wed", 0.9], ["Thu", 0.8], ["Fri", 1], ["Sat", 0.95], ["Sun", 0.6]];
    const topItems = (menu.items || []).slice(0, 4).map((it, i) => ({ name: it.name, v: Math.round(scans * (0.3 - i * 0.05)) }));
    const download = () => {
      try {
        const svg = document.querySelector(".rm-qr-code svg") || document.querySelector(".rm-qr-code canvas");
        if (!svg) return;
        if (svg.tagName === "CANVAS") { const a = document.createElement("a"); a.href = svg.toDataURL("image/png"); a.download = menu.name + "-qr.png"; a.click(); return; }
        const xml = new XMLSerializer().serializeToString(svg); const blob = new Blob([xml], { type: "image/svg+xml" });
        const a = document.createElement("a"); a.href = URL.createObjectURL(blob); a.download = menu.name + "-qr.svg"; a.click();
      } catch (e) {}
    };
    return (
      <React.Fragment>
        <div className="rm-drawer-scrim" onMouseDown={(e) => { if (e.target === e.currentTarget) onClose(); }} />
        <div className="rm-drawer">
          <div className="rm-drawer-h"><div><b>QR & Analytics</b><span>{menu.name}</span></div><button className="rm-iconbtn" onClick={onClose}>{I("x", 18)}</button></div>
          <div className="rm-drawer-list">
            <div className="rm-qr-card">
              <div className="rm-qr-code">{QRc ? <QRc value={url} size={150} /> : I("qr-code", 60)}</div>
              <div className="rm-qr-url">{url}</div>
              <div className="rm-qr-btns">
                <button className="btn secondary sm" onClick={() => { try { navigator.clipboard.writeText(url); window.__toast && window.__toast("Link copied"); } catch (e) {} }}>{I("link", 13)} Copy link</button>
                <button className="btn primary sm" onClick={download}>{I("download", 13)} Download QR</button>
              </div>
              <div className="rm-qr-note">{I("info", 11)} The QR encodes only this secure link — update the menu anytime without reprinting.</div>
            </div>
            <div className="rm-an-kpis">
              <div className="rm-an-kpi"><b>{scans.toLocaleString()}</b><span>Total scans</span></div>
              <div className="rm-an-kpi"><b>{uniq.toLocaleString()}</b><span>Unique visitors</span></div>
              <div className="rm-an-kpi"><b>{reorders.toLocaleString()}</b><span>Reorder clicks</span></div>
            </div>
            <div className="rm-an-sec"><div className="rm-an-h">Scans by day</div>
              <div className="rm-an-bars">{days.map(([d, h]) => <div key={d} className="rm-an-bar"><span className="rm-an-fill" style={{ height: (h * 100) + "%" }} /><em>{d}</em></div>)}</div>
            </div>
            {topItems.length > 0 && <div className="rm-an-sec"><div className="rm-an-h">Most-viewed items</div>
              {topItems.map((t) => <div key={t.name} className="rm-an-row"><span>{t.name}</span><b>{t.v}</b></div>)}
            </div>}
            <div className="rm-an-note">Analytics are simulated for this prototype. Live scans populate when the backend QR resolver is connected.</div>
          </div>
        </div>
      </React.Fragment>
    );
  }
  window.RmQrPanel = RmQrPanel;
})();
