/* global React, Icon */
const { useState: useStateShell, useEffect: useEffectShell } = React;

// Flat list of every navigable page (built once, used by SearchModal)
const SEARCH_ITEMS = (() => {
  const items = [];
  // NAV_FULL is defined below — we defer evaluation via a function called after NAV_FULL is defined
  return items; // placeholder; real build happens inside SearchModal via closure over NAV_FULL
})();

function buildSearchItems() {
  const items = [];
  NAV_FULL.forEach(g => {
    if (!g.children) {
      items.push({ id: g.id, label: g.label, icon: g.icon, parent: null });
    } else {
      items.push({ id: g.children[0].id, label: g.label, icon: g.icon, parent: null });
      g.children.forEach(c => {
        items.push({ id: c.id, label: c.label, icon: c.icon, parent: g.label });
      });
    }
  });
  return items;
}

function SearchModal({ onClose, onNav }) {
  const [q, setQ]   = useStateShell('');
  const [sel, setSel] = useStateShell(0);
  const inputRef = React.useRef(null);

  const ALL = React.useMemo(() => buildSearchItems(), []);

  const results = q.trim() === ''
    ? ALL.slice(0, 9)
    : ALL.filter(it =>
        it.label.toLowerCase().includes(q.toLowerCase()) ||
        (it.parent && it.parent.toLowerCase().includes(q.toLowerCase()))
      ).slice(0, 10);

  useEffectShell(() => { inputRef.current?.focus(); }, []);
  useEffectShell(() => { setSel(0); }, [q]);

  const go = (item) => { onNav(item.id); onClose(); };

  const onKey = (e) => {
    if (e.key === 'Escape') { onClose(); return; }
    if (e.key === 'ArrowDown') { e.preventDefault(); setSel(s => Math.min(s + 1, results.length - 1)); }
    if (e.key === 'ArrowUp')   { e.preventDefault(); setSel(s => Math.max(s - 1, 0)); }
    if (e.key === 'Enter' && results[sel]) { go(results[sel]); }
  };

  return (
    <div
      style={{ position: 'fixed', inset: 0, zIndex: 1000, background: 'rgba(0,0,0,0.52)', backdropFilter: 'blur(4px)', display: 'flex', alignItems: 'flex-start', justifyContent: 'center', paddingTop: '11vh' }}
      onClick={onClose}
    >
      <div
        style={{ width: 560, background: 'var(--tm-bg-1)', borderRadius: 14, border: '1px solid var(--tm-line-2)', overflow: 'hidden', boxShadow: '0 28px 64px rgba(0,0,0,0.55)' }}
        onClick={e => e.stopPropagation()}
      >
        {/* Input row */}
        <div style={{ display: 'flex', alignItems: 'center', gap: 12, padding: '13px 18px', borderBottom: '1px solid var(--tm-line-1)' }}>
          <Icon name="search" size={16} style={{ color: 'var(--tm-fg-3)', flexShrink: 0 }} />
          <input
            ref={inputRef}
            value={q}
            onChange={e => setQ(e.target.value)}
            onKeyDown={onKey}
            placeholder="Pesquisar módulo, pedido, cliente, SKU, NF…"
            style={{ flex: 1, background: 'none', border: 'none', outline: 'none', fontSize: 15, color: 'var(--tm-fg-1)', fontFamily: 'inherit' }}
          />
          <kbd style={{ fontSize: 10.5, color: 'var(--tm-fg-4)', padding: '2px 7px', border: '1px solid var(--tm-line-2)', borderRadius: 5, background: 'var(--tm-bg-2)', flexShrink: 0 }}>ESC</kbd>
        </div>

        {/* Results list */}
        <div style={{ maxHeight: 380, overflowY: 'auto' }}>
          {results.length === 0 && (
            <div style={{ padding: '36px 20px', textAlign: 'center', color: 'var(--tm-fg-4)', fontSize: 13 }}>
              Nenhum resultado para "<b>{q}</b>"
            </div>
          )}
          {results.map((item, i) => (
            <div
              key={item.id + i}
              onClick={() => go(item)}
              onMouseEnter={() => setSel(i)}
              style={{
                display: 'flex', alignItems: 'center', gap: 12, padding: '10px 18px',
                cursor: 'pointer', fontSize: 13.5,
                background: i === sel ? 'color-mix(in srgb, var(--tm-brand-champagne) 9%, var(--tm-bg-2))' : 'transparent',
                borderLeft: `2px solid ${i === sel ? 'var(--tm-brand-champagne)' : 'transparent'}`,
                transition: 'background 0.1s',
              }}
            >
              <div style={{ width: 30, height: 30, borderRadius: 7, background: i === sel ? 'color-mix(in srgb, var(--tm-brand-champagne) 16%, var(--tm-bg-3))' : 'var(--tm-bg-3)', display: 'flex', alignItems: 'center', justifyContent: 'center', flexShrink: 0 }}>
                <Icon name={item.icon} size={14} style={{ color: i === sel ? 'var(--tm-brand-champagne)' : 'var(--tm-fg-3)' }} />
              </div>
              <div style={{ flex: 1, minWidth: 0 }}>
                <div style={{ color: i === sel ? 'var(--tm-fg-1)' : 'var(--tm-fg-2)' }}>{item.label}</div>
                {item.parent && <div style={{ fontSize: 11, color: 'var(--tm-fg-4)' }}>{item.parent}</div>}
              </div>
              {i === sel && <div style={{ fontSize: 11, color: 'var(--tm-fg-4)', flexShrink: 0 }}>↵ abrir</div>}
            </div>
          ))}
        </div>

        {/* Footer hints */}
        <div style={{ padding: '7px 18px', borderTop: '1px solid var(--tm-line-0)', display: 'flex', gap: 18, fontSize: 11, color: 'var(--tm-fg-4)' }}>
          <span>↑↓ navegar</span>
          <span>↵ abrir</span>
          <span>esc fechar</span>
        </div>
      </div>
    </div>
  );
}

