/* ============================================================
   ELECTROMED — Shell: icons, primitives, sidebar, topbar
   Exposes everything on window for other module files.
   ============================================================ */
const { useState, useEffect, useRef, useMemo } = React;

/* ---------- Icons (simple line glyphs) ---------- */
const Ic = ({ d, size = 19, fill, stroke = 2, children, vb = 24 }) => (
  <svg width={size} height={size} viewBox={`0 0 ${vb} ${vb}`} fill={fill || 'none'}
       stroke={fill ? 'none' : 'currentColor'} strokeWidth={stroke}
       strokeLinecap="round" strokeLinejoin="round">
    {d ? <path d={d} /> : children}
  </svg>
);
const Icons = {
  dash:   (p) => <Ic {...p}><rect x="3" y="3" width="7" height="7" rx="2"/><rect x="14" y="3" width="7" height="7" rx="2"/><rect x="3" y="14" width="7" height="7" rx="2"/><rect x="14" y="14" width="7" height="7" rx="2"/></Ic>,
  crm:    (p) => <Ic {...p}><circle cx="9" cy="8" r="3.2"/><path d="M3.5 20a5.5 5.5 0 0 1 11 0"/><path d="M16 6.5a3 3 0 0 1 0 5.8"/><path d="M17.5 20a5 5 0 0 0-3-4.6"/></Ic>,
  sales:  (p) => <Ic {...p}><path d="M5 7h14l-1.2 9.2a2 2 0 0 1-2 1.8H8.2a2 2 0 0 1-2-1.8L5 7Z"/><path d="M8.5 7V5.5a3.5 3.5 0 0 1 7 0V7"/></Ic>,
  rental: (p) => <Ic {...p}><path d="M3 9.5 12 4l9 5.5"/><path d="M5 8.8V19a1 1 0 0 0 1 1h12a1 1 0 0 0 1-1V8.8"/><path d="M9.5 20v-5h5v5"/></Ic>,
  wrench: (p) => <Ic {...p}><path d="M14.7 6.3a4 4 0 0 0-5.2 5.2l-5.9 5.9a1.8 1.8 0 0 0 2.5 2.5l5.9-5.9a4 4 0 0 0 5.2-5.2l-2.4 2.4-2.1-.3-.3-2.1 2.3-2.5Z"/></Ic>,
  box:    (p) => <Ic {...p}><path d="m3.5 7.5 8.5-4 8.5 4-8.5 4-8.5-4Z"/><path d="M3.5 7.5v9l8.5 4 8.5-4v-9"/><path d="M12 11.5v9"/></Ic>,
  pay:    (p) => <Ic {...p}><rect x="3" y="5.5" width="18" height="13" rx="2.5"/><path d="M3 9.5h18"/><path d="M7 14.5h4"/></Ic>,
  bell:   (p) => <Ic {...p}><path d="M6 9a6 6 0 0 1 12 0c0 5 2 6 2 6H4s2-1 2-6Z"/><path d="M10 20a2.2 2.2 0 0 0 4 0"/></Ic>,
  chart:  (p) => <Ic {...p}><path d="M4 20V10"/><path d="M10 20V4"/><path d="M16 20v-7"/><path d="M21 20H3"/></Ic>,
  search: (p) => <Ic {...p}><circle cx="11" cy="11" r="7"/><path d="m20 20-3.2-3.2"/></Ic>,
  gear:   (p) => <Ic {...p}><circle cx="12" cy="12" r="3.2"/><path d="M12 2.5v3M12 18.5v3M21.5 12h-3M5.5 12h-3M18.4 5.6l-2.1 2.1M7.7 16.3l-2.1 2.1M18.4 18.4l-2.1-2.1M7.7 7.7 5.6 5.6"/></Ic>,
  help:   (p) => <Ic {...p}><circle cx="12" cy="12" r="9"/><path d="M9.5 9.5a2.5 2.5 0 0 1 4.5 1.5c0 1.5-2 2-2 3"/><path d="M12 17h.01"/></Ic>,
  logout: (p) => <Ic {...p}><path d="M15 4h3a1 1 0 0 1 1 1v14a1 1 0 0 1-1 1h-3"/><path d="M10 12h9"/><path d="m13 8 4 4-4 4"/></Ic>,
  plus:   (p) => <Ic {...p}><path d="M12 5v14M5 12h14"/></Ic>,
  filter: (p) => <Ic {...p}><path d="M3 5h18M6 12h12M10 19h4"/></Ic>,
  chevD:  (p) => <Ic {...p}><path d="m6 9 6 6 6-6"/></Ic>,
  chevR:  (p) => <Ic {...p}><path d="m9 6 6 6-6 6"/></Ic>,
  arrowUp:(p) => <Ic {...p}><path d="M12 19V5M6 11l6-6 6 6"/></Ic>,
  arrowDn:(p) => <Ic {...p}><path d="M12 5v14M6 13l6 6 6-6"/></Ic>,
  swap:   (p) => <Ic {...p}><path d="M7 4 3 8l4 4"/><path d="M3 8h13a4 4 0 0 1 0 8h-1"/><path d="m17 20 4-4-4-4"/></Ic>,
  x:      (p) => <Ic {...p}><path d="M6 6l12 12M18 6 6 18"/></Ic>,
  check:  (p) => <Ic {...p}><path d="m5 12 4.5 4.5L19 7"/></Ic>,
  dots:   (p) => <Ic {...p}><circle cx="5" cy="12" r="1.6" fill="currentColor" stroke="none"/><circle cx="12" cy="12" r="1.6" fill="currentColor" stroke="none"/><circle cx="19" cy="12" r="1.6" fill="currentColor" stroke="none"/></Ic>,
  doc:    (p) => <Ic {...p}><path d="M6 3h8l4 4v14a1 1 0 0 1-1 1H6a1 1 0 0 1-1-1V4a1 1 0 0 1 1-1Z"/><path d="M14 3v4h4"/></Ic>,
  phone:  (p) => <Ic {...p}><path d="M5 4h3l1.5 4-2 1.5a11 11 0 0 0 5 5l1.5-2 4 1.5v3a2 2 0 0 1-2 2A15 15 0 0 1 3 6a2 2 0 0 1 2-2Z"/></Ic>,
  pin:    (p) => <Ic {...p}><path d="M12 21s-6-5.3-6-10a6 6 0 0 1 12 0c0 4.7-6 10-6 10Z"/><circle cx="12" cy="11" r="2.2"/></Ic>,
  cal:    (p) => <Ic {...p}><rect x="3.5" y="5" width="17" height="16" rx="2.5"/><path d="M3.5 9.5h17M8 3v4M16 3v4"/></Ic>,
  truck:  (p) => <Ic {...p}><path d="M3 6.5h11v9H3z"/><path d="M14 9.5h4l3 3v3h-7z"/><circle cx="7" cy="18" r="1.8"/><circle cx="17.5" cy="18" r="1.8"/></Ic>,
  shield: (p) => <Ic {...p}><path d="M12 3 5 6v5c0 4.5 3 8 7 10 4-2 7-5.5 7-10V6l-7-3Z"/></Ic>,
  clock:  (p) => <Ic {...p}><circle cx="12" cy="12" r="8.5"/><path d="M12 7.5V12l3 2"/></Ic>,
  o2:     (p) => <Ic {...p}><circle cx="12" cy="12" r="8.5"/><path d="M12 8v8M8 12h8" stroke="currentColor"/></Ic>,
  print:  (p) => <Ic {...p}><path d="M7 8V3h10v5"/><rect x="4.5" y="8" width="15" height="8" rx="1.5"/><path d="M7 14h10v6H7z"/></Ic>,
  download:(p)=> <Ic {...p}><path d="M12 4v11M7 11l5 5 5-5"/><path d="M5 20h14"/></Ic>,
  spark:  (p) => <Ic {...p}><path d="M12 3v4M12 17v4M3 12h4M17 12h4"/></Ic>,
  moon:   (p) => <Ic {...p}><path d="M20 14.5A8 8 0 1 1 9.5 4a6.5 6.5 0 0 0 10.5 10.5Z"/></Ic>,
  building:(p)=> <Ic {...p}><path d="M4 21V5a1 1 0 0 1 1-1h9a1 1 0 0 1 1 1v16"/><path d="M15 9h4a1 1 0 0 1 1 1v11"/><path d="M3 21h18M8 8h3M8 12h3M8 16h3"/></Ic>,
  percent:(p) => <Ic {...p}><path d="M19 5 5 19"/><circle cx="7.5" cy="7.5" r="2.5"/><circle cx="16.5" cy="16.5" r="2.5"/></Ic>,
  users:  (p) => <Ic {...p}><circle cx="8" cy="8" r="3"/><path d="M2.5 20a5.5 5.5 0 0 1 11 0"/><path d="M16 5.5a3 3 0 0 1 0 5.8M21.5 20a5.2 5.2 0 0 0-3.5-4.8"/></Ic>,
  receipt:(p) => <Ic {...p}><path d="M5 3v18l2-1.4L9 21l2-1.4L13 21l2-1.4L17 21l2-1.4V3l-2 1.4L15 3l-2 1.4L11 3 9 4.4 7 3Z"/><path d="M8.5 8.5h7M8.5 12h7M8.5 15.5h4"/></Ic>,
  list:   (p) => <Ic {...p}><path d="M8 6h13M8 12h13M8 18h13M3.5 6h.01M3.5 12h.01M3.5 18h.01"/></Ic>,
  user:   (p) => <Ic {...p}><circle cx="12" cy="8" r="3.4"/><path d="M5.5 20a6.5 6.5 0 0 1 13 0"/></Ic>,
  bolt:   (p) => <Ic {...p}><path d="M13 3 4 14h6l-1 7 9-11h-6l1-7Z"/></Ic>,
  trash:  (p) => <Ic {...p}><path d="M4 7h16M9 7V4h6v3M10 12v5M14 12v5M5 7l1 13h12L19 7"/></Ic>,
  undo:   (p) => <Ic {...p}><path d="M3 10h13a5 5 0 0 1 0 10H7"/><path d="m7 6-4 4 4 4"/></Ic>,
};

