// Shell — sidebar, top bar (with Locations dropdown), page header

const Icon = ({ name, size = 20, stroke = 1.6, className = '', style }) => {
  const common = { width: size, height: size, viewBox: '0 0 24 24', fill: 'none', stroke: 'currentColor', strokeWidth: stroke, strokeLinecap: 'round', strokeLinejoin: 'round', className, style };
  switch (name) {
    case 'home':       return <svg {...common}><path d="M3 11l9-7 9 7v9a2 2 0 0 1-2 2h-4v-7H9v7H5a2 2 0 0 1-2-2z"/></svg>;
    case 'users':      return <svg {...common}><circle cx="9" cy="8" r="3.5"/><path d="M2 20a7 7 0 0 1 14 0"/><circle cx="17" cy="9" r="2.8"/><path d="M22 19a5 5 0 0 0-7-4.6"/></svg>;
    case 'calendar':   return <svg {...common}><rect x="3" y="5" width="18" height="16" rx="2"/><path d="M3 9h18M8 3v4M16 3v4"/></svg>;
    case 'shop':       return <svg {...common}><path d="M3 9l1-4h16l1 4M5 9v11h14V9M9 14h6"/></svg>;
    case 'message':    return <svg {...common}><path d="M21 12a8 8 0 0 1-11.6 7.1L3 21l1.9-6.4A8 8 0 1 1 21 12z"/></svg>;
    case 'megaphone':  return <svg {...common}><path d="M3 11v2a2 2 0 0 0 2 2h2l5 4V5L7 9H5a2 2 0 0 0-2 2zM15 8a4 4 0 0 1 0 8M18 5a8 8 0 0 1 0 14"/></svg>;
    case 'scissors':   return <svg {...common}><circle cx="6" cy="6" r="3"/><circle cx="6" cy="18" r="3"/><path d="M20 4L8.12 15.88M14.5 14.5L20 20M8.12 8.12L12 12"/></svg>;
    case 'chart':      return <svg {...common}><path d="M4 20V10M10 20V4M16 20v-7M22 20H2"/></svg>;
    case 'sparkle':    return <svg {...common}><path d="M12 3l1.8 4.8L18 9.6l-4.2 1.8L12 16l-1.8-4.6L6 9.6l4.2-1.8zM19 14l.7 2 2 .7-2 .7-.7 2-.7-2-2-.7 2-.7z"/></svg>;
    case 'gear':       return <svg {...common}><circle cx="12" cy="12" r="3"/><path d="M19.4 15a1.7 1.7 0 0 0 .3 1.9l.1.1a2 2 0 1 1-2.8 2.8l-.1-.1a1.7 1.7 0 0 0-1.9-.3 1.7 1.7 0 0 0-1 1.5V21a2 2 0 1 1-4 0v-.1a1.7 1.7 0 0 0-1.1-1.5 1.7 1.7 0 0 0-1.9.3l-.1.1a2 2 0 1 1-2.8-2.8l.1-.1a1.7 1.7 0 0 0 .3-1.9 1.7 1.7 0 0 0-1.5-1H3a2 2 0 1 1 0-4h.1a1.7 1.7 0 0 0 1.5-1 1.7 1.7 0 0 0-.3-1.9l-.1-.1a2 2 0 1 1 2.8-2.8l.1.1a1.7 1.7 0 0 0 1.9.3h.1a1.7 1.7 0 0 0 1-1.5V3a2 2 0 1 1 4 0v.1a1.7 1.7 0 0 0 1 1.5h.1a1.7 1.7 0 0 0 1.9-.3l.1-.1a2 2 0 1 1 2.8 2.8l-.1.1a1.7 1.7 0 0 0-.3 1.9v.1a1.7 1.7 0 0 0 1.5 1H21a2 2 0 1 1 0 4h-.1a1.7 1.7 0 0 0-1.5 1z"/></svg>;
    case 'logout':     return <svg {...common}><path d="M9 21H5a2 2 0 0 1-2-2V5a2 2 0 0 1 2-2h4M16 17l5-5-5-5M21 12H9"/></svg>;
    case 'search':     return <svg {...common}><circle cx="11" cy="11" r="7"/><path d="m20 20-3.5-3.5"/></svg>;
    case 'bell':       return <svg {...common}><path d="M6 8a6 6 0 1 1 12 0c0 7 3 8 3 8H3s3-1 3-8zM10 21a2 2 0 0 0 4 0"/></svg>;
    case 'plus':       return <svg {...common}><path d="M12 5v14M5 12h14"/></svg>;
    case 'arrow-up':   return <svg {...common}><path d="M7 17L17 7M17 17V7H7"/></svg>;
    case 'arrow-down': return <svg {...common}><path d="M7 7l10 10M7 17h10V7"/></svg>;
    case 'arrow-right':return <svg {...common}><path d="M5 12h14M13 5l7 7-7 7"/></svg>;
    case 'dollar':     return <svg {...common}><path d="M12 2v20M17 6.5A4.5 4.5 0 0 0 12.5 4h-1A3.5 3.5 0 0 0 8 7.5C8 9.4 9.6 10 12 11s4 1.6 4 3.5A3.5 3.5 0 0 1 12.5 18h-1A4.5 4.5 0 0 1 7 14.5"/></svg>;
    case 'percent':    return <svg {...common}><circle cx="6" cy="6" r="2.5"/><circle cx="18" cy="18" r="2.5"/><path d="M19 5L5 19"/></svg>;
    case 'clock':      return <svg {...common}><circle cx="12" cy="12" r="9"/><path d="M12 7v5l3 2"/></svg>;
    case 'building':   return <svg {...common}><path d="M3 21V6l9-3 9 3v15M3 21h18M9 9h.01M9 13h.01M9 17h.01M15 9h.01M15 13h.01M15 17h.01"/></svg>;
    case 'star':       return <svg {...common}><path d="M12 3l2.6 6.3L21 10l-5 4.5L17.5 21 12 17.5 6.5 21 8 14.5 3 10l6.4-.7z"/></svg>;
    case 'shield':     return <svg {...common}><path d="M12 3l8 3v6c0 5-3.5 8.4-8 9-4.5-.6-8-4-8-9V6z"/></svg>;
    case 'box':        return <svg {...common}><path d="M3 8l9-5 9 5v8l-9 5-9-5zM3 8l9 5 9-5M12 13v8"/></svg>;
    case 'flag':       return <svg {...common}><path d="M4 22V4M4 4h12l-2 4 2 4H4"/></svg>;
    case 'pin':        return <svg {...common}><path d="M12 21s-7-7-7-12a7 7 0 1 1 14 0c0 5-7 12-7 12z"/><circle cx="12" cy="9" r="2.5"/></svg>;
    case 'trend':      return <svg {...common}><path d="M3 17l6-6 4 4 8-8M14 7h7v7"/></svg>;
    case 'warn':       return <svg {...common}><path d="M12 3 2 21h20zM12 10v5M12 18h.01"/></svg>;
    case 'check':      return <svg {...common}><path d="M5 12l5 5L20 6"/></svg>;
    case 'close':      return <svg {...common}><path d="M6 6l12 12M18 6 6 18"/></svg>;
    case 'filter':     return <svg {...common}><path d="M3 5h18l-7 9v6l-4-2v-4z"/></svg>;
    case 'down':       return <svg {...common}><path d="M6 9l6 6 6-6"/></svg>;
    case 'gift':       return <svg {...common}><path d="M3 11h18v9H3zM12 22V11M12 11s-4-3-4-6 4-3 4 0c0-3 4-3 4 0s-4 6-4 6z"/></svg>;
    default: return null;
  }
};