// Full menu structure mirroring the codebase's src/constants/menu.ts
const NAV_FULL = [
  { id: "dashboard", label: "Dashboard", icon: "layout-dashboard" },
  { id: "crm", label: "CRM", icon: "users", children: [
    { id: "crm/clientes-finais", label: "Clientes Finais", icon: "user" },
    { id: "crm/saloes", label: "Salões / Barbearias", icon: "store" },
    { id: "crm/distribuidores", label: "Distribuidores", icon: "building-2" },
    { id: "crm/representantes", label: "Representantes", icon: "user-cog" },
  ]},
  { id: "mensagens", label: "Mensagens", icon: "message-square", children: [
    { id: "mensagens/inbox", label: "Caixa de Entrada", icon: "inbox" },
    { id: "mensagens/conversas", label: "Conversas", icon: "messages-square" },
    { id: "mensagens/canais", label: "Canais", icon: "radio" },
    { id: "mensagens/agentes", label: "Agentes IA", icon: "bot" },
    { id: "mensagens/templates", label: "Templates", icon: "file-text" },
  ]},
  { id: "ia", label: "Agentes de IA", icon: "bot", children: [
    { id: "ia/comercial", label: "IA Comercial", icon: "trending-up" },
    { id: "ia/sac", label: "IA de SAC", icon: "message-square" },
    { id: "ia/interna", label: "IA Interna", icon: "sparkles" },
  ]},
  { id: "produtos", label: "Produtos", icon: "package", children: [
    { id: "produtos/lista", label: "Lista", icon: "list-ordered" },
    { id: "produtos/linhas", label: "Linhas", icon: "boxes" },
    { id: "produtos/categorias", label: "Categorias", icon: "tags" },
    { id: "produtos/tabelas-preco", label: "Tabelas de Preço", icon: "dollar-sign" },
    { id: "produtos/estoque", label: "Estoque", icon: "warehouse" },
  ]},
  { id: "pedidos", label: "Pedidos", icon: "shopping-cart", children: [
    { id: "pedidos/criar", label: "Criar Pedido", icon: "plus-circle" },
    { id: "pedidos/abertos", label: "Em Aberto", icon: "clock" },
    { id: "pedidos/faturados", label: "Faturados", icon: "check-circle" },
    { id: "pedidos/cancelados", label: "Cancelados", icon: "x-circle" },
  ]},
  { id: "pdv", label: "PDV (Frente de Caixa)", icon: "credit-card" },
  { id: "financeiro", label: "Financeiro", icon: "wallet", children: [
    { id: "financeiro/entradas", label: "Entradas", icon: "trending-up" },
    { id: "financeiro/saidas", label: "Saídas", icon: "trending-down" },
    { id: "financeiro/fluxo-caixa", label: "Fluxo de Caixa", icon: "bar-chart-3" },
    { id: "financeiro/contas-pagar", label: "Contas a Pagar", icon: "receipt" },
    { id: "financeiro/contas-receber", label: "Contas a Receber", icon: "dollar-sign" },
    { id: "financeiro/extrato", label: "Extrato Consolidado", icon: "file-text" },
  ]},
  { id: "relatorios", label: "Relatórios", icon: "bar-chart-3", children: [
    { id: "relatorios/vendas", label: "Vendas Detalhadas", icon: "trending-up" },
    { id: "relatorios/distribuidores", label: "Distribuidores e Ranking", icon: "building-2" },
    { id: "relatorios/clientes", label: "Clientes e Recorrência", icon: "users-2" },
    { id: "relatorios/financeiro", label: "Financeiro", icon: "pie-chart" },
    { id: "relatorios/produtos", label: "Produtos & Estoque", icon: "package" },
    { id: "relatorios/curvaabc", label: "Curva ABC", icon: "bar-chart-3" },
    { id: "relatorios/insights", label: "Insights Automáticos", icon: "sparkles" },
    { id: "relatorios/executivo", label: "Resumo Executivo", icon: "layout" },
  ]},
  { id: "formularios", label: "Formulários", icon: "file-text", children: [
    { id: "formularios/lista", label: "Formulários", icon: "file-text" },
    { id: "formularios/leads", label: "Leads Recebidos", icon: "clipboard-list" },
  ]},
  { id: "kanban", label: "Kanban / Tarefas", icon: "columns" },
  { id: "agenda", label: "Agenda / Calendário", icon: "calendar" },
  { id: "nf", label: "Nota Fiscal", icon: "file-check", children: [
    { id: "nf/emissao", label: "Emissão", icon: "send" },
    { id: "nf/historico", label: "Histórico", icon: "file-text" },
    { id: "nf/empresas", label: "Empresas Emissoras", icon: "building-2" },
    { id: "nf/importar", label: "Importar XML", icon: "upload" },
    { id: "nf/logs", label: "Logs", icon: "list" },
  ]},
  { id: "config", label: "Configurações", icon: "settings", children: [
    { id: "config/perfil", label: "Perfil", icon: "user" },
    { id: "config/equipe", label: "Equipe", icon: "users-2" },
    { id: "config/empresa", label: "Dados da Empresa", icon: "building-2" },
    { id: "config/canais", label: "Integrações", icon: "plug" },
    { id: "config/ia", label: "Personalização IA", icon: "bot" },
    { id: "config/permissoes", label: "Permissões e Papéis", icon: "user-cog" },
  ]},
];