/* ---------- Primitives ---------- */
const cls = (...a) => a.filter(Boolean).join(' ');

function Badge({ kind = 'idle', children }) {
  const map = {
    ok: ['var(--ok)', 'var(--ok-bg)'], warn: ['var(--warn)', 'var(--warn-bg)'],
    info: ['var(--info)', 'var(--info-bg)'], bad: ['var(--bad)', 'var(--bad-bg)'],
    idle: ['var(--idle)', 'var(--idle-bg)'],
  };
  const [c, bg] = map[kind] || map.idle;
  return <span className="badge" style={{ color: c, background: bg }}>
    <span className="dot" style={{ background: c }} />{children}
  </span>;
}
window.statusKind = (s) => ({
  Paid: 'ok', Active: 'ok', Closed: 'idle', Completed: 'ok', Partial: 'warn',
  'Due Soon': 'warn', Pending: 'warn', Unpaid: 'bad', Overdue: 'bad',
  Diagnosing: 'info', 'In Repair': 'info', 'Awaiting Parts': 'warn', Billed: 'ok',
  Inactive: 'idle',
  Sent: 'info', Accepted: 'ok', Draft: 'idle', Expired: 'bad', Converted: 'ok',
  Scheduled: 'info', 'In Progress': 'info', Reported: 'ok',
  'In Transit': 'warn', 'On Consignment': 'warn', Received: 'ok', Delivered: 'ok',
  Approved: 'ok', Reclassified: 'info',
}[s] || 'idle');

