/* =============================================================
   CoreIQ Office — Stores, transfers, reports, admin
   ============================================================= */
const { useState: oxUseState, useMemo: oxUseMemo } = React;

// =================================================================
// STORES (list & detail)
// =================================================================
function Stores() {
  const { setScreen, setScope, setScreenState, pushToast } = window.useOffice();

  return (
    <div className="off-screen">
      <header className="off-screen-header">
        <div className="off-screen-header-meta">
          <span className="off-screen-eyebrow">Multi-store</span>
          <h2 className="off-screen-title">Stores</h2>
        </div>
        <div className="off-screen-actions">
          <button className="btn btn--ghost btn--sm">Export</button>
          <button className="btn btn--primary btn--sm"><OIcon name="plus"/> Add store</button>
        </div>
      </header>

      <div className="off-screen-body">
        <div className="off-kpi-grid" style={{gridTemplateColumns:'repeat(4,1fr)'}}>
          <KpiCard label="Stores in group" value={OD.STORES.length} delta={{text: "Across VIC"}}/>
          <KpiCard label="Total patients" value={OD.STORES.reduce((s, st) => s + st.patients, 0).toLocaleString()} delta={{dir: "up", text: "+182 this month"}}/>
          <KpiCard label="Takings MTD" value={oMoney(OD.STORES.reduce((s, st) => s + st.takings.mtd, 0))} delta={{dir: "up", text: "▲ 11.2% YoY"}}/>
          <KpiCard label="Group stock value" value={oMoney(OD.STORES.reduce((s, st) => s + st.stockValue, 0))} delta={{text: "Ex-GST · at cost"}}/>
        </div>

        <div className="off-table">
          <div className="off-grid" style={{gridTemplateColumns:'80px 1.4fr 1fr 130px 110px 130px 130px 130px 80px'}}>
            <div className="off-grid-headcell">Code</div>
            <div className="off-grid-headcell">Store</div>
            <div className="off-grid-headcell">Manager</div>
            <div className="off-grid-headcell" style={{justifyContent:'flex-end'}}>Registers</div>
            <div className="off-grid-headcell" style={{justifyContent:'flex-end'}}>Patients</div>
            <div className="off-grid-headcell" style={{justifyContent:'flex-end'}}>Today</div>
            <div className="off-grid-headcell" style={{justifyContent:'flex-end'}}>MTD</div>
            <div className="off-grid-headcell" style={{justifyContent:'flex-end'}}>Stock value</div>
            <div className="off-grid-headcell">Open</div>

            {OD.STORES.map(s => (
              <div key={s.id} className="off-grid-row">
                <div className="off-grid-cell">
                  <div className="off-topbar-store-av" style={{width:28, height:28, borderRadius:6}}>{s.code}</div>
                </div>
                <div className="off-grid-cell off-cell-strong">
                  {s.name}
                  <div className="off-cell-mono off-muted" style={{marginTop:2}}>{s.address}</div>
                </div>
                <div className="off-grid-cell">{s.manager}</div>
                <div className="off-grid-cell off-cell-num">{s.registers}</div>
                <div className="off-grid-cell off-cell-num">{s.patients.toLocaleString()}</div>
                <div className="off-grid-cell off-cell-num">{oMoney(s.takings.today)}</div>
                <div className="off-grid-cell off-cell-num">{oMoney(s.takings.mtd)}</div>
                <div className="off-grid-cell off-cell-num">{oMoney(s.stockValue)}</div>
                <div className="off-grid-cell">
                  <button className="btn btn--ghost btn--sm" onClick={() => { setScreenState({ activeStoreId: s.id }); setScreen("storeDetail"); }}>Open</button>
                </div>
              </div>
            ))}
          </div>
        </div>

        <div style={{marginTop:18}}>
          <div className="off-card-title" style={{fontSize:13, marginBottom:10, textTransform:'uppercase', letterSpacing:'0.06em', color:'var(--text-subtle)', fontWeight:500}}>Compare · MTD takings</div>
          <div className="off-card">
            <div className="dash-chart" style={{height:180}}>
              {OD.REVENUE_30D["S-001"].map((_, i) => {
                const a = OD.REVENUE_30D["S-001"][i];
                const b = OD.REVENUE_30D["S-002"][i];
                const c = OD.REVENUE_30D["S-003"][i];
                const max = 6500;
                return (
                  <div key={i} style={{flex:1, display:'flex', gap:1, alignItems:'flex-end'}}>
                    <div style={{flex:1, background:'var(--teal-700)', height:(a/max*100)+'%', borderRadius:'1px 1px 0 0'}}/>
                    <div style={{flex:1, background:'var(--navy-600)', height:(b/max*100)+'%', borderRadius:'1px 1px 0 0'}}/>
                    <div style={{flex:1, background:'var(--violet-600)', height:(c/max*100)+'%', borderRadius:'1px 1px 0 0'}}/>
                  </div>
                );
              })}
            </div>
            <div className="dash-chart-legend">
              <span><span className="dash-chart-legend-dot" style={{background:'var(--teal-700)'}}/>Camberwell</span>
              <span><span className="dash-chart-legend-dot" style={{background:'var(--navy-600)'}}/>Glen Iris</span>
              <span><span className="dash-chart-legend-dot" style={{background:'var(--violet-600)'}}/>Ringwood</span>
            </div>
          </div>
        </div>
      </div>
    </div>
  );
}