// Franchise HQ-grade sidebar — operator-only items (Calendar, raw Messages, single-shop Loyalty) are removed.
// Services + Catalog merge into one Brand Catalog page. Messages become a Franchisee Hub.
const HQ_SIDEBAR_ITEMS = [
  { id:'dashboard',   icon:'home',      label:'Network Dashboard' },
  { id:'actions',     icon:'check',     label:'Action Center' },
  { id:'customers',   icon:'users',     label:'Customer Intelligence' },
  { id:'catalog',     icon:'shop',      label:'Brand Catalog & Supply' },
  { id:'franchisees', icon:'message',   label:'Franchisee Hub' },
  { id:'marketing',   icon:'megaphone', label:'Brand Marketing' },
  { id:'reports',     icon:'chart',     label:'Network Reports' },
  { id:'team',        icon:'building',  label:'Talent Network' },
  { id:'ai',          icon:'sparkle',   label:'AI Insights' },
  { id:'settings',    icon:'gear',      label:'Franchise Settings' },
];

const Sidebar = ({ page, onNav }) => (
  <aside className="sidebar">
    <div className="sidebar-logo">
      <img src="groom-logo.png" alt="Hawke & Blade" className="sidebar-logo-img"/>
      <div className="sidebar-role">HQ</div>
    </div>
    <nav className="sidebar-nav">
      {HQ_SIDEBAR_ITEMS.map(it => (
        <button
          key={it.id}
          className={'sidebar-item' + (page === it.id ? ' is-active' : '')}
          title={it.label}
          onClick={() => onNav(it.id)}
        >
          <Icon name={it.icon} size={20} />
          <span className="sidebar-tip">{it.label}</span>
        </button>
      ))}
    </nav>
    <div className="sidebar-foot">
      <button className="sidebar-item" title="Sign out"><Icon name="logout" size={20} /><span className="sidebar-tip">Sign out</span></button>
    </div>
  </aside>
);