function Avatar({ init, src, size = 36, ring }) {
  return src
    ? <img className="avatar" src={src} style={{ width: size, height: size }} />
    : <div className="avatar" style={{ width: size, height: size, fontSize: size * .38, border: ring ? '2px solid var(--lime)' : 'none' }}>{init}</div>;
}

function Btn({ variant = 'ghost', sm, icon, children, ...rest }) {
  return <button className={cls('btn', `btn-${variant}`, sm && 'btn-sm')} {...rest}>
    {icon}{children}
  </button>;
}

function Delta({ v }) {
  const up = v >= 0;
  return <span className={cls('delta', up ? 'up' : 'down')}>
    {up ? <Icons.arrowUp size={12} stroke={2.6} /> : <Icons.arrowDn size={12} stroke={2.6} />}{Math.abs(v)}%
  </span>;
}

function StatCard({ icon, label, value, delta, sub, accent }) {
  return (
    <div className="stat" style={accent ? { background: 'var(--grad-green)', border: 'none', color: '#fff' } : null}>
      <div className="stat-top">
        <span className="stat-label" style={accent ? { color: 'rgba(255,255,255,.8)' } : null}>{label}</span>
        <span className="stat-ic" style={accent ? { background: 'rgba(255,255,255,.14)', color: 'var(--lime)' } : null}>{icon}</span>
      </div>
      <div className="stat-val" style={accent ? { color: '#fff' } : null}>{value}</div>
      <div className="row" style={{ gap: 8, marginTop: 8 }}>
        {delta != null && <Delta v={delta} />}
        {sub && <span className="tiny" style={{ color: accent ? 'rgba(255,255,255,.7)' : 'var(--ink-3)' }}>{sub}</span>}
      </div>
    </div>
  );
}