function StoreDetail() {
  const { setScreen, screenState } = window.useOffice();
  const s = findS(screenState.activeStoreId) || OD.STORES[0];
  const stock = OD.STOCK[s.id] || {};
  const stockedSkus = Object.keys(stock).length;
  const stockValue = Object.entries(stock).reduce((acc, [pid, v]) => acc + (v.onHand * (findP(pid)?.cost || 0)), 0);
  const lowStock = Object.entries(stock).filter(([pid, v]) => v.onHand <= v.min && v.min > 0).length;

  const STORE_COLOURS = { "S-001": "var(--teal-700)", "S-002": "var(--navy-600)", "S-003": "var(--violet-600)" };

  return (
    <div className="off-screen">
      <header className="off-screen-header">
        <div className="off-screen-header-meta">
          <span className="off-screen-eyebrow">Store · {s.code}</span>
          <h2 className="off-screen-title">{s.name}</h2>
        </div>
        <div className="off-screen-actions">
          <button className="btn btn--ghost btn--sm" onClick={() => setScreen("stores")}>
            <OIcon name="chevron-right" style={{transform:'rotate(180deg)'}}/> Stores
          </button>
          <button className="btn btn--secondary btn--sm"><OIcon name="transfer"/> Transfer to/from</button>
          <button className="btn btn--secondary btn--sm">Edit details</button>
        </div>
      </header>

      <div className="off-screen-body">
        <div className="off-card" style={{flexDirection:'row', alignItems:'flex-start', gap:18}}>
          <div className="off-topbar-store-av" style={{width:64, height:64, borderRadius:12, background:STORE_COLOURS[s.id], color:'#fff', fontSize:16}}>
            {s.code}
          </div>
          <div style={{flex:1}}>
            <div style={{fontSize:22, fontWeight:600, letterSpacing:'-0.015em'}}>{s.name}</div>
            <div className="off-mono off-muted" style={{marginTop:4}}>{s.address} · {s.phone}</div>
            <div style={{display:'flex', gap:10, flexWrap:'wrap', marginTop:10}}>
              <span className="badge badge--neutral">{s.type === "flagship" ? "Flagship" : s.type === "suburban" ? "Suburban" : "Regional"}</span>
              <span className="badge badge--neutral">{s.registers} registers</span>
              <span className="badge badge--paid"><span className="badge-dot"/> Open · {s.hours.split("·")[0]}</span>
              <span className="badge badge--neutral">Manager · {s.manager}</span>
              <span className="badge badge--neutral">Opened {s.openedOn}</span>
            </div>
          </div>
        </div>

        <div className="off-kpi-grid" style={{marginTop:14}}>
          <KpiCard label="Takings today"   value={oMoney(s.takings.today)} delta={{dir:"up", text:"▲ 8.4% vs Mon avg"}}/>
          <KpiCard label="Scripts today"   value={s.scripts.today}         delta={{text: s.scripts.mtd.toLocaleString() + " MTD"}}/>
          <KpiCard label="Stock value"     value={oMoney(stockValue)}      delta={{text: stockedSkus + " SKUs · " + lowStock + " low"}}/>
          <KpiCard label="Patients"        value={s.patients.toLocaleString()} delta={{dir:"up", text:"+24 new this month"}}/>
        </div>

        <div style={{display:'grid', gridTemplateColumns:'2fr 1fr', gap:14, marginTop:14}}>
          <div className="off-card">
            <div className="off-card-header">
              <h3 className="off-card-title">Revenue · last 30 days</h3>
              <span className="off-mono off-muted">{oMoney(s.takings.mtd)} MTD</span>
            </div>
            <div className="dash-chart">
              {OD.REVENUE_30D[s.id].map((v, i) => (
                <div key={i} style={{flex:1, background: STORE_COLOURS[s.id], height: (v / 6500 * 100) + "%", borderRadius:'2px 2px 0 0', opacity: i === OD.REVENUE_30D[s.id].length - 1 ? 1 : 0.85}}/>
              ))}
            </div>
          </div>

          <div className="off-card">
            <div className="off-card-title">Top movers · 30d</div>
            <div style={{display:'flex', flexDirection:'column', gap:8, fontSize:13}}>
              {OD.PRODUCTS.slice(0, 6).map((p, i) => (
                <div key={p.id} style={{display:'flex', justifyContent:'space-between', alignItems:'center'}}>
                  <span style={{flex:1, fontWeight: i < 3 ? 500 : 400, whiteSpace:'nowrap', overflow:'hidden', textOverflow:'ellipsis'}}>{p.name}</span>
                  <span className="off-mono" style={{color:'var(--text-muted)'}}>{Math.max(20, 180 - i * 18)} units</span>
                </div>
              ))}
            </div>
          </div>
        </div>
      </div>
    </div>
  );
}