// Map id -> human label (for breadcrumb)
const LABEL_MAP = (() => {
  const m = {};
  NAV_FULL.forEach(g => {
    m[g.id] = g.label;
    (g.children || []).forEach(c => m[c.id] = c.label);
  });
  return m;
})();

function EmpresaSelector({ empresas, empresaAtual, setEmpresaAtual }) {
  const [open, setOpen] = useStateShell(false);
  // Sem document.addEventListener — backdrop posicionado em fixed faz o trabalho
  // sem nenhuma manipulação imperativa do DOM.

  if (!empresas || empresas.length === 0) return null;

  const label = empresaAtual
    ? (empresaAtual.nome_fantasia || empresaAtual.razao_social || 'Empresa')
    : 'Todas as empresas';
  const cor = empresaAtual?.cor || null;

  const escolher = (emp) => {
    setEmpresaAtual(emp);
    setOpen(false);
  };

  return (
    <div style={{ position: 'relative', padding: '0 10px 10px' }}>

      {/* Backdrop invisível — fecha ao clicar fora sem event listeners no document */}
      {open && (
        <div
          style={{ position: 'fixed', inset: 0, zIndex: 198 }}
          onClick={() => setOpen(false)}
        />
      )}

      {/* Botão trigger */}
      <div
        onClick={() => setOpen(o => !o)}
        style={{
          position: 'relative', zIndex: open ? 201 : 'auto',
          display: 'flex', alignItems: 'center', gap: 7, padding: '6px 10px',
          borderRadius: 8, cursor: 'pointer', userSelect: 'none',
          background: open ? 'var(--tm-bg-2)' : 'transparent',
          border: '1px solid var(--tm-line-1)',
          transition: 'background 0.15s',
        }}
        title={label}
      >
        {cor
          ? <span style={{ width: 8, height: 8, borderRadius: '50%', background: cor, flexShrink: 0 }} />
          : <Icon name="building-2" size={12} style={{ color: 'var(--tm-fg-3)', flexShrink: 0 }} />
        }
        <span style={{ flex: 1, overflow: 'hidden', textOverflow: 'ellipsis', whiteSpace: 'nowrap', fontSize: 11.5, color: 'var(--tm-fg-2)' }}>
          {label}
        </span>
        <Icon name="chevrons-up-down" size={11} style={{ color: 'var(--tm-fg-4)', flexShrink: 0 }} />
      </div>

      {/*
        Dropdown com display toggle em vez de montagem/desmontagem condicional.
        Isso evita que React chame removeChild durante renders concorrentes
        (que era a causa do NotFoundError ao trocar de empresa).
      */}
      <div style={{
        display: open ? 'block' : 'none',
        position: 'absolute', top: 'calc(100% - 2px)', left: 10, right: 10,
        background: 'var(--tm-bg-2)', border: '1px solid var(--tm-line-1)',
        borderRadius: 8, zIndex: 200, overflow: 'hidden',
        boxShadow: '0 8px 24px rgba(0,0,0,0.28)',
      }}>
        {/* "Todas" option */}
        <div
          style={{
            display: 'flex', alignItems: 'center', gap: 8, padding: '8px 12px',
            cursor: 'pointer', fontSize: 12,
            background: !empresaAtual ? 'color-mix(in srgb, var(--tm-brand-champagne) 12%, transparent)' : 'transparent',
            color: !empresaAtual ? 'var(--tm-brand-champagne)' : 'var(--tm-fg-2)',
          }}
          onClick={() => escolher(null)}
        >
          <Icon name="layers" size={13} />
          <span>Todas as empresas</span>
        </div>
        <div style={{ height: 1, background: 'var(--tm-line-1)' }} />
        {empresas.map((e, i) => {
          const isActive = empresaAtual?.id === e.id;
          const nome = e.nome_fantasia || e.razao_social || 'Empresa';
          return (
            <div
              key={e.id}
              style={{
                display: 'flex', alignItems: 'center', gap: 8, padding: '8px 12px',
                cursor: 'pointer', fontSize: 12,
                background: isActive ? 'color-mix(in srgb, var(--tm-brand-champagne) 12%, transparent)' : 'transparent',
                color: isActive ? 'var(--tm-brand-champagne)' : 'var(--tm-fg-2)',
                borderTop: i > 0 ? '1px solid var(--tm-line-0)' : 'none',
              }}
              onClick={() => escolher(e)}
            >
              <span style={{ width: 8, height: 8, borderRadius: '50%', background: e.cor || '#6b7280', flexShrink: 0 }} />
              <span style={{ flex: 1, overflow: 'hidden', textOverflow: 'ellipsis', whiteSpace: 'nowrap' }}>{nome}</span>
              {e.principal && (
                <span style={{ fontSize: 9.5, padding: '1px 5px', borderRadius: 10, background: 'color-mix(in srgb, var(--tm-brand-champagne) 18%, transparent)', color: 'var(--tm-brand-champagne)', flexShrink: 0 }}>
                  principal
                </span>
              )}
            </div>
          );
        })}
      </div>
    </div>
  );
}