function Modal({ title, sub, onClose, children, foot, wide }) {
  useEffect(() => {
    const h = (e) => e.key === 'Escape' && onClose();
    window.addEventListener('keydown', h);
    return () => window.removeEventListener('keydown', h);
  }, []);
  const node = (
    <div className="scrim" onMouseDown={onClose}>
      <div className="modal" style={wide ? { maxWidth: 720 } : null} onMouseDown={(e) => e.stopPropagation()}>
        <div className="modal-head">
          <div>
            <div style={{ fontSize: 18, fontWeight: 800, letterSpacing: '-.02em' }}>{title}</div>
            {sub && <div className="tiny muted" style={{ marginTop: 4 }}>{sub}</div>}
          </div>
          <button className="btn-icon" style={{ color: 'var(--ink-2)' }} onClick={onClose}><Icons.x size={20} /></button>
        </div>
        <div className="modal-body">{children}</div>
        {foot && <div className="modal-foot">{foot}</div>}
      </div>
    </div>
  );
  // Portal to <body> so the fixed overlay covers the full viewport, regardless
  // of any transformed/overflow ancestor (e.g. the animated page wrapper).
  return (window.ReactDOM && window.ReactDOM.createPortal)
    ? window.ReactDOM.createPortal(node, document.body)
    : node;
}

/* ============================================================
   ConfirmDeleteModal — reusable destructive action confirmation.
   Usage: <ConfirmDeleteModal title="Delete X?" body={<>…</>}
            onCancel={fn} onConfirm={async fn} />
   ============================================================ */
function ConfirmDeleteModal({ title, body, onCancel, onConfirm, confirmLabel = 'Delete' }) {
  const [busy, setBusy] = useState(false);
  const run = async () => {
    setBusy(true);
    try { await onConfirm(); } finally { setBusy(false); }
  };
  return (
    <Modal title={title} onClose={onCancel}
      foot={<>
        <Btn variant="ghost" onClick={onCancel} disabled={busy}>Cancel</Btn>
        <Btn variant="danger" onClick={run} disabled={busy}>{busy ? 'Deleting…' : confirmLabel}</Btn>
      </>}>
      <div style={{ padding: '4px 0', lineHeight: 1.6 }}>{body}</div>
    </Modal>
  );
}
window.ConfirmDeleteModal = ConfirmDeleteModal;

/* ============================================================
   WaSendBtn — manual "Send via WhatsApp" for any document.
   Usage: <WaSendBtn docType="Invoice" docId={inv.id} />
   Sends the branch template (+ PDF for invoices) on demand; the
   result is recorded in Settings → Message Logs.
   ============================================================ */
function WaSendBtn({ docType, docId, label = 'Send via WhatsApp', sm, variant = 'ghost', onClick }) {
  const [busy, setBusy] = useState(false);
  const send = async (e) => {
    if (e) e.stopPropagation();
    if (busy) return;
    setBusy(true);
    try {
      await api.whatsappSendDoc(docType, docId);
      window.toast('WhatsApp message sent', 'ok');
      if (onClick) onClick();
    } catch (err) {
      window.toast(err.message || 'Could not send — is WhatsApp connected?', 'error');
    } finally { setBusy(false); }
  };
  return (
    <Btn variant={variant} sm={sm} disabled={busy} onClick={send}
      icon={<svg width="15" height="15" viewBox="0 0 32 32" fill="currentColor" aria-hidden="true"><path d="M16 5.3C10.6 5.3 6.3 9.6 6.3 15c0 1.9.6 3.7 1.5 5.2l-1 3.6 3.7-1c1.5.8 3.1 1.2 4.5 1.2 5.4 0 9.7-4.3 9.7-9.7S21.4 5.3 16 5.3zm5.7 13.7c-.2.7-1.4 1.3-2 1.4-.5.1-1.2.1-1.9-.1-.4-.1-1-.3-1.8-.6-3.1-1.3-5.1-4.4-5.3-4.6-.2-.2-1.3-1.7-1.3-3.2s.8-2.3 1.1-2.6c.3-.3.6-.4.8-.4h.6c.2 0 .5-.1.7.5l.9 2.1c.1.2.1.4 0 .6l-.4.6c-.2.2-.4.4-.2.7.2.4.9 1.4 1.9 2.3 1.3 1.1 2.3 1.5 2.7 1.6.3.1.5.1.7-.1l.8-1c.2-.3.5-.2.7-.1l2 1c.3.1.5.2.5.3.1.2.1.8-.1 1.5z" /></svg>}>
      {busy ? 'Sending…' : label}
    </Btn>
  );
}
window.WaSendBtn = WaSendBtn;