// =================================================================
// TRANSFERS
// =================================================================
function Transfers() {
  const { pushToast } = window.useOffice();
  const [filter, setFilter] = oxUseState("all");
  const [creating, setCreating] = oxUseState(false);

  const FILTERS = [
    { key: "all",        label: "All",         pred: () => true },
    { key: "pending",    label: "Pending",     pred: t => t.status === "pending" },
    { key: "in-transit", label: "In transit",  pred: t => t.status === "in-transit" },
    { key: "received",   label: "Received",    pred: t => t.status === "received" },
    { key: "cancelled",  label: "Cancelled",   pred: t => t.status === "cancelled" },
  ];

  return (
    <div className="off-screen">
      <header className="off-screen-header">
        <div className="off-screen-header-meta">
          <span className="off-screen-eyebrow">Multi-store</span>
          <h2 className="off-screen-title">Stock transfers</h2>
        </div>
        <div className="off-screen-actions">
          <button className="btn btn--primary btn--sm" onClick={() => setCreating(true)}>
            <OIcon name="plus"/> New transfer
          </button>
        </div>
      </header>

      <div className="off-screen-body">
        <div className="off-table">
          <div className="off-table-toolbar">
            <div className="off-filters">
              {FILTERS.map(f => {
                const c = OD.TRANSFERS.filter(f.pred).length;
                return (
                  <button key={f.key} className={"off-filter" + (filter === f.key ? " off-filter--active" : "")} onClick={() => setFilter(f.key)}>
                    {f.label} <span className="off-filter-count">{c}</span>
                  </button>
                );
              })}
            </div>
          </div>

          <div className="off-grid" style={{gridTemplateColumns:'100px 140px 140px 1fr 100px 130px 130px 130px'}}>
            <div className="off-grid-headcell">ID</div>
            <div className="off-grid-headcell">From</div>
            <div className="off-grid-headcell">To</div>
            <div className="off-grid-headcell">Items</div>
            <div className="off-grid-headcell" style={{justifyContent:'flex-end'}}>Lines</div>
            <div className="off-grid-headcell">Requested</div>
            <div className="off-grid-headcell">Expected</div>
            <div className="off-grid-headcell">Status</div>

            {OD.TRANSFERS.filter(FILTERS.find(f => f.key === filter).pred).map(t => {
              const from = findS(t.from);
              const to = findS(t.to);
              return (
                <div key={t.id} className="off-grid-row">
                  <div className="off-grid-cell off-cell-mono off-cell-strong">{t.id}</div>
                  <div className="off-grid-cell">{from.name}</div>
                  <div className="off-grid-cell">{to.name}</div>
                  <div className="off-grid-cell" style={{whiteSpace:'normal'}}>
                    {t.items.slice(0, 2).map((i, j) => (
                      <div key={j} style={{fontSize:13}}>{findP(i.productId)?.name} <span className="off-muted">× {i.qty}</span></div>
                    ))}
                    {t.items.length > 2 && <div className="off-muted" style={{fontSize:12}}>+{t.items.length - 2} more</div>}
                  </div>
                  <div className="off-grid-cell off-cell-num">{t.items.length}</div>
                  <div className="off-grid-cell off-mono off-muted">{t.requested}</div>
                  <div className="off-grid-cell off-mono off-muted">{t.expected}</div>
                  <div className="off-grid-cell">
                    {t.status === "pending"    && <span className="badge badge--hold"><span className="badge-dot"/> Pending</span>}
                    {t.status === "in-transit" && <span className="badge badge--brand"><span className="badge-dot"/> In transit</span>}
                    {t.status === "received"   && <span className="badge badge--paid"><span className="badge-dot"/> Received</span>}
                    {t.status === "cancelled"  && <span className="badge badge--void"><span className="badge-dot"/> Cancelled</span>}
                  </div>
                </div>
              );
            })}
          </div>
        </div>
      </div>

      {creating && <TransferModal onClose={() => setCreating(false)} onSubmit={() => { setCreating(false); pushToast({kind:'paid', icon:'transfer', title:'Transfer requested', meta:'Awaiting source store packing'}); }}/>}
    </div>
  );
}

function TransferModal({ onClose, onSubmit }) {
  const [from, setFrom] = oxUseState("S-001");
  const [to, setTo] = oxUseState("S-002");
  const [items, setItems] = oxUseState([{ productId: "", qty: 1 }]);

  return (
    <div className="app-overlay" onClick={onClose}>
      <div className="app-overlay-card" style={{width:640}} onClick={e => e.stopPropagation()}>
        <div className="app-overlay-head">
          <h3>New stock transfer</h3>
          <button className="off-topbar-btn" onClick={onClose} style={{marginLeft:'auto', border:'none'}}><OIcon name="x"/></button>
        </div>
        <div style={{padding:'18px 22px', display:'flex', flexDirection:'column', gap:14}}>
          <div style={{display:'grid', gridTemplateColumns:'1fr auto 1fr', gap:10, alignItems:'flex-end'}}>
            <div className="field">
              <label className="field-label">From</label>
              <select className="input select" value={from} onChange={e => setFrom(e.target.value)}>
                {OD.STORES.map(s => <option key={s.id} value={s.id}>{s.name}</option>)}
              </select>
            </div>
            <div style={{marginBottom:8, padding:'8px 10px', color:'var(--text-subtle)'}}>→</div>
            <div className="field">
              <label className="field-label">To</label>
              <select className="input select" value={to} onChange={e => setTo(e.target.value)}>
                {OD.STORES.filter(s => s.id !== from).map(s => <option key={s.id} value={s.id}>{s.name}</option>)}
              </select>
            </div>
          </div>

          <div>
            <div style={{fontSize:11, textTransform:'uppercase', letterSpacing:'0.06em', color:'var(--text-subtle)', fontWeight:500, marginBottom:6}}>Items</div>
            {items.map((it, i) => (
              <div key={i} style={{display:'grid', gridTemplateColumns:'1fr 80px 40px', gap:8, marginBottom:6}}>
                <select className="input select" value={it.productId} onChange={e => setItems(arr => arr.map((x, j) => j === i ? { ...x, productId: e.target.value } : x))}>
                  <option value="">Select product…</option>
                  {OD.PRODUCTS.map(p => <option key={p.id} value={p.id}>{p.name} · {p.strength}</option>)}
                </select>
                <input className="input tabular" type="number" value={it.qty} onChange={e => setItems(arr => arr.map((x, j) => j === i ? { ...x, qty: parseInt(e.target.value) || 0 } : x))}/>
                <button className="btn btn--ghost btn--sm" onClick={() => setItems(arr => arr.filter((_, j) => j !== i))}><OIcon name="x"/></button>
              </div>
            ))}
            <button className="btn btn--ghost btn--sm" onClick={() => setItems(arr => [...arr, { productId: "", qty: 1 }])}>
              <OIcon name="plus"/> Add item
            </button>
          </div>

          <div className="field">
            <label className="field-label">Reason / notes</label>
            <textarea className="input" rows={2} placeholder="e.g. Glen Iris stock-out — short-term cover" style={{height:'auto', padding:12}}/>
          </div>
        </div>
        <div style={{padding:'12px 22px', borderTop:'1px solid var(--border)', display:'flex', gap:10, justifyContent:'flex-end', background:'var(--bg-subtle)'}}>
          <button className="btn btn--ghost" onClick={onClose}>Cancel</button>
          <button className="btn btn--primary" onClick={onSubmit}><OIcon name="check"/> Create transfer</button>
        </div>
      </div>
    </div>
  );
}