function Sidebar({ active, onNav, permissions, empresas, empresaAtual, setEmpresaAtual }) {
  // null/undefined = sem restrição (admin sem perfil_id configurado)
  const canSee = (id) => !permissions || permissions[id]?.ver !== false;
  const NAV_VISIBLE = NAV_FULL.filter(g => canSee(g.id));

  // Auto-open the group containing the active item
  const initiallyOpen = () => {
    const open = {};
    NAV_VISIBLE.forEach(g => {
      if (g.children && g.children.some(c => c.id === active)) open[g.id] = true;
    });
    return open;
  };
  const [open, setOpen] = useStateShell(initiallyOpen());

  const toggle = (id) => setOpen(o => ({ ...o, [id]: !o[id] }));

  return (
    <aside className="sidebar">
      <div className="brand">
        {empresaAtual?.logo_url
          ? <img src={empresaAtual.logo_url} alt={empresaAtual.nome_fantasia || "Logo"} style={{ height: 30, maxWidth: 148, objectFit: "contain", display: "block" }} />
          : <>
              <img className="logo-dark"  src="assets/logo-topmix-branco.png" alt="TopMix ProHub" />
              <img className="logo-light" src="assets/logo-topmix-preto.png"  alt="TopMix ProHub" />
            </>
        }
        <div style={{ fontFamily: "var(--tm-font-display)", fontSize: 11, letterSpacing: "0.22em", color: "var(--tm-fg-3)", marginTop: 4 }}>
          PROHUB
        </div>
      </div>

      <EmpresaSelector empresas={empresas} empresaAtual={empresaAtual} setEmpresaAtual={setEmpresaAtual} />

      {NAV_VISIBLE.map(group => {
        if (!group.children) {
          return (
            <div
              key={group.id}
              className={`nav-item ${active === group.id ? "active" : ""}`}
              onClick={() => onNav(group.id)}
            >
              <Icon name={group.icon} size={16} />
              <span>{group.label}</span>
              {group.badge && <span className="badge-small">{group.badge}</span>}
            </div>
          );
        }
        const hasActive = group.children.some(c => c.id === active);
        const isOpen = open[group.id] || hasActive;
        return (
          <React.Fragment key={group.id}>
            <div
              className={`nav-group ${isOpen ? "open" : ""} ${hasActive ? "has-active" : ""}`}
              onClick={() => toggle(group.id)}
            >
              <span className="l">
                <Icon name={group.icon} size={16} />
                <span>{group.label}</span>
              </span>
              {group.badge && <span className="badge-small">{group.badge}</span>}
              <Icon name="chevron-right" size={14} className="caret" />
            </div>
            {isOpen && (
              <div className="nav-sub">
                {group.children.map(child => (
                  <div
                    key={child.id}
                    className={`nav-item ${active === child.id ? "active" : ""}`}
                    onClick={(e) => { e.stopPropagation(); onNav(child.id); }}
                  >
                    <Icon name={child.icon} size={13} />
                    <span>{child.label}</span>
                  </div>
                ))}
              </div>
            )}
          </React.Fragment>
        );
      })}

      <div style={{ height: 24 }} />
    </aside>
  );
}

function ThemeToggle({ theme, setTheme }) {
  return (
    <div
      className={`theme-toggle ${theme === "light" ? "light" : ""}`}
      onClick={() => setTheme(theme === "dark" ? "light" : "dark")}
      title={theme === "dark" ? "Mudar para modo claro" : "Mudar para modo escuro"}
      role="switch"
      aria-checked={theme === "light"}
    >
      <span className="knob" />
      <span className={`ti ${theme === "dark" ? "active" : ""}`}><Icon name="moon" size={12} /></span>
      <span className={`ti ${theme === "light" ? "active" : ""}`}><Icon name="sun" size={12} /></span>
    </div>
  );
}

// ─── Notifications ────────────────────────────────────────────────────────────