/* ============================================================
   Print / PDF — clone a document node into #print-mount and print.
   The browser's print dialog provides "Save as PDF" for download.
   Usage: const ref = useRef(); attach to the document container;
   <Btn onClick={() => printDocument(ref.current)}>Print</Btn>
   ============================================================ */
function printDocument(node) {
  if (!node) return;
  const mount = document.getElementById('print-mount');
  if (!mount) { window.print(); return; }
  mount.innerHTML = '';
  const clone = node.cloneNode(true);
  clone.classList.add('print-sheet');
  mount.appendChild(clone);
  document.body.classList.add('printing');
  const done = () => {
    document.body.classList.remove('printing');
    mount.innerHTML = '';
    window.removeEventListener('afterprint', done);
  };
  window.addEventListener('afterprint', done);
  setTimeout(() => { window.print(); setTimeout(done, 800); }, 60);
}
window.printDocument = printDocument;

function SearchBox({ value, onChange, placeholder = 'Search…', w }) {
  return (
    <div className="field" style={{ width: w }}>
      <Icons.search size={17} stroke={2.2} style={{ color: 'var(--ink-3)' }} />
      <input value={value} onChange={(e) => onChange(e.target.value)} placeholder={placeholder} />
    </div>
  );
}

function Tabs({ tabs, value, onChange }) {
  return (
    <div className="tabs">
      {tabs.map((t) => (
        <button key={t} className={cls('tab', value === t && 'active')} onClick={() => onChange(t)}>{t}</button>
      ))}
    </div>
  );
}

function PageHead({ eyebrow, title, sub, actions }) {
  return (
    <div className="page-head">
      <div>
        {eyebrow && <div className="eyebrow" style={{ marginBottom: 8 }}>{eyebrow}</div>}
        <h1 className="page-title">{title}</h1>
        {sub && <div className="page-sub">{sub}</div>}
      </div>
      {actions && <div className="row" style={{ gap: 10, flexWrap: 'wrap' }}>{actions}</div>}
    </div>
  );
}

/* Lightweight bar chart (grouped or single) */
function BarChart({ data, keys, colors, height = 220, maxTicks = 5, fmt = (v) => v }) {
  const max = Math.max(...data.flatMap((d) => keys.map((k) => d[k]))) * 1.1;
  const ticks = Array.from({ length: maxTicks + 1 }, (_, i) => Math.round((max / maxTicks) * (maxTicks - i)));
  return (
    <div style={{ display: 'flex', gap: 12 }}>
      <div style={{ display: 'flex', flexDirection: 'column', justifyContent: 'space-between', height, fontSize: 11, color: 'var(--ink-3)', fontWeight: 600, textAlign: 'right' }}>
        {ticks.map((t) => <span key={t}>{fmt(t)}</span>)}
      </div>
      <div style={{ flex: 1, position: 'relative' }}>
        <div style={{ position: 'absolute', inset: 0, display: 'flex', flexDirection: 'column', justifyContent: 'space-between' }}>
          {ticks.map((t, i) => <div key={i} style={{ borderTop: '1px dashed var(--line-2)' }} />)}
        </div>
        <div style={{ position: 'relative', height, display: 'flex', alignItems: 'flex-end', justifyContent: 'space-around', gap: 8 }}>
          {data.map((d, i) => (
            <div key={i} style={{ display: 'flex', flexDirection: 'column', alignItems: 'center', flex: 1 }}>
              <div style={{ display: 'flex', alignItems: 'flex-end', gap: 4, height, width: '100%', justifyContent: 'center' }}>
                {keys.map((k, ki) => (
                  <div key={k} title={fmt(d[k])} style={{
                    width: keys.length > 1 ? `${56 / keys.length}%` : '58%',
                    maxWidth: 34,
                    height: `${(d[k] / max) * 100}%`,
                    background: colors[ki], borderRadius: '7px 7px 4px 4px',
                    transition: 'height .5s cubic-bezier(.2,.8,.3,1)',
                  }} />
                ))}
              </div>
              <span style={{ fontSize: 11.5, color: 'var(--ink-3)', fontWeight: 600, marginTop: 8 }}>{d.m || d.label}</span>
            </div>
          ))}
        </div>
      </div>
    </div>
  );
}