// =================================================================
// REPORTS + REPORT COLUMN SCHEMAS
// =================================================================
function Reports() {
  const { setScreen, setScreenState, pushToast } = window.useOffice();
  const [active, setActive] = oxUseState(OD.REPORT_SCHEMAS[0].id);
  const schema = OD.REPORT_SCHEMAS.find(s => s.id === active);
  const baseFields = OD.COLUMN_FIELDS[schema.base];

  // Build rows from products (for stock-based reports) or fake sales (for sales-based)
  const rows = oxUseMemo(() => {
    if (schema.base === "stock") {
      return OD.PRODUCTS.map(p => {
        const onHand = window.officeTotalStock(p.id);
        const stock = OD.STOCK["S-001"]?.[p.id] || {};
        const margin = p.price > 0 ? Math.round(((p.price - p.cost) / p.price) * 100) : 0;
        return {
          ...p,
          onHand,
          min: stock.min || 0,
          max: stock.max || 0,
          expiry: stock.expiry || "—",
          lot: stock.lot || "—",
          location: stock.location || "—",
          margin,
          lastSold: stock.lastSold || "—",
          movement: Math.max(2, Math.round(Math.random() * 180)),
          stockValue: onHand * p.cost,
        };
      });
    }
    // sales — synthetic
    return Array.from({length: 24}, (_, i) => ({
      date: ["Today","Yesterday","2 days ago","3 days ago"][i % 4],
      store: OD.STORES[i % 3].name,
      register: "Reg " + ((i % 2) + 1),
      staff: ["Suni K.","Rachel P.","James L.","Priya S."][i % 4],
      items: 1 + (i % 6),
      subtotal: 14 + i * 7.4,
      pbs: i % 3 === 0 ? 18.20 : 0,
      discount: i % 5 === 0 ? -2.40 : 0,
      total: 14 + i * 7.4 + (i % 5 === 0 ? -2.40 : 0),
      method: ["Eftpos","Cash","Wallet","Account"][i % 4],
      patient: ["M. Tan","J. Riley","A. Costa","Walk-in","P. Sharma"][i % 5],
    }));
  }, [active, schema]);

  return (
    <div className="off-screen">
      <header className="off-screen-header">
        <div className="off-screen-header-meta">
          <span className="off-screen-eyebrow">Reports</span>
          <h2 className="off-screen-title">{schema.name}</h2>
        </div>
        <div className="off-screen-actions">
          <button className="btn btn--ghost btn--sm">Date range</button>
          <button className="btn btn--secondary btn--sm">Customise columns</button>
          <button className="btn btn--secondary btn--sm"><OIcon name="printer"/> Export CSV</button>
        </div>
      </header>

      <div className="off-screen-body" style={{display:'grid', gridTemplateColumns:'220px 1fr', gap:14}}>
        {/* Saved schemas sidebar */}
        <div>
          <div style={{fontSize:11, textTransform:'uppercase', letterSpacing:'0.06em', color:'var(--text-subtle)', fontWeight:500, marginBottom:8}}>Saved reports</div>
          <div style={{display:'flex', flexDirection:'column', gap:2}}>
            {OD.REPORT_SCHEMAS.map(s => (
              <button
                key={s.id}
                onClick={() => setActive(s.id)}
                className="off-nav-item"
                style={{
                  color: active === s.id ? '#fff' : 'var(--text)',
                  background: active === s.id ? 'var(--brand)' : 'transparent',
                  fontFamily:'inherit',
                  fontWeight: 500,
                  fontSize: 13,
                  padding: '9px 11px',
                  borderRadius: 7,
                }}
              >
                <div style={{flex:1, minWidth:0}}>
                  <div style={{whiteSpace:'nowrap', overflow:'hidden', textOverflow:'ellipsis'}}>{s.name}</div>
                  <div style={{fontSize:10, opacity:0.7, marginTop:1}}>{s.base} · {s.columns.length} cols</div>
                </div>
              </button>
            ))}
          </div>
          <button className="btn btn--ghost btn--sm btn--block" style={{marginTop:8, justifyContent:'flex-start'}} onClick={() => setScreen("schemas")}>
            <OIcon name="settings"/> Edit columns
          </button>
        </div>

        {/* Data */}
        <div>
          <div className="off-card" style={{marginBottom:12, flexDirection:'row', justifyContent:'space-between', padding:'12px 16px'}}>
            <div style={{fontSize:13, color:'var(--text-muted)'}}>
              Showing <strong style={{color:'var(--text)'}}>{rows.length}</strong> rows · grouped by <strong style={{color:'var(--text)'}}>{schema.grouping}</strong> · sorted by <strong style={{color:'var(--text)'}}>{baseFields.find(f => f.id === schema.sortBy)?.label}</strong> ({schema.sortDir})
            </div>
            <div className="off-mono off-muted" style={{fontSize:11}}>Last edited {schema.lastEdited} by {schema.editedBy}</div>
          </div>

          <div className="off-table">
            <div className="off-grid" style={{gridTemplateColumns: schema.columns.map(() => "minmax(80px, 1fr)").join(" ")}}>
              {schema.columns.map(cid => {
                const f = baseFields.find(x => x.id === cid);
                return <div key={cid} className="off-grid-headcell" style={f && (f.type === "money" || f.type === "int" || f.type === "percent") ? {justifyContent:'flex-end'} : null}>{f?.label || cid}</div>;
              })}
              {rows.slice(0, 30).map((r, i) => (
                <div key={i} className="off-grid-row">
                  {schema.columns.map(cid => {
                    const f = baseFields.find(x => x.id === cid);
                    let val = r[cid];
                    if (cid === "supplier" && schema.base === "stock") val = findSup(r.supplier)?.name.split(" ")[0];
                    if (f?.type === "money")   val = oMoney(val || 0);
                    if (f?.type === "percent") val = (val || 0) + "%";
                    if (f?.type === "bool")    val = val ? "Yes" : "No";
                    return (
                      <div
                        key={cid}
                        className={"off-grid-cell" + (f && (f.type === "money" || f.type === "int" || f.type === "percent") ? " off-cell-num" : "") + (f && f.type === "text" && (cid === "name" || cid === "store") ? " off-cell-strong" : "")}
                      >
                        {val ?? "—"}
                      </div>
                    );
                  })}
                </div>
              ))}
            </div>
          </div>
        </div>
      </div>
    </div>
  );
}