const NOTIF_CFG = {
  pedido:            { icon: 'shopping-cart', color: 'var(--tm-brand-champagne)', label: 'Pedido'     },
  pagamento:         { icon: 'banknote',       color: 'var(--tm-success)',         label: 'Pagamento'  },
  recebivel_vencido: { icon: 'alert-circle',   color: 'var(--tm-danger)',          label: 'Financeiro' },
  estoque_baixo:     { icon: 'package-x',      color: 'var(--tm-warning)',         label: 'Estoque'    },
  nf:                { icon: 'file-check',     color: 'var(--tm-info)',            label: 'NF-e'       },
  nf_erro:           { icon: 'file-x',         color: 'var(--tm-danger)',          label: 'NF-e Erro'  },
  lead:              { icon: 'user-plus',      color: 'var(--tm-info)',            label: 'Lead'       },
  mensagem:          { icon: 'message-square', color: '#8b5cf6',                  label: 'Mensagem'   },
  ia:                { icon: 'bot',            color: 'var(--tm-brand-champagne)', label: 'IA'         },
};

const NOTIF_ROUTE = {
  pedido:            'pedidos/abertos',
  pagamento:         'financeiro/contas-receber',
  recebivel_vencido: 'financeiro/contas-receber',
  estoque_baixo:     'produtos/estoque',
  nf:                'nf/historico',
  nf_erro:           'nf/logs',
  lead:              'formularios/leads',
  mensagem:          'mensagens/inbox',
  ia:                'ia/comercial',
};

const DEMO_NOTIFS = [
  { id: 'd1', tipo: 'recebivel_vencido', titulo: '3 contas a receber vencidas hoje',    descricao: 'Total: R$ 4.180,00 · Salão Beleza Pura, Distribuidora Glow Norte, Top Hair', lida: false, created_at: new Date(Date.now() - 4*3600000).toISOString() },
  { id: 'd2', tipo: 'pedido',            titulo: 'Novo pedido #2842 criado',            descricao: 'Salão Beleza Pura · R$ 1.250,00',                                           lida: false, created_at: new Date(Date.now() - 12*60000).toISOString()   },
  { id: 'd3', tipo: 'nf',               titulo: 'NF-e 003421 emitida com sucesso',     descricao: 'Distribuidora Glow Norte',                                                  lida: false, created_at: new Date(Date.now() - 38*60000).toISOString()   },
  { id: 'd4', tipo: 'pagamento',         titulo: 'Pagamento parcial recebido',          descricao: 'Top Hair Cosméticos · R$ 500,00',                                           lida: false, created_at: new Date(Date.now() - 3600000).toISOString()    },
  { id: 'd5', tipo: 'estoque_baixo',     titulo: '5 SKUs abaixo do estoque mínimo',    descricao: 'Shampoo Glow System 2,5L · apenas 4 un.',                                  lida: false, created_at: new Date(Date.now() - 2*3600000).toISOString()  },
  { id: 'd6', tipo: 'lead',              titulo: 'Novo lead: "Quero ser distribuidor"', descricao: 'Belezza Salão — formulário público · há 3h',                                lida: false, created_at: new Date(Date.now() - 3*3600000).toISOString()  },
  { id: 'd7', tipo: 'ia',               titulo: 'IA Comercial fechou negociação',      descricao: 'Salão Studio Marina · margem de 28%',                                       lida: true,  created_at: new Date(Date.now() - 70*60000).toISOString()   },
];

function fmtTimeAgo(iso) {
  const m = Math.floor((Date.now() - new Date(iso).getTime()) / 60000);
  if (m < 1)  return 'agora mesmo';
  if (m < 60) return `há ${m} min`;
  const h = Math.floor(m / 60);
  if (h < 24) return `há ${h}h`;
  return `há ${Math.floor(h / 24)}d`;
}