/* ---------- Sidebar ---------- */
const NAV = [
  { id: 'dashboard',     label: 'Dashboard',     icon: Icons.dash,   group: 'Overview',    perm: 'dashboard' },
  { id: 'crm',           label: 'Customer CRM',  icon: Icons.crm,    group: 'Operations',  perm: 'customers' },
  { id: 'sales',         label: 'Sales',         icon: Icons.sales,  group: 'Operations',  perm: 'sales' },
  { id: 'rentals',       label: 'Rentals',       icon: Icons.rental, group: 'Operations',  perm: 'rentals' },
  { id: 'workshop',      label: 'Workshop',      icon: Icons.wrench, group: 'Operations',  perm: 'workshop',  badge: '4' },
  { id: 'inventory',     label: 'Inventory',     icon: Icons.box,    group: 'Operations',  perm: 'inventory' },
  { id: 'payments',      label: 'Payments',      icon: Icons.pay,    group: 'Finance',     perm: 'payments' },
  { id: 'reports',       label: 'Reports',       icon: Icons.chart,  group: 'Finance',     perm: 'reports' },
  { id: 'notifications', label: 'Notifications', icon: Icons.bell,   group: 'System', perm: 'settings' },
];

function Sidebar({ route, go }) {
  const D = window.DATA;
  const visible = NAV.filter(n => !n.perm || window.can(n.perm, 'view'));
  const groups = [...new Set(visible.map((n) => n.group))];
  return (
    <aside className="sidebar">
      <div className="brand">
        <div className="brand-mark">
          <svg width="22" height="22" viewBox="0 0 24 24" fill="none" stroke="var(--lime)" strokeWidth="2.2" strokeLinecap="round" strokeLinejoin="round">
            <path d="M2 12h4l2-6 4 13 3-9 2 2h5" />
          </svg>
        </div>
        <div>
          <div className="brand-name">Electromed</div>
          <div className="brand-sub">RESPIRATORY · SLEEP CARE</div>
        </div>
      </div>

      <div style={{ flex: 1, overflowY: 'auto', margin: '0 -6px', padding: '0 6px' }}>
        {groups.map((g) => (
          <div key={g}>
            <div className="nav-label">{g}</div>
            {visible.filter((n) => n.group === g).map((n) => (
              <button key={n.id} className={cls('nav-item', route === n.id && 'active')} onClick={() => go(n.id)}>
                <n.icon className="nav-ic" />
                {n.label}
                {n.badge && <span className="nav-badge">{n.badge}</span>}
              </button>
            ))}
          </div>
        ))}
      </div>

      <div style={{ borderTop: '1px solid var(--line)', paddingTop: 12, marginTop: 6 }}>
        {window.can('settings','view') && <button className={cls('nav-item', route === 'settings' && 'active')} onClick={() => go('settings')}><Icons.gear className="nav-ic" />Settings</button>}
        <button className={cls('nav-item', route === 'help' && 'active')} onClick={() => go('help')}><Icons.help className="nav-ic" />Help & Support</button>
      </div>
    </aside>
  );
}