// Locations dropdown — replaces region selector, lives in top nav
const LocationSelector = ({ value, onChange, locations }) => {
  const [open, setOpen] = React.useState(false);
  const ref = React.useRef(null);
  React.useEffect(() => {
    const onClick = (e) => { if (ref.current && !ref.current.contains(e.target)) setOpen(false); };
    document.addEventListener('mousedown', onClick);
    return () => document.removeEventListener('mousedown', onClick);
  }, []);

  const sel = value === 'all' ? null : locations.find(l => l.id === value);
  const label = sel ? sel.name.replace('Hawke & Blade — ','') : 'All Locations';
  const sub = sel ? sel.city : `${locations.length} shops · ${locations.filter(l => l.type==='corporate').length} corp · ${locations.filter(l => l.type==='franchised').length} franchised`;

  return (
    <div className="loc-selector" ref={ref}>
      <button className="loc-selector-btn" onClick={() => setOpen(o => !o)}>
        <Icon name="shop" size={16} stroke={2}/>
        <div className="loc-selector-text">
          <div className="loc-selector-label">{label}</div>
          <div className="loc-selector-sub">{sub}</div>
        </div>
        <Icon name="down" size={14}/>
      </button>
      {open && (
        <div className="loc-selector-pop">
          <button className={'loc-opt' + (value === 'all' ? ' is-on' : '')} onClick={() => { onChange('all'); setOpen(false); }}>
            <div>
              <div className="loc-opt-name">All Locations</div>
              <div className="loc-opt-sub">{locations.length} shops · network rollup</div>
            </div>
            {value === 'all' && <Icon name="check" size={14} stroke={2.4}/>}
          </button>
          <div className="loc-opt-divider">Corporate</div>
          {locations.filter(l => l.type === 'corporate').map(l => (
            <button key={l.id} className={'loc-opt' + (value === l.id ? ' is-on' : '')} onClick={() => { onChange(l.id); setOpen(false); }}>
              <div>
                <div className="loc-opt-name">{l.name.replace('Hawke & Blade — ','')}</div>
                <div className="loc-opt-sub">{l.city} · {l.id}</div>
              </div>
              <TypeBadge type={l.type}/>
            </button>
          ))}
          <div className="loc-opt-divider">Franchised</div>
          {locations.filter(l => l.type === 'franchised').map(l => (
            <button key={l.id} className={'loc-opt' + (value === l.id ? ' is-on' : '')} onClick={() => { onChange(l.id); setOpen(false); }}>
              <div>
                <div className="loc-opt-name">{l.name.replace('Hawke & Blade — ','')}</div>
                <div className="loc-opt-sub">{l.city} · {l.id}</div>
              </div>
              {l.flags && <TypeBadge type={l.type}/>}
            </button>
          ))}
        </div>
      )}
    </div>
  );
};