function NotificationsPanel({ notifs, onMarkRead, onMarkAllRead, onNav, onClose }) {
  const unread = notifs.filter(n => !n.lida).length;

  const handleClick = (n) => {
    onMarkRead(n.id);
    const route = NOTIF_ROUTE[n.tipo];
    if (route) { onNav(route); onClose(); }
  };

  return (
    <div style={{
      position: 'absolute', top: 'calc(100% + 10px)', right: -8,
      width: 384, background: 'var(--tm-bg-1)',
      borderRadius: 12, border: '1px solid var(--tm-line-2)',
      boxShadow: '0 16px 48px rgba(0,0,0,0.38)', zIndex: 400,
      overflow: 'hidden',
    }}>
      {/* Header */}
      <div style={{ display: 'flex', alignItems: 'center', justifyContent: 'space-between', padding: '13px 16px', borderBottom: '1px solid var(--tm-line-1)' }}>
        <div style={{ display: 'flex', alignItems: 'center', gap: 8 }}>
          <span style={{ fontSize: 14, fontWeight: 600 }}>Notificações</span>
          {unread > 0 && (
            <span style={{ fontSize: 10, fontWeight: 700, padding: '1px 7px', borderRadius: 10, background: 'var(--tm-danger)', color: '#fff', lineHeight: 1.6 }}>
              {unread}
            </span>
          )}
        </div>
        {unread > 0 && (
          <button onClick={onMarkAllRead} style={{ fontSize: 11.5, background: 'none', border: 'none', cursor: 'pointer', color: 'var(--tm-brand-champagne)', padding: 0 }}>
            Marcar todas como lidas
          </button>
        )}
      </div>

      {/* List */}
      <div style={{ maxHeight: 440, overflowY: 'auto' }}>
        {notifs.length === 0 ? (
          <div style={{ padding: '44px 20px', textAlign: 'center' }}>
            <Icon name="bell-off" size={30} style={{ color: 'var(--tm-fg-4)', marginBottom: 10 }} />
            <div className="muted" style={{ fontSize: 13 }}>Tudo em dia, nenhuma notificação</div>
          </div>
        ) : notifs.map((n, i) => {
          const cfg = NOTIF_CFG[n.tipo] || NOTIF_CFG.pedido;
          const hasRoute = !!NOTIF_ROUTE[n.tipo];
          return (
            <div
              key={n.id}
              onClick={() => handleClick(n)}
              style={{
                display: 'flex', alignItems: 'flex-start', gap: 12,
                padding: '12px 16px', cursor: hasRoute ? 'pointer' : 'default',
                background: n.lida ? 'transparent' : 'color-mix(in srgb, var(--tm-brand-champagne) 5%, var(--tm-bg-2))',
                borderBottom: i < notifs.length - 1 ? '1px solid var(--tm-line-0)' : 'none',
                transition: 'background 0.12s',
              }}
            >
              {/* Icon badge */}
              <div style={{
                width: 35, height: 35, borderRadius: 9, flexShrink: 0, marginTop: 1,
                background: `color-mix(in srgb, ${cfg.color} 15%, var(--tm-bg-3))`,
                display: 'flex', alignItems: 'center', justifyContent: 'center',
              }}>
                <Icon name={cfg.icon} size={15} style={{ color: cfg.color }} />
              </div>

              {/* Text */}
              <div style={{ flex: 1, minWidth: 0 }}>
                <div style={{ fontSize: 13, fontWeight: n.lida ? 400 : 600, color: 'var(--tm-fg-1)', lineHeight: 1.4 }}>
                  {n.titulo}
                </div>
                {n.descricao && (
                  <div style={{ fontSize: 11.5, color: 'var(--tm-fg-3)', marginTop: 2, lineHeight: 1.4, overflow: 'hidden', textOverflow: 'ellipsis', whiteSpace: 'nowrap' }}>
                    {n.descricao}
                  </div>
                )}
                <div style={{ display: 'flex', alignItems: 'center', gap: 8, marginTop: 5 }}>
                  <span style={{ fontSize: 11, color: 'var(--tm-fg-4)' }}>{fmtTimeAgo(n.created_at)}</span>
                  <span style={{ fontSize: 10.5, padding: '0 6px', borderRadius: 8, background: 'var(--tm-bg-3)', color: 'var(--tm-fg-4)' }}>{cfg.label}</span>
                </div>
              </div>

              {/* Unread dot */}
              {!n.lida && (
                <span style={{ width: 7, height: 7, borderRadius: '50%', background: 'var(--tm-brand-champagne)', flexShrink: 0, marginTop: 6 }} />
              )}
            </div>
          );
        })}
      </div>

      {/* Footer */}
      {notifs.length > 0 && (
        <div style={{ padding: '10px 16px', borderTop: '1px solid var(--tm-line-1)', textAlign: 'center' }}>
          <button style={{ fontSize: 12.5, color: 'var(--tm-brand-champagne)', background: 'none', border: 'none', cursor: 'pointer' }}>
            Ver histórico completo
          </button>
        </div>
      )}
    </div>
  );
}

// ─── Topbar ───────────────────────────────────────────────────────────────────