/* ---------- Topbar ---------- */
function Topbar({ route, go, branch, setBranch, currentUser }) {
  const [openBranch, setOpenBranch] = useState(false);
  const [openUser,   setOpenUser]   = useState(false);
  const [branches,   setBranches]   = useState([]);
  const branchRef = useRef(null);
  const userRef   = useRef(null);

  // Load real branches from API once
  useEffect(() => {
    api.getBranches()
      .then(r => setBranches(Array.isArray(r) ? r : (r.branches || [])))
      .catch(() => {});
  }, []);

  // Close dropdowns on outside click
  useEffect(() => {
    const handler = (e) => {
      if (branchRef.current && !branchRef.current.contains(e.target)) setOpenBranch(false);
      if (userRef.current   && !userRef.current.contains(e.target))   setOpenUser(false);
    };
    document.addEventListener('mousedown', handler);
    return () => document.removeEventListener('mousedown', handler);
  }, []);

  // Resolve logged-in user: prop → localStorage → static fallback
  const u = currentUser || (() => {
    try { return JSON.parse(localStorage.getItem('currentUser') || 'null'); } catch { return null; }
  })() || window.DATA.company.user;

  const initials = u.init || (u.name || 'U').split(' ').map(n => n[0]).join('').toUpperCase().slice(0, 2);
  const displayRole = u.display_role || u.role || '';

  // Only true super-admins/admins may switch branches; everyone else is locked
  // to their own branch (role-based — never trust a missing permissions field).
  const canSwitchBranch = api.isSuperAdmin();

  const title = (NAV.find((n) => n.id === route) || {}).label || { settings: 'Settings', help: 'Help & Support' }[route] || 'Dashboard';
  const lockedBranchName = branches.find(b => String(b.id) === String(u.branch_id))?.name || u.branch_name || u.branch || 'Your branch';
  const activeBranchLabel = !canSwitchBranch
    ? lockedBranchName
    : (branch === 'All' ? 'All Branches' : (branches.find(b => String(b.id) === String(branch))?.name || branch));

  return (
    <header className="topbar">
      <div className="row" style={{ gap: 12 }}>
        <span style={{ fontWeight: 800, fontSize: 16, letterSpacing: '-.02em' }}>{title}</span>
        <span className="tiny muted" style={{ borderLeft: '1px solid var(--line)', paddingLeft: 12 }}>
          {new Date().toLocaleDateString('en-GB', { weekday: 'long', day: 'numeric', month: 'long', year: 'numeric' })}
        </span>
      </div>
      <div className="grow" />
      <SearchBox value="" onChange={() => {}} placeholder="Search customers, invoices, serials…" w={300} />

      {/* Branch selector — admins can switch, others are locked to their branch */}
      <div ref={branchRef} style={{ position: 'relative' }}>
        <button className="btn btn-ghost btn-sm"
          onClick={canSwitchBranch ? () => setOpenBranch((v) => !v) : undefined}
          style={{ cursor: canSwitchBranch ? 'pointer' : 'default', opacity: canSwitchBranch ? 1 : 0.85 }}
          title={canSwitchBranch ? 'Switch branch' : 'Access limited to your branch'}>
          <Icons.pin size={15} stroke={2.2} style={{ color: 'var(--lime-700)' }} />
          {activeBranchLabel}
          {canSwitchBranch && <Icons.chevD size={14} />}
        </button>
        {openBranch && canSwitchBranch && (
          <div style={{ position: 'absolute', right: 0, top: 'calc(100% + 8px)', background: '#fff', border: '1px solid var(--line)', borderRadius: 14, boxShadow: 'var(--sh-lg)', padding: 6, width: 210, zIndex: 40 }}>
            {[{ id: 'All', name: 'All Branches' }, ...branches].map((b) => (
              <button key={b.id} className="nav-item" style={{ fontWeight: String(branch) === String(b.id) ? 700 : 600 }}
                onClick={() => { setBranch(b.id); setOpenBranch(false); }}>
                <Icons.pin className="nav-ic" size={16} />{b.name || b.label}
                {String(branch) === String(b.id) && <Icons.check size={16} style={{ marginLeft: 'auto', color: 'var(--lime-700)' }} />}
              </button>
            ))}
          </div>
        )}
      </div>

      <button className="btn-icon btn-ghost" style={{ position: 'relative' }} onClick={() => go('notifications')}>
        <Icons.bell size={19} stroke={2} />
        <span style={{ position: 'absolute', top: 7, right: 7, width: 8, height: 8, borderRadius: 9, background: 'var(--bad)', border: '2px solid #fff' }} />
      </button>

      {/* User menu */}
      <div ref={userRef} className="row" style={{ gap: 10, paddingLeft: 6, borderLeft: '1px solid var(--line)', position: 'relative' }}>
        <button className="row" style={{ gap: 10, background: 'none', border: 'none', cursor: 'pointer', padding: 0 }} onClick={() => setOpenUser((v) => !v)}>
          <div style={{ width: 38, height: 38, borderRadius: 50, background: 'var(--grad-green)', color: 'var(--lime)', display: 'grid', placeItems: 'center', fontWeight: 800, fontSize: 14 }}>{initials}</div>
          <div style={{ lineHeight: 1.2, textAlign: 'left' }}>
            <div style={{ fontWeight: 700, fontSize: 13.5 }}>{u.name}</div>
            <div className="tiny muted">{displayRole}</div>
          </div>
          <Icons.chevD size={15} style={{ color: 'var(--ink-3)' }} />
        </button>
        {openUser && (
          <div style={{ position: 'absolute', right: 0, top: 'calc(100% + 10px)', background: '#fff', border: '1px solid var(--line)', borderRadius: 14, boxShadow: 'var(--sh-lg)', padding: 6, width: 200, zIndex: 40 }}>
            <div style={{ padding: '8px 12px 10px', borderBottom: '1px solid var(--line)', marginBottom: 4 }}>
              <div style={{ fontWeight: 700, fontSize: 13 }}>{u.name}</div>
              <div className="tiny muted">{u.email}</div>
              <div className="tiny" style={{ color: 'var(--lime-700)', fontWeight: 700, marginTop: 2 }}>{displayRole}</div>
            </div>
            <button className="nav-item" onClick={() => { setOpenUser(false); go('settings'); }}><Icons.gear className="nav-ic" size={16} />Settings</button>
            <button className="nav-item" onClick={() => { setOpenUser(false); go('help'); }}><Icons.help className="nav-ic" size={16} />Help &amp; Support</button>
            <div style={{ height: 1, background: 'var(--line)', margin: '5px 8px' }} />
            <button className="nav-item" style={{ color: 'var(--bad)' }} onClick={() => window.__logout && window.__logout()}><Icons.logout className="nav-ic" size={16} style={{ color: 'var(--bad)' }} />Sign out</button>
          </div>
        )}
      </div>
    </header>
  );
}

