// Shell do portal autenticado (Control Center): NavSidebar, Topbar com busca global, notificações, command palette (⌘K),
// menus de conta e de organização/ambiente, Toast e layout responsivo (desktop ≥1100, tablet 700–1099, mobile <700).
const VxShellCtx = React.createContext(null);
const useShell = () => React.useContext(VxShellCtx);
const vxLs = (k, d) => { try { const v = localStorage.getItem(k); return v == null ? d : v; } catch (e) { return d; } };
const vxLsSet = (k, v) => { try { localStorage.setItem(k, v); } catch (e) {} };

function useBreakpoint() {
  const [w, setW] = React.useState(window.innerWidth);
  React.useEffect(() => { const h = () => setW(window.innerWidth); window.addEventListener('resize', h); return () => window.removeEventListener('resize', h); }, []);
  return w < 700 ? 'mobile' : w < 1100 ? 'tablet' : 'desktop';
}

function Shell(props) {
  return <AccessProvider permissions={window.VX_NAV.permissions}><ShellFrame {...props} /></AccessProvider>;
}

function ShellFrame({ page, params = {}, go, onLogout, onLogoClick, bleed, children }) {
  const { Topbar, SearchField, Menu, IconButton, Avatar, Toast } = window.VRticeDesignSystem_d763eb;
  const { can, allows } = useAccess();
  const bp = useBreakpoint();
  const nav0 = (() => { try { return JSON.parse(vxLs('vx-cc-nav', '{}')); } catch (e) { return {}; } })();
  // A sidebar nasce expandida. Só fica colapsada se a própria pessoa clicou na seta (chave nova: ignora o 'collapsed' legado de vx-cc-nav).
  const [collapsed, setCollapsed] = React.useState(() => vxLs('vx-cc-sb', '') === 'collapsed'), [closed, setClosed] = React.useState(nav0.closed || []);
  const [q, setQ] = React.useState('');
  const [notifs, setNotifs] = React.useState(window.VXData.notifs), [nd, setNd] = React.useState(false), [pal, setPal] = React.useState(false), [sheet, setSheet] = React.useState(false);
  const [menu, setMenu] = React.useState(null), [modal, setModal] = React.useState(null), [user, setUser] = React.useState(window.VXData.user);
  // Começa vazio: só contextos reais (get_my_app_context) podem ser escolhidos; nunca os exemplos de admin-data.js.
  const [envs, setEnvs] = React.useState([]), [env, setEnv] = React.useState({ id: '', org: 'Carregando…', label: 'Contexto', kind: 'VERTICE', tone: 'neutral' });
  const [toastM, setToastM] = React.useState(null), tt = React.useRef(null);
  const toast = (m, icon) => { setToastM({ m, icon }); clearTimeout(tt.current); tt.current = setTimeout(() => setToastM(null), 2400); };
  React.useEffect(() => () => clearTimeout(tt.current), []);
  React.useEffect(() => {
    let alive = true;
    const hydrateContext = async () => {
      try {
        const ctx = await window.VxAuthorization.getContext();
        if (!alive || !ctx) return;
        const tone = { VERTICE: 'success', ADMIN: 'warning', CLIENT: 'info', PARTNER: 'active', SERVICE_PROVIDER: 'proposal', AUDIT: 'neutral' };
        const realEnvs = (ctx.memberships || []).flatMap(m => (m.environments || []).map(e => ({
          id: e.id,
          org: m.organization?.name || 'Organização',
          label: e.name,
          kind: e.kind,
          tone: tone[e.kind] || 'neutral'
        })));
        if (!realEnvs.length) return;
        setEnvs(realEnvs);
        const activeId = ctx.active_context && ctx.active_context.environment_id;
        setEnv(realEnvs.find(e => e.id === activeId) || realEnvs[0]);
      } catch (e) {}
    };
    hydrateContext();
    return () => { alive = false; };
  }, []);
  React.useEffect(() => {
    const syncProfile = () => setUser({ ...(window.VXData.user || {}) });
    window.addEventListener('vx-profile-hydrated', syncProfile);
    return () => window.removeEventListener('vx-profile-hydrated', syncProfile);
  }, []);
  React.useEffect(() => { const h = e => { if ((e.metaKey || e.ctrlKey) && e.key.toLowerCase() === 'k') { e.preventDefault(); setPal(p => !p); } }; window.addEventListener('keydown', h); return () => window.removeEventListener('keydown', h); }, []);
  const nav = (id, prm) => { setSheet(false); setMenu(null); go(id, prm); };
  const saveNav = (c, cl) => vxLsSet('vx-cc-nav', JSON.stringify({ closed: cl }));
  const saveCollapsed = c => vxLsSet('vx-cc-sb', c ? 'collapsed' : 'expanded');
  const toggleGroup = id => setClosed(cs => { const n = cs.includes(id) ? cs.filter(x => x !== id) : [...cs, id]; saveNav(collapsed, n); return n; });
  // Só colapsa por escolha do usuário (botão da sidebar); nenhum breakpoint força o colapso.
  const eColl = bp !== 'mobile' && collapsed;
  const unread = notifs.filter(n => n.unread).length;
  const meta = window.VX_NAV.meta[page] || window.VX_NAV.meta.dash;
  const parent = meta.parent && window.VX_NAV.meta[meta.parent];
  const entity = page === 'prospect' && window.VXCommercial.byId[params.id];
  // Cada nível do breadcrumb navega: grupo -> primeira tela do grupo, pai -> tela pai, atual -> sem ação.
  const crumbTo = id => ({ onClick: e => { e && e.preventDefault && e.preventDefault(); nav(id); } });
  const groupFirst = (window.VX_NAV.groups.find(g => g.items.some(i => i.id === (parent || meta).id)) || { items: [] }).items[0];
  const crumbs = [
    { label: meta.group, ...(groupFirst && groupFirst.id !== meta.id ? crumbTo(groupFirst.id) : {}) },
    ...(parent ? [{ label: parent.label, ...crumbTo(parent.id) }] : []),
    { label: entity ? entity.name : meta.label, onClick: e => e && e.preventDefault && e.preventDefault() },
  ];
  const pageKey = page + (params.id ? ':' + params.id : '');
  const pad = bp === 'mobile' ? 16 : bp === 'tablet' ? 28 : 40;
  const body = (
    <VxBoundary k={pageKey}>
      <PageStateGuard meta={meta} go={nav}>{children}</PageStateGuard>
    </VxBoundary>
  );
  const content = bleed
    ? <div key={pageKey} style={{ animation: 'vx-enter .3s ease backwards', paddingBottom: bp === 'mobile' ? 96 : 0 }}>{body}</div>
    : <div key={pageKey} style={{ padding: pad, paddingBottom: bp === 'mobile' ? 96 : pad, display: 'flex', flexDirection: 'column', gap: bp === 'mobile' ? 20 : 32, maxWidth: 1680, width: '100%', margin: '0 auto', boxSizing: 'border-box', animation: 'vx-enter .3s ease backwards' }}>{body}</div>;
  const sidebar = extra => <NavSidebar active={meta.parent || page} go={nav} closed={closed} toggleGroup={toggleGroup} user={user} env={env} onLogo={() => { setSheet(false); onLogoClick(); }} {...extra} />;
  const orgMenu = (
    <><div onClick={() => setMenu(null)} style={{ position: 'fixed', inset: 0, zIndex: 299 }} />
      <div style={{ position: 'fixed', zIndex: 300, left: bp === 'mobile' ? 14 : eColl ? 84 : 14, top: 124 }}>
        <Menu
          width={300}
          header={{ title: 'Organização e ambiente', sub: 'Contextos da sua conta' }}
          items={envs.map(e => ({
            icon: env.id === e.id ? 'ph-check-circle' : 'ph-circle',
            label: e.org + ' · ' + e.label,
            onClick: async () => {
              try {
                await window.VxAuthorization.setActiveContext(e.id);
                setEnv(e);
                setMenu(null);
                toast('Contexto alterado para ' + e.org + ' · ' + e.label);
              } catch (err) {
                toast('Não foi possível alterar o contexto.', 'ph-warning');
              }
            }
          }))}
        />
      </div></>
  );
  const userPos = { side: { left: eColl ? 84 : 14, bottom: 84 }, top: { top: 96, right: pad }, mobile: { top: 56, right: 8 } }[menu];
  // Barra inferior (mobile): só telas que o usuário pode abrir, pela mesma regra do menu (permissão + escopo).
  const tabs = ['dash', 'prospects', 'pipeline', 'audit', 'org'].filter(id => allows(window.VX_NAV.meta[id])).slice(0, 3)
    .map(id => [id, { dash: 'Início', prospects: 'Prospects', pipeline: 'Pipeline', audit: 'Auditoria', org: 'Organização' }[id], { dash: 'ph-squares-four', prospects: 'ph-database', pipeline: 'ph-kanban', audit: 'ph-list-magnifying-glass', org: 'ph-buildings' }[id]]);
  const search = <SearchField value={q} onChange={setQ} results={vxSearchGroups(q, allows)} onSelect={it => { setQ(''); nav(it.id, it.params); }} />;
  const saveUser = u => { window.VXData.user = u; setUser(u); };
  const ctx = { go: nav, toast, bp, user, saveUser, can, env };

  return (
    <VxShellCtx.Provider value={ctx}>
      {bp === 'mobile' ? (
        <div style={{ minHeight: '100vh', background: 'var(--bg-app)' }}>
          <header style={{ position: 'sticky', top: 0, zIndex: 20, height: 60, display: 'flex', alignItems: 'center', gap: 4, padding: '0 8px', background: 'var(--bg-app)', borderBottom: '1px solid var(--border-faint)' }}>
            <IconButton icon="ph-list" label="Menu" onClick={() => setSheet(true)} />
            <span style={{ flex: 1, fontSize: 16, fontWeight: 600, minWidth: 0, overflow: 'hidden', textOverflow: 'ellipsis', whiteSpace: 'nowrap' }}>{page === 'prospect' ? 'Prospect' : meta.label}</span>
            <IconButton icon="ph-magnifying-glass" label="Buscar" onClick={() => setPal(true)} />
            <IconButton icon="ph-bell" label="Notificações" badge={unread > 0} onClick={() => setNd(true)} />
            <a href="#" aria-label="Menu da conta" onClick={e => { e.preventDefault(); setMenu(menu ? null : 'mobile'); }} style={{ padding: 4 }}><Avatar name={user.name} src={user.photo} color={user.color} size={32} /></a>
          </header>
          <main>{content}</main>
          <nav aria-label="Navegação principal" style={{ position: 'fixed', left: 0, right: 0, bottom: 0, height: 68, display: 'flex', background: 'var(--surface-dialog)', borderTop: '1px solid var(--border-default)', zIndex: 20 }}>
            {[...tabs, ['notif', 'Alertas', 'ph-bell'], ['more', 'Mais', 'ph-dots-three-outline']].map(([id, l, ic]) => (
              <button key={id} type="button" onClick={() => id === 'more' ? setSheet(true) : id === 'notif' ? setNd(true) : nav(id)} aria-current={(meta.parent || page) === id ? 'page' : undefined} style={{ all: 'unset', flex: 1, boxSizing: 'border-box', cursor: 'pointer', display: 'flex', flexDirection: 'column', alignItems: 'center', justifyContent: 'center', gap: 4, fontSize: 11, color: (meta.parent || page) === id ? 'var(--action-selected-icon)' : 'var(--text-muted)', fontWeight: (meta.parent || page) === id ? 600 : 400, position: 'relative' }}>
                <i className={'ph ' + ic} style={{ fontSize: 22 }} />{l}
                {id === 'notif' && unread > 0 && <span style={{ position: 'absolute', top: 10, left: '56%', width: 8, height: 8, borderRadius: '50%', background: 'var(--status-info)' }} />}
              </button>
            ))}
          </nav>
          {sheet && <>
            <div onClick={() => setSheet(false)} style={{ position: 'fixed', inset: 0, background: 'var(--bg-overlay)', zIndex: 40 }} />
            <div style={{ position: 'fixed', top: 0, bottom: 0, left: 0, zIndex: 41 }}>{sidebar({ sheet: true, collapsed: false, onUser: () => { setSheet(false); nav('profile', { tab: 'perfil' }); }, onOrg: () => setMenu('org') })}</div>
          </>}
        </div>
      ) : (
        <div style={{ display: 'grid', gridTemplateColumns: 'auto minmax(0,1fr)', minHeight: '100vh', background: 'var(--bg-app)' }}>
          <div style={{ position: 'sticky', top: 0, height: '100vh', alignSelf: 'start', zIndex: 5 }}>
            {sidebar({ collapsed: eColl, onToggle: bp !== 'mobile' ? () => { setCollapsed(!collapsed); saveCollapsed(!collapsed); } : null, onUser: () => setMenu(menu === 'side' ? null : 'side'), onOrg: () => setMenu(menu === 'org' ? null : 'org') })}
          </div>
          <main style={{ display: 'flex', flexDirection: 'column', minWidth: 0 }}>
            <Topbar breadcrumb={crumbs} user={user} unread={unread > 0} onNotifications={() => setNd(true)} onUserClick={() => setMenu(menu === 'top' ? null : 'top')} search={search} />
            {content}
          </main>
        </div>
      )}
      <UserMenuLayer origin={menu === 'org' ? null : menu} position={userPos} user={user} modal={modal} setModal={setModal} onClose={() => setMenu(null)} go={nav} onLogout={onLogout} />
      {menu === 'org' && orgMenu}
      {nd && <NotificationCenter notifs={notifs} setNotifs={setNotifs} onClose={() => setNd(false)} />}
      {pal && <CommandPalette onClose={() => setPal(false)} go={nav} toast={toast} />}
      {toastM && <Toast icon={toastM.icon}>{toastM.m}</Toast>}
    </VxShellCtx.Provider>
  );
}
Object.assign(window, { Shell, useShell });