function Topbar({ active, theme, setTheme, profile, empresaAtual, onNav }) {
  const [searchOpen, setSearchOpen] = useStateShell(false);
  const [notifOpen,  setNotifOpen]  = useStateShell(false);
  const [quickOpen,  setQuickOpen]  = useStateShell(false);
  const [helpOpen,   setHelpOpen]   = useStateShell(false);
  const [notifs, setNotifs]         = useStateShell(DEMO_NOTIFS);
  // notifRef removido — painel usa backdrop para fechar (sem document.addEventListener)

  const parts = active.split("/");
  const root = parts[0];
  const rootLabel = LABEL_MAP[root] || root;
  const leaf = active.includes("/") ? LABEL_MAP[active] || parts[1] : null;

  const displayName = profile
    ? (() => { const p = profile.nome.split(' '); return p[0] + (p[1] ? ' ' + p[1][0] + '.' : ''); })()
    : (window.tmUser?.email?.split('@')[0] || '…');
  const displayRole = profile ? `${profile.perfil || 'Usuário'} · TopMix` : '…';
  const initial = profile ? profile.nome[0].toUpperCase() : (window.tmUser?.email?.[0]?.toUpperCase() || '?');

  // Carregar notificações reais do Supabase (se tabela existir)
  useEffectShell(() => {
    if (!window.tmSupabase) return;
    window.tmSupabase
      .from('notificacoes')
      .select('*')
      .order('created_at', { ascending: false })
      .limit(40)
      .then(({ data, error }) => {
        if (!error && data && data.length > 0) setNotifs(data);
      });
  }, []);

  // ⌘K / Ctrl+K global shortcut
  useEffectShell(() => {
    const handler = (e) => {
      if ((e.metaKey || e.ctrlKey) && e.key === 'k') { e.preventDefault(); setSearchOpen(true); }
    };
    window.addEventListener('keydown', handler);
    return () => window.removeEventListener('keydown', handler);
  }, []);

  const unreadCount = notifs.filter(n => !n.lida).length;

  const markRead = async (id) => {
    setNotifs(prev => prev.map(n => n.id === id ? { ...n, lida: true } : n));
    if (window.tmSupabase && !String(id).startsWith('d')) {
      await window.tmSupabase.from('notificacoes').update({ lida: true }).eq('id', id);
    }
  };

  const markAllRead = async () => {
    setNotifs(prev => prev.map(n => ({ ...n, lida: true })));
    if (window.tmSupabase) {
      const ids = notifs.filter(n => !n.lida && !String(n.id).startsWith('d')).map(n => n.id);
      if (ids.length > 0) {
        await window.tmSupabase.from('notificacoes').update({ lida: true }).in('id', ids);
      }
    }
  };

  return (
    <div className="topbar">
      {searchOpen && <SearchModal onClose={() => setSearchOpen(false)} onNav={onNav} />}

      <div className="crumb" style={{ display: 'flex', alignItems: 'center', gap: 10, flexWrap: 'nowrap' }}>
        <span>TopMix&nbsp;›&nbsp;
          {leaf ? <>{rootLabel}&nbsp;›&nbsp;<b>{leaf}</b></> : <b>{rootLabel}</b>}
        </span>
        {empresaAtual && (
          <span style={{
            display: 'inline-flex', alignItems: 'center', gap: 5,
            padding: '2px 8px', borderRadius: 20,
            background: 'color-mix(in srgb, var(--tm-bg-2) 90%, transparent)',
            border: '1px solid var(--tm-line-1)',
            fontSize: 10.5, color: 'var(--tm-fg-3)', flexShrink: 0,
          }}>
            <span style={{ width: 6, height: 6, borderRadius: '50%', background: empresaAtual.cor || '#6b7280', flexShrink: 0 }} />
            {empresaAtual.nome_fantasia || empresaAtual.razao_social}
          </span>
        )}
      </div>

      <div className="search-box" onClick={() => setSearchOpen(true)} style={{ cursor: 'pointer' }}>
        <Icon name="search" size={14} />
        <span>Pesquisar pedido, cliente, SKU, lead, NF…</span>
        <span style={{ marginLeft: "auto", fontSize: 10.5, color: "var(--tm-fg-4)", fontFamily: "var(--tm-font-mono)" }}>⌘K</span>
      </div>

      <div className="right">
        <ThemeToggle theme={theme} setTheme={setTheme} />
        {/* Quick-create menu */}
        <div style={{ position: 'relative' }}>
          {quickOpen && (
            <div
              style={{ position: 'fixed', inset: 0, zIndex: 398 }}
              onClick={() => setQuickOpen(false)}
            />
          )}
          <div
            className="icon-btn"
            title="Criar novo"
            onClick={() => { setQuickOpen(o => !o); setNotifOpen(false); setHelpOpen(false); }}
            style={{ position: 'relative', zIndex: quickOpen ? 401 : 'auto' }}
          >
            <Icon name="plus" size={16} />
          </div>
          {quickOpen && (
            <div style={{
              position: 'absolute', top: 'calc(100% + 8px)', right: 0, zIndex: 400,
              background: 'var(--tm-bg-1)', border: '1px solid var(--tm-line-1)',
              borderRadius: 10, padding: '6px 0', minWidth: 210,
              boxShadow: '0 8px 24px rgba(0,0,0,.25)',
            }}>
              {[
                { icon: 'shopping-cart', label: 'Novo Pedido',        nav: 'pedidos/criar' },
                { icon: 'user-plus',     label: 'Novo Cliente',       nav: 'crm/clientes-finais' },
                { icon: 'file-check',    label: 'Emitir Nota Fiscal', nav: 'nf/emissao' },
                { icon: 'dollar-sign',   label: 'Lançamento Financeiro', nav: 'financeiro/entradas' },
                { icon: 'calendar',      label: 'Novo Evento',        nav: 'agenda' },
                { icon: 'columns',       label: 'Nova Tarefa',        nav: 'kanban' },
              ].map(item => (
                <div
                  key={item.nav}
                  onClick={() => { onNav(item.nav); setQuickOpen(false); }}
                  style={{
                    display: 'flex', alignItems: 'center', gap: 10,
                    padding: '8px 14px', cursor: 'pointer', fontSize: 13,
                    color: 'var(--tm-fg-1)', transition: 'background .15s',
                  }}
                  onMouseEnter={e => e.currentTarget.style.background = 'var(--tm-bg-2)'}
                  onMouseLeave={e => e.currentTarget.style.background = 'transparent'}
                >
                  <Icon name={item.icon} size={15} />
                  <span>{item.label}</span>
                </div>
              ))}
            </div>
          )}
        </div>

        {/* Bell com painel de notificações */}
        <div style={{ position: 'relative' }}>
          {/* Backdrop invisível — fecha painel ao clicar fora (sem document listener) */}
          {notifOpen && (
            <div
              style={{ position: 'fixed', inset: 0, zIndex: 398 }}
              onClick={() => setNotifOpen(false)}
            />
          )}
          <div
            className="icon-btn"
            title="Notificações"
            onClick={() => { setNotifOpen(o => !o); setQuickOpen(false); setHelpOpen(false); }}
            style={{ position: 'relative', zIndex: notifOpen ? 401 : 'auto' }}
          >
            <Icon name="bell" size={16} />
            {unreadCount > 0 && (
              <span style={{
                position: 'absolute', top: 4, right: 4,
                width: unreadCount > 9 ? 'auto' : 8, height: 8,
                minWidth: 8, padding: unreadCount > 9 ? '0 3px' : 0,
                borderRadius: 10, background: 'var(--tm-danger)',
                border: '1.5px solid var(--tm-bg-0)',
                fontSize: 8, color: '#fff', fontWeight: 700,
                display: 'flex', alignItems: 'center', justifyContent: 'center',
                lineHeight: 1,
              }}>
                {unreadCount > 9 ? '9+' : ''}
              </span>
            )}
          </div>
          {notifOpen && (
            <div style={{ position: 'relative', zIndex: 400 }}>
              <NotificationsPanel
                notifs={notifs}
                onMarkRead={markRead}
                onMarkAllRead={markAllRead}
                onNav={onNav}
                onClose={() => setNotifOpen(false)}
              />
            </div>
          )}
        </div>

        {/* Help / Shortcuts panel */}
        <div style={{ position: 'relative' }}>
          {helpOpen && (
            <div
              style={{ position: 'fixed', inset: 0, zIndex: 398 }}
              onClick={() => setHelpOpen(false)}
            />
          )}
          <div
            className="icon-btn"
            title="Ajuda e atalhos"
            onClick={() => { setHelpOpen(o => !o); setNotifOpen(false); setQuickOpen(false); }}
            style={{ position: 'relative', zIndex: helpOpen ? 401 : 'auto' }}
          >
            <Icon name="help-circle" size={16} />
          </div>
          {helpOpen && (
            <div style={{
              position: 'absolute', top: 'calc(100% + 8px)', right: 0, zIndex: 400,
              background: 'var(--tm-bg-1)', border: '1px solid var(--tm-line-1)',
              borderRadius: 10, padding: '16px 18px', minWidth: 260, maxWidth: 300,
              boxShadow: '0 8px 24px rgba(0,0,0,.25)',
            }}>
              <div style={{ fontWeight: 600, fontSize: 13, marginBottom: 12, color: 'var(--tm-fg-1)' }}>
                Atalhos do teclado
              </div>
              {[
                { keys: '⌘ K', desc: 'Busca rápida' },
                { keys: 'Esc', desc: 'Fechar modal / painel' },
              ].map((s, i) => (
                <div key={i} style={{
                  display: 'flex', justifyContent: 'space-between', alignItems: 'center',
                  padding: '5px 0', fontSize: 12.5, color: 'var(--tm-fg-2)',
                }}>
                  <span>{s.desc}</span>
                  <kbd style={{
                    padding: '2px 7px', borderRadius: 5,
                    background: 'var(--tm-bg-2)', border: '1px solid var(--tm-line-1)',
                    fontSize: 11, fontFamily: 'var(--tm-font-mono)', color: 'var(--tm-fg-3)',
                  }}>{s.keys}</kbd>
                </div>
              ))}
              <div style={{ borderTop: '1px solid var(--tm-line-1)', margin: '12px 0' }} />
              <div style={{ fontWeight: 600, fontSize: 13, marginBottom: 8, color: 'var(--tm-fg-1)' }}>
                Suporte
              </div>
              <div style={{ fontSize: 12, color: 'var(--tm-fg-3)', lineHeight: 1.5 }}>
                Dúvidas ou problemas?<br />
                <span style={{ color: 'var(--tm-accent)' }}>suporte@topmixprofissional.com.br</span>
              </div>
              <div style={{ borderTop: '1px solid var(--tm-line-1)', margin: '12px 0' }} />
              <div style={{ fontSize: 11, color: 'var(--tm-fg-4)', textAlign: 'center' }}>
                TopMix ProHub v1.0
              </div>
            </div>
          )}
        </div>

        <div style={{ display: "flex", alignItems: "center", gap: 10, paddingLeft: 12, borderLeft: "1px solid var(--tm-line-1)", marginLeft: 6 }}>
          {profile?.avatar_url ? (
            <img src={profile.avatar_url} alt={initial}
              style={{ width:32, height:32, borderRadius:'50%', objectFit:'cover', border:'1.5px solid var(--tm-line-2)', flexShrink:0 }} />
          ) : (
            <div className="avatar sm">{initial}</div>
          )}
          <div style={{ display: "flex", flexDirection: "column", lineHeight: 1.1 }}>
            <span style={{ fontSize: 12, fontWeight: 500 }}>{displayName}</span>
            <span style={{ fontSize: 10.5, color: "var(--tm-fg-3)" }}>{displayRole}</span>
          </div>
          <button className="icon-btn" title="Sair da conta" onClick={() => window.tmSignOut && window.tmSignOut()} style={{ marginLeft: 4 }}>
            <Icon name="log-out" size={14} />
          </button>
        </div>
      </div>
    </div>
  );
}

Object.assign(window, { Sidebar, Topbar, LABEL_MAP, NAV_FULL });