// REPORT COLUMN SCHEMAS — admin can configure
function ReportSchemas() {
  const { pushToast } = window.useOffice();
  const [activeId, setActiveId] = oxUseState(OD.REPORT_SCHEMAS[0].id);
  const baseSchema = OD.REPORT_SCHEMAS.find(s => s.id === activeId);
  const [columns, setColumns] = oxUseState(baseSchema.columns);
  const fields = OD.COLUMN_FIELDS[baseSchema.base];

  React.useEffect(() => {
    const s = OD.REPORT_SCHEMAS.find(x => x.id === activeId);
    if (s) setColumns(s.columns);
  }, [activeId]);

  function toggle(fid) {
    setColumns(c => c.includes(fid) ? c.filter(x => x !== fid) : [...c, fid]);
  }
  function move(fid, dir) {
    const i = columns.indexOf(fid);
    if (i < 0) return;
    const j = i + dir;
    if (j < 0 || j >= columns.length) return;
    const next = [...columns];
    [next[i], next[j]] = [next[j], next[i]];
    setColumns(next);
  }

  // Group fields by their group attr
  const grouped = fields.reduce((acc, f) => {
    acc[f.group] = acc[f.group] || [];
    acc[f.group].push(f);
    return acc;
  }, {});

  return (
    <div className="off-screen">
      <header className="off-screen-header">
        <div className="off-screen-header-meta">
          <span className="off-screen-eyebrow">Reports · administration</span>
          <h2 className="off-screen-title">Report column definitions</h2>
        </div>
        <div className="off-screen-actions">
          <button className="btn btn--ghost btn--sm">Discard</button>
          <button className="btn btn--primary btn--sm" onClick={() => pushToast({kind:'paid', icon:'check-circle', title:'Schema saved', meta:`${columns.length} columns · applies to ${baseSchema.defaultFor.join(", ")}`})}>
            <OIcon name="check"/> Save schema
          </button>
        </div>
      </header>

      <div className="off-screen-body">
        <div style={{display:'grid', gridTemplateColumns:'220px 1fr', gap:14, marginBottom:14}}>
          <div>
            <div style={{fontSize:11, textTransform:'uppercase', letterSpacing:'0.06em', color:'var(--text-subtle)', fontWeight:500, marginBottom:8}}>Schemas</div>
            <div style={{display:'flex', flexDirection:'column', gap:2}}>
              {OD.REPORT_SCHEMAS.map(s => (
                <button
                  key={s.id}
                  onClick={() => setActiveId(s.id)}
                  style={{
                    padding:'9px 11px',
                    border:'1px solid ' + (activeId === s.id ? 'var(--brand-border)' : 'transparent'),
                    background: activeId === s.id ? 'var(--brand-bg)' : 'transparent',
                    color: activeId === s.id ? 'var(--brand)' : 'var(--text)',
                    fontFamily:'inherit',
                    borderRadius:7,
                    textAlign:'left',
                    cursor:'pointer',
                    fontSize:13,
                    fontWeight:500,
                  }}
                >
                  <div>{s.name}</div>
                  <div style={{fontSize:11, opacity:0.7, marginTop:1}}>{s.base} · {s.columns.length} cols</div>
                </button>
              ))}
            </div>
            <button className="btn btn--ghost btn--sm btn--block" style={{marginTop:8, justifyContent:'flex-start'}}>
              <OIcon name="plus"/> New schema
            </button>
          </div>

          <div className="off-card">
            <div className="off-card-header">
              <div>
                <h3 className="off-card-title">{baseSchema.name}</h3>
                <div className="off-card-meta">Base · <strong style={{color:'var(--text)'}}>{baseSchema.base}</strong> · Default for <strong style={{color:'var(--text)'}}>{baseSchema.defaultFor.join(", ")}</strong> roles</div>
              </div>
              <span className="badge badge--brand"><span className="badge-dot"/> Org schema</span>
            </div>
            <div style={{fontSize:13, color:'var(--text-muted)'}}>
              Defines which columns appear by default. Per-user picker lets staff hide columns locally without affecting the schema.
            </div>
          </div>
        </div>

        <div className="schema-grid">
          {/* Pool — available fields grouped */}
          <div className="schema-pool">
            <div className="schema-pool-head">
              <span>Available fields ({fields.length})</span>
              <span className="off-mono off-muted">Drag or click to add</span>
            </div>
            <div className="schema-pool-body">
              {Object.entries(grouped).map(([group, fields]) => (
                <div key={group} style={{marginBottom:14}}>
                  <div style={{fontSize:10, textTransform:'uppercase', letterSpacing:'0.06em', color:'var(--text-subtle)', fontWeight:500, padding:'6px 4px'}}>{group}</div>
                  <div style={{display:'flex', flexDirection:'column', gap:4}}>
                    {fields.map(f => {
                      const inSchema = columns.includes(f.id);
                      return (
                        <div key={f.id} className={"schema-field-pill" + (inSchema ? " schema-field-pill--selected" : "")} onClick={() => toggle(f.id)}>
                          <OIcon name={inSchema ? "check" : "plus"} width={12} height={12}/>
                          <span style={{flex:1}}>{f.label}</span>
                          <span className="schema-field-pill-type">{f.type}</span>
                        </div>
                      );
                    })}
                  </div>
                </div>
              ))}
            </div>
          </div>

          {/* Selected — ordered */}
          <div className="schema-pool">
            <div className="schema-pool-head">
              <span>Schema columns ({columns.length})</span>
              <span className="off-mono off-muted">Drag to reorder</span>
            </div>
            <div className="schema-pool-body">
              {columns.length === 0 && (
                <div style={{padding:'24px 12px', textAlign:'center', color:'var(--text-muted)', fontSize:13}}>
                  No columns yet. Click fields on the left to add.
                </div>
              )}
              {columns.map((cid, i) => {
                const f = fields.find(x => x.id === cid);
                if (!f) return null;
                return (
                  <div key={cid} className="schema-field-pill schema-field-pill--selected" style={{background:'var(--brand-bg)'}}>
                    <span style={{fontFamily:'var(--font-mono)', fontSize:11, color:'var(--text-subtle)'}}>{i + 1}.</span>
                    <span style={{flex:1, color:'var(--brand)'}}>{f.label}</span>
                    <span className="schema-field-pill-type">{f.type}</span>
                    <button className="btn btn--ghost btn--sm" style={{padding:'2px 4px', height:'auto'}} onClick={() => move(cid, -1)}><OIcon name="arrow-up" width={10} height={10}/></button>
                    <button className="btn btn--ghost btn--sm" style={{padding:'2px 4px', height:'auto'}} onClick={() => move(cid, 1)}><OIcon name="arrow-down" width={10} height={10}/></button>
                    <button className="btn btn--ghost btn--sm" style={{padding:'2px 4px', height:'auto', color:'var(--void)'}} onClick={() => toggle(cid)}><OIcon name="x" width={10} height={10}/></button>
                  </div>
                );
              })}
            </div>
          </div>
        </div>
      </div>
    </div>
  );
}