const PAGE_META = {
  dashboard:   { title:'Dashboard',                 crumb:'Network Overview',     showLocSelect:true  },
  actions:     { title:'HQ Action Center',          crumb:'Tasks & follow-up',    showLocSelect:false },
  customers:   { title:'Customer Intelligence',     crumb:'Network customers',    showLocSelect:true  },
  catalog:     { title:'Brand Catalog & Supply',    crumb:'Catalog governance',   showLocSelect:false },
  franchisees: { title:'Franchisee Hub',            crumb:'Operator communications', showLocSelect:false },
  marketing:   { title:'Brand Marketing',           crumb:'Campaign governance',  showLocSelect:false },
  reports:     { title:'Network Reports',           crumb:'Financial roll-up',    showLocSelect:true  },
  team:        { title:'Talent Network',            crumb:'Cross-shop performance', showLocSelect:false },
  ai:          { title:'AI Insights',               crumb:'Network intelligence', showLocSelect:false },
  settings:    { title:'Franchise Settings',        crumb:'Brand standards & RBAC', showLocSelect:false },
};

const TopBar = ({ page, role, locationFilter, setLocationFilter, locations }) => {
  const meta = PAGE_META[page] || PAGE_META.dashboard;
  return (
  <header className="topbar">
    <div className="topbar-left">
      <div className="topbar-title">{meta.title}</div>
      <div className="topbar-crumbs">
        <span className="topbar-crumb">{role}</span>
        <span className="topbar-crumb-sep">/</span>
        <span className="topbar-crumb is-current">{meta.crumb}</span>
      </div>
    </div>
    <div className="topbar-mid">
      {meta.showLocSelect && <LocationSelector value={locationFilter} onChange={setLocationFilter} locations={locations}/>}
    </div>
    <div className="topbar-right">
      <GlobalSearch/>
      <NotifBell/>
    </div>
  </header>
  );
};

const PageHeader = ({ period, setPeriod }) => (
  <div className="pageheader">
    <div>
      <h1 className="pageheader-title">Performance Dashboard</h1>
      <p className="pageheader-sub">Network-wide performance, royalties, and compliance across {window.FRANCHISE_DATA.NETWORK.totalLocations} locations.</p>
    </div>
    <div className="pageheader-tools">
      <div className="pageheader-tool">
        <label>Period</label>
        <div className="seg-group">
          {['T','WTD','MTD','QTD','YTD'].map(p => (
            <button key={p} className={'seg' + (period === p ? ' is-on' : '')} onClick={() => setPeriod(p)}>{p}</button>
          ))}
        </div>
      </div>
    </div>
  </div>
);

// ── Demo interactivity: toast, notifications dropdown, global search, modal ──