/* ============================================================
   Global Toast notification system
   Call from anywhere: window.toast('Message', 'ok' | 'error' | 'warn')
   ============================================================ */
let _toastSetter = null;

window.toast = (msg, type = 'ok') => {
  if (!_toastSetter) { console.warn('[toast]', type, msg); return; }
  const id = Date.now() + Math.random();
  _toastSetter(prev => [...prev, { id, msg, type }]);
  setTimeout(() => _toastSetter(prev => prev.filter(t => t.id !== id)), 4200);
};

function ToastContainer() {
  const [toasts, setToasts] = useState([]);
  useEffect(() => {
    _toastSetter = setToasts;
    return () => { if (_toastSetter === setToasts) _toastSetter = null; };
  }, []);
  if (!toasts.length) return null;
  return (
    <div style={{ position: 'fixed', bottom: 24, right: 24, zIndex: 99999, display: 'flex', flexDirection: 'column-reverse', gap: 10, maxWidth: 400, pointerEvents: 'none' }}>
      {toasts.map(t => {
        const isErr = t.type === 'error', isWarn = t.type === 'warn';
        const bg  = isErr ? '#2a1215' : isWarn ? '#2a2110' : '#111f11';
        const bdr = isErr ? '#6b1a22' : isWarn ? '#6b4f1a' : '#1e4d1a';
        const icon = isErr ? '✕' : isWarn ? '⚠' : '✓';
        const col  = isErr ? 'var(--bad)' : isWarn ? 'var(--warn)' : 'var(--ok)';
        return (
          <div key={t.id} style={{ padding: '12px 16px', borderRadius: 14, background: bg, color: '#fff', fontSize: 14, fontWeight: 600, boxShadow: '0 8px 32px rgba(0,0,0,.45)', border: `1px solid ${bdr}`, display: 'flex', alignItems: 'center', gap: 12, pointerEvents: 'auto' }}>
            <span style={{ width: 22, height: 22, borderRadius: '50%', display: 'grid', placeItems: 'center', fontSize: 13, flexShrink: 0, color: col, border: `1.5px solid ${col}` }}>{icon}</span>
            <span style={{ lineHeight: 1.45 }}>{t.msg}</span>
          </div>
        );
      })}
    </div>
  );
}

Object.assign(window, {
  React, useState, useEffect, useRef, useMemo,
  Ic, Icons, cls, Badge, Avatar, Btn, Delta, StatCard, Modal,
  SearchBox, Tabs, PageHead, BarChart, Sidebar, Topbar, NAV,
  ToastContainer,
});