// =================================================================
// USERS & ROLES
// =================================================================
function Users() {
  const { pushToast } = window.useOffice();
  const [tab, setTab] = oxUseState("users");

  return (
    <div className="off-screen">
      <header className="off-screen-header">
        <div className="off-screen-header-meta">
          <span className="off-screen-eyebrow">Administration</span>
          <h2 className="off-screen-title">Users &amp; permissions</h2>
        </div>
        <div className="off-screen-actions">
          <button className="btn btn--primary btn--sm" onClick={() => pushToast({kind:'paid', icon:'plus', title:'Invite user', meta:'Invitation form would open here'})}>
            <OIcon name="plus"/> Invite user
          </button>
        </div>
      </header>

      <div className="off-subtabs">
        <button className={"off-subtab" + (tab === "users" ? " off-subtab--active" : "")} onClick={() => setTab("users")}>People ({OD.USERS.length})</button>
        <button className={"off-subtab" + (tab === "roles" ? " off-subtab--active" : "")} onClick={() => setTab("roles")}>Roles &amp; permissions</button>
        <button className={"off-subtab" + (tab === "audit" ? " off-subtab--active" : "")} onClick={() => setTab("audit")}>Access audit</button>
      </div>

      <div className="off-screen-body">
        {tab === "users" && (
          <div className="off-table">
            <div className="off-grid" style={{gridTemplateColumns:'40px 1.4fr 1fr 1fr 130px 100px 120px 80px'}}>
              <div className="off-grid-headcell"></div>
              <div className="off-grid-headcell">Name</div>
              <div className="off-grid-headcell">Email</div>
              <div className="off-grid-headcell">Role</div>
              <div className="off-grid-headcell">Stores</div>
              <div className="off-grid-headcell">2FA</div>
              <div className="off-grid-headcell">Last seen</div>
              <div className="off-grid-headcell">Status</div>
              {OD.USERS.map(u => (
                <div key={u.id} className="off-grid-row">
                  <div className="off-grid-cell"><div className="off-side-user-av" style={{width:28, height:28, background:'var(--brand)', color:'#fff'}}>{(u.first[0]+u.last[0]).toUpperCase()}</div></div>
                  <div className="off-grid-cell off-cell-strong">{u.first} {u.last}</div>
                  <div className="off-grid-cell off-cell-mono">{u.email}</div>
                  <div className="off-grid-cell">{u.role}</div>
                  <div className="off-grid-cell off-cell-mono">{u.stores[0] === "—" ? "Org-wide" : u.stores.map(id => findS(id)?.code).join(", ")}</div>
                  <div className="off-grid-cell">
                    {u.twoFA ? <span className="badge badge--paid"><span className="badge-dot"/> On</span> : <span className="badge badge--hold"><span className="badge-dot"/> Off</span>}
                  </div>
                  <div className="off-grid-cell off-cell-mono off-muted">{u.lastSeen}</div>
                  <div className="off-grid-cell">
                    {u.status === "active"  && <span className="badge badge--paid"><span className="badge-dot"/> Active</span>}
                    {u.status === "leave"   && <span className="badge badge--neutral"><span className="badge-dot"/> Leave</span>}
                    {u.status === "pending" && <span className="badge badge--hold"><span className="badge-dot"/> Pending</span>}
                  </div>
                </div>
              ))}
            </div>
          </div>
        )}

        {tab === "roles" && (
          <div className="off-table">
            <div className="off-grid" style={{gridTemplateColumns:'1.4fr 60px repeat(12, 1fr)'}}>
              <div className="off-grid-headcell">Role</div>
              <div className="off-grid-headcell" style={{justifyContent:'flex-end'}}>Users</div>
              {["Sell","Dispense","S8","Refund","Void","Receive","Count","Manage stock","Pricing","Reports","Users","Billing"].map(c => (
                <div key={c} className="off-grid-headcell" style={{justifyContent:'center', writingMode:'horizontal-tb'}}>{c}</div>
              ))}
              {OD.ROLES.map(r => (
                <div key={r.id} className="off-grid-row">
                  <div className="off-grid-cell off-cell-strong">
                    {r.name}
                    <div className="off-muted" style={{fontSize:11, fontWeight:400, marginTop:2}}>{r.description}</div>
                  </div>
                  <div className="off-grid-cell off-cell-num">{r.users}</div>
                  {["sell","dispense","s8","refund","void","receive","count","manageStock","pricing","reports","users","billing"].map(p => (
                    <div key={p} className="off-grid-cell" style={{justifyContent:'center', display:'flex'}}>
                      {r.perms[p] ? <OIcon name="check" width={14} height={14} style={{color:'var(--paid)'}}/> : <span style={{color:'var(--text-subtle)'}}>—</span>}
                    </div>
                  ))}
                </div>
              ))}
            </div>
          </div>
        )}

        {tab === "audit" && (
          <div className="off-empty" style={{padding:60, background:'var(--surface)', border:'1px dashed var(--border)', borderRadius:12}}>
            <div className="empty-icon"><OIcon name="info" width={22} height={22}/></div>
            <div style={{fontSize:16, fontWeight:600}}>Access audit</div>
            <div className="off-muted" style={{fontSize:13, textAlign:'center', maxWidth:'48ch'}}>Sign-ins, permission changes, password resets — all surfaced here. Filterable by user, action and store.</div>
          </div>
        )}
      </div>
    </div>
  );
}