function hbToast(label, sub) {
  let host = document.getElementById('hb-toasts');
  if (!host) { host = document.createElement('div'); host.id = 'hb-toasts'; document.body.appendChild(host); }
  const t = document.createElement('div');
  t.className = 'hb-toast';
  t.innerHTML = '<span class="hb-toast-check">✓</span><span class="hb-toast-body"><b></b><span></span></span>';
  t.querySelector('b').textContent = label;
  t.querySelector('.hb-toast-body span').textContent = sub || 'Demo mode — action simulated';
  host.appendChild(t);
  requestAnimationFrame(() => t.classList.add('is-in'));
  setTimeout(() => { t.classList.remove('is-in'); setTimeout(() => t.remove(), 300); }, 2600);
  while (host.children.length > 3) host.firstChild.remove();
}

// Any button without its own handler acknowledges the click with a toast,
// so nothing in the demo feels dead. Buttons with real handlers either live
// in a skipped container or carry data-live="1".
if (!window.__hbFallback) {
  window.__hbFallback = true;
  document.addEventListener('click', (e) => {
    const b = e.target.closest('button');
    if (!b) return;
    if (b.dataset.live) return;
    if (b.closest('.sidebar, .seg-group, .cat-tabs, .twk-panel, .field-picker, .loc-selector, .notif-wrap, .gsearch-wrap, .hb-modal')) return;
    if (b.classList.contains('detail-back') || b.classList.contains('icon-btn') || b.classList.contains('seg') || b.classList.contains('cat-tab')) return;
    const label = (b.innerText || b.title || '').trim().replace(/\s+/g, ' ').replace(/[→←✕]/g, '').trim();
    if (!label) return;
    hbToast(label.length > 42 ? label.slice(0, 42) + '…' : label);
  }, true);
}

const NotifBell = () => {
  const [open, setOpen] = React.useState(false);
  const ref = React.useRef(null);
  React.useEffect(() => {
    const onClick = (e) => { if (ref.current && !ref.current.contains(e.target)) setOpen(false); };
    document.addEventListener('mousedown', onClick);
    return () => document.removeEventListener('mousedown', onClick);
  }, []);
  const alerts = window.FRANCHISE_DATA.ALERTS;
  const tone = { casl:'#DC2626', royalty:'#B45309', nps:'#DB2777', vendor:'#EA580C', underperf:'#4F46E5' };
  return (
    <div className="notif-wrap" ref={ref}>
      <button className="topbar-bell" title="Alerts" onClick={() => setOpen(o => !o)}>
        <Icon name="bell" size={18}/>
        <span className="topbar-bell-dot">{alerts.length}</span>
      </button>
      {open && (
        <div className="notif-pop">
          <div className="notif-head"><b>Notifications</b><span>{alerts.length} new</span></div>
          {alerts.map(a => (
            <button key={a.kind} className="notif-item" onClick={() => { setOpen(false); if (a.kind === 'casl') window.dispatchEvent(new CustomEvent('hb:casl')); else window.dispatchEvent(new CustomEvent('hb:nav', { detail: 'actions' })); }}>
              <span className="notif-dot" style={{ background: tone[a.kind] || '#64748B' }}/>
              <span className="notif-body"><b>{a.title}</b><span>{a.detail.length > 84 ? a.detail.slice(0, 84) + '…' : a.detail}</span></span>
            </button>
          ))}
          <button className="notif-foot" onClick={() => { setOpen(false); window.dispatchEvent(new CustomEvent('hb:nav', { detail: 'actions' })); }}>Open Action Center →</button>
        </div>
      )}
    </div>
  );
};