// =================================================================
// SUPPLIERS
// =================================================================
function Suppliers() {
  return (
    <div className="off-screen">
      <header className="off-screen-header">
        <div className="off-screen-header-meta">
          <span className="off-screen-eyebrow">Administration</span>
          <h2 className="off-screen-title">Suppliers</h2>
        </div>
        <div className="off-screen-actions">
          <button className="btn btn--primary btn--sm"><OIcon name="plus"/> New supplier</button>
        </div>
      </header>

      <div className="off-screen-body">
        <div className="off-table">
          <div className="off-grid" style={{gridTemplateColumns:'1.4fr 1fr 100px 1fr 100px 130px 100px'}}>
            <div className="off-grid-headcell">Supplier</div>
            <div className="off-grid-headcell">Contact</div>
            <div className="off-grid-headcell">Terms</div>
            <div className="off-grid-headcell">Phone</div>
            <div className="off-grid-headcell" style={{justifyContent:'flex-end'}}>SKUs</div>
            <div className="off-grid-headcell">Last order</div>
            <div className="off-grid-headcell" style={{justifyContent:'flex-end'}}>Action</div>
            {OD.SUPPLIERS.map(s => {
              const skuCount = OD.PRODUCTS.filter(p => p.supplier === s.id).length;
              return (
                <div key={s.id} className="off-grid-row">
                  <div className="off-grid-cell off-cell-strong">
                    {s.name}
                    <div className="off-cell-mono off-muted" style={{marginTop:2}}>Account {s.account}</div>
                  </div>
                  <div className="off-grid-cell">{s.contact}</div>
                  <div className="off-grid-cell">
                    <span className="badge badge--neutral">{s.terms}</span>
                  </div>
                  <div className="off-grid-cell off-cell-mono">{s.phone}</div>
                  <div className="off-grid-cell off-cell-num off-cell-strong">{skuCount}</div>
                  <div className="off-grid-cell off-cell-mono off-muted">{s.lastOrder}</div>
                  <div className="off-grid-cell">
                    <button className="btn btn--ghost btn--sm">Open</button>
                  </div>
                </div>
              );
            })}
          </div>
        </div>
      </div>
    </div>
  );
}