const GlobalSearch = () => {
  const [q, setQ] = React.useState('');
  const [focus, setFocus] = React.useState(false);
  const ref = React.useRef(null);
  React.useEffect(() => {
    const onClick = (e) => { if (ref.current && !ref.current.contains(e.target)) setFocus(false); };
    const onKey = (e) => {
      if ((e.metaKey || e.ctrlKey) && e.key.toLowerCase() === 'k') {
        e.preventDefault();
        const inp = ref.current && ref.current.querySelector('input');
        if (inp) { inp.focus(); setFocus(true); }
      }
    };
    document.addEventListener('mousedown', onClick);
    document.addEventListener('keydown', onKey);
    return () => { document.removeEventListener('mousedown', onClick); document.removeEventListener('keydown', onKey); };
  }, []);
  const D = window.FRANCHISE_DATA;
  const needle = q.trim().toLowerCase();
  let results = null;
  if (needle.length >= 2) {
    const locs = D.LOCATIONS.filter(l => (l.name + ' ' + l.city + ' ' + l.id).toLowerCase().includes(needle)).slice(0, 4);
    const staff = Object.entries(D.BARBERS_BY_STORE || {})
      .flatMap(([sid, names]) => names.map(n => ({ n, sid })))
      .filter(s => s.n.toLowerCase().includes(needle)).slice(0, 4);
    const prods = D.TOP_PRODUCTS.filter(p => (p.name + ' ' + p.sku).toLowerCase().includes(needle)).slice(0, 3);
    results = { locs, staff, prods, none: !locs.length && !staff.length && !prods.length };
  }
  const openLoc = (id) => { setFocus(false); setQ(''); window.dispatchEvent(new CustomEvent('hb:openloc', { detail: id })); };
  const shopName = (sid) => { const l = D.LOCATIONS.find(x => x.id === sid); return l ? l.name.replace('Hawke & Blade — ', '') : sid; };
  return (
    <div className="gsearch-wrap" ref={ref}>
      <div className="topbar-search">
        <Icon name="search" size={16}/>
        <input placeholder="Search locations, staff, products…" value={q} onChange={e => setQ(e.target.value)} onFocus={() => setFocus(true)}/>
        <kbd>⌘K</kbd>
      </div>
      {focus && results && (
        <div className="gsearch-pop">
          {results.locs.length > 0 && <div className="gsearch-sect">Locations</div>}
          {results.locs.map(l => (
            <button key={l.id} className="gsearch-item" onClick={() => openLoc(l.id)}>
              <Icon name="shop" size={13} stroke={2}/><b>{l.name.replace('Hawke & Blade — ', '')}</b><span>{l.city} · {l.id}</span>
            </button>
          ))}
          {results.staff.length > 0 && <div className="gsearch-sect">Staff</div>}
          {results.staff.map(s => (
            <button key={s.n + s.sid} className="gsearch-item" onClick={() => openLoc(s.sid)}>
              <Icon name="users" size={13} stroke={2}/><b>{s.n}</b><span>{shopName(s.sid)}</span>
            </button>
          ))}
          {results.prods.length > 0 && <div className="gsearch-sect">Products</div>}
          {results.prods.map(p => (
            <button key={p.sku} className="gsearch-item" onClick={() => { setFocus(false); setQ(''); window.dispatchEvent(new CustomEvent('hb:nav', { detail: 'catalog' })); hbToast(p.name, 'Opened Brand Catalog · ' + p.sku); }}>
              <Icon name="box" size={13} stroke={2}/><b>{p.name}</b><span>{p.sku}</span>
            </button>
          ))}
          {results.none && <div className="gsearch-empty">No matches for “{q}”</div>}
        </div>
      )}
    </div>
  );
};

const HBModal = ({ title, sub, onClose, children, footer }) => (
  <div className="overlay hb-modal-overlay" onClick={onClose}>
    <div className="hb-modal" onClick={e => e.stopPropagation()}>
      <div className="hb-modal-head">
        <div><h3>{title}</h3>{sub && <p>{sub}</p>}</div>
        <button className="icon-btn" onClick={onClose}><Icon name="close" size={16}/></button>
      </div>
      <div className="hb-modal-body">{children}</div>
      {footer && <div className="hb-modal-foot">{footer}</div>}
    </div>
  </div>
);

const HBField = ({ label, children }) => (
  <label className="hb-field"><span>{label}</span>{children}</label>
);

Object.assign(window, { Icon, Sidebar, TopBar, PageHeader, LocationSelector, hbToast, NotifBell, GlobalSearch, HBModal, HBField });