// =================================================================
// SETTINGS (org level)
// =================================================================
function OfficeSettings() {
  const [section, setSection] = oxUseState("organisation");
  const SECTIONS = [
    { key: "organisation", label: "Organisation" },
    { key: "billing",      label: "Billing & plan" },
    { key: "integrations", label: "Integrations" },
    { key: "branding",     label: "Branding" },
    { key: "compliance",   label: "Compliance" },
    { key: "data",         label: "Data exports" },
    { key: "danger",       label: "Danger zone" },
  ];

  return (
    <div className="off-screen">
      <header className="off-screen-header">
        <div className="off-screen-header-meta">
          <span className="off-screen-eyebrow">Administration</span>
          <h2 className="off-screen-title">Settings</h2>
        </div>
      </header>

      <div className="off-screen-body">
        <div className="settings-grid">
          <div className="settings-nav">
            {SECTIONS.map(s => (
              <button key={s.key} className={section === s.key ? "active" : ""} onClick={() => setSection(s.key)}>{s.label}</button>
            ))}
          </div>

          <div className="settings-panel">
            {section === "organisation" && (
              <>
                <h3 style={{margin:'0 0 4px', fontSize:18, fontWeight:600, letterSpacing:'-0.01em'}}>Organisation</h3>
                <p style={{margin:'0 0 16px', fontSize:13, color:'var(--text-muted)'}}>Top-level group details.</p>
                <div className="settings-row">
                  <div><div className="settings-row-title">Group name</div><div className="settings-row-desc">Shown across receipts and statements.</div></div>
                  <input className="input" defaultValue={OD.ORG.name}/>
                </div>
                <div className="settings-row">
                  <div><div className="settings-row-title">ABN</div></div>
                  <input className="input tabular" defaultValue={OD.ORG.abn}/>
                </div>
                <div className="settings-row">
                  <div><div className="settings-row-title">Head office address</div></div>
                  <input className="input" defaultValue={OD.ORG.address}/>
                </div>
                <div className="settings-row">
                  <div><div className="settings-row-title">Default currency</div></div>
                  <select className="input select" defaultValue="AUD"><option>AUD</option><option>NZD</option></select>
                </div>
                <div className="settings-row">
                  <div><div className="settings-row-title">Time zone</div></div>
                  <select className="input select" defaultValue="AEST"><option>AEST · Melbourne</option><option>AEDT · Sydney</option><option>AWST · Perth</option></select>
                </div>
              </>
            )}

            {section === "billing" && (
              <>
                <h3 style={{margin:'0 0 4px', fontSize:18, fontWeight:600, letterSpacing:'-0.01em'}}>Plan</h3>
                <p style={{margin:'0 0 16px', fontSize:13, color:'var(--text-muted)'}}>Your CoreIQ subscription.</p>
                <div className="off-card" style={{flexDirection:'row', alignItems:'center', gap:18}}>
                  <div style={{width:48, height:48, borderRadius:12, background:'var(--brand)', color:'var(--brand-fg)', display:'grid', placeItems:'center', fontWeight:600, fontSize:20}}>G</div>
                  <div style={{flex:1}}>
                    <div style={{fontSize:18, fontWeight:600, letterSpacing:'-0.01em'}}>CoreIQ Group · 3 stores</div>
                    <div style={{fontSize:13, color:'var(--text-muted)'}}>$748/month · billed monthly · next on 01 Jun 2026</div>
                  </div>
                  <button className="btn btn--secondary btn--sm">Change plan</button>
                </div>
              </>
            )}

            {section === "integrations" && (
              <>
                <h3 style={{margin:'0 0 4px', fontSize:18, fontWeight:600, letterSpacing:'-0.01em'}}>Integrations</h3>
                <p style={{margin:'0 0 16px', fontSize:13, color:'var(--text-muted)'}}>Connected services.</p>
                {[
                  ["PBS Online Claiming",  "Connected · all stores",       "paid"],
                  ["Tyro Payments",        "Connected · Reg 02 paired",     "paid"],
                  ["Xero accounting",      "Connected · daily sync 22:00", "paid"],
                  ["MailChimp · marketing","Disconnected",                   "neutral"],
                  ["Healthbookings.com.au","Connected · same group",         "paid"],
                  ["SafeScript Victoria",  "Connected · S8 lookups live",    "paid"],
                ].map(([name, state, kind]) => (
                  <div key={name} className="settings-row" style={{gridTemplateColumns:'1fr auto'}}>
                    <div><div className="settings-row-title">{name}</div><div className="settings-row-desc">{state}</div></div>
                    <div style={{display:'flex', gap:8}}>
                      <span className={"badge badge--" + (kind === "paid" ? "paid" : "neutral")}><span className="badge-dot"/> {kind === "paid" ? "Live" : "Off"}</span>
                      <button className="btn btn--ghost btn--sm">Configure</button>
                    </div>
                  </div>
                ))}
              </>
            )}

            {!["organisation","billing","integrations"].includes(section) && (
              <div className="off-empty" style={{padding:60}}>
                <div className="empty-icon"><OIcon name="settings" width={20} height={20}/></div>
                <div style={{fontSize:16, fontWeight:600}}>{SECTIONS.find(s => s.key === section).label}</div>
                <div className="off-muted" style={{fontSize:13}}>Section scoped — not wired up in this preview.</div>
              </div>
            )}
          </div>
        </div>
      </div>
    </div>
  );
}

window.OFFICE_SCREENS = Object.assign(window.OFFICE_SCREENS || {}, {
  stores: Stores,
  storeDetail: StoreDetail,
  transfers: Transfers,
  reports: Reports,
  schemas: ReportSchemas,
  users: Users,
  suppliers: Suppliers,
  settings: OfficeSettings,
});
