// ─── Shell (Sidebar + Header) ──────────────────────
// El esqueleto visual de la SPA: Sidebar (nav agrupado por sección, filtrado por
// permisos) y Header (breadcrumbs, buscador, tema, campana de margen, ajustes de
// inventario, Configuración, menú de usuario). Expone a window: Sidebar, Header.
// Consume window.MicosPuedeVer (dominio/sesion.js), window.APROBACIONES/
// AJUSTES_ENTREGA (colecciones hidratadas), window.ROUTES.LOGIN, Icon*/MicosWordmark
// (ui/icons.jsx). Lo carga solo Micos ERP.html, después de ui/icons.jsx. P4: podados
// DataMenu/UserMenu (muertos, sin consumidor) y la rama item.badge (ningún ítem de
// NAV_SECTIONS define badge); el wordmark inline divergente pasó a <MicosWordmark/>.

const { useState, useEffect, useRef } = React;

// ─── Sidebar ───────────────────────────────────────
const NAV_SECTIONS = [
  {
    title: 'General',
    items: [
      { label: 'Panel general', href: 'dashboard', icon: IconLayoutDashboard },
    ],
  },
  {
    title: 'Operaciones',
    items: [
      { label: 'Expedientes', href: 'expedientes', icon: IconFileText },
      { label: 'Compras', href: 'compras', icon: IconShoppingCart },
      { label: 'Finanzas', href: 'finanzas', icon: IconDollar },
      { label: 'Logística', href: 'logistica', icon: IconTruck },
      { label: 'Inventario', href: 'inventario', icon: IconPackage },
    ],
  },
  {
    title: 'Directorio',
    items: [
      { label: 'Entidades', href: 'entidades', icon: IconBuilding },
      { label: 'Médicos', href: 'medicos', icon: IconStethoscope },
      { label: 'Particulares', href: 'particulares', icon: IconUsers },
      { label: 'Proveedores', href: 'proveedores', icon: IconTruck },
    ],
  },
  {
    title: 'Herramientas',
    items: [
      { label: 'Caja Chica', href: 'caja-chica', icon: IconWallet },
    ],
  },
];

function Sidebar({ activeKey, onNav, user, onLogout }) {
  return (
    <aside
      className="hidden md:flex flex-col w-[272px] sticky top-0 h-screen z-10"
      style={{
        background: 'var(--sidebar)',
        borderRight: '1px solid var(--sidebar-border)',
      }}
    >
      <div className="flex items-end gap-2 py-7 px-7">
        <button
          type="button"
          onClick={() => onNav('dashboard')}
          className="group flex items-center bg-transparent border-0 p-0 cursor-pointer"
          aria-label="Ir al Panel general"
        >
        <MicosWordmark
          style={{ height: 30, width: 'auto', color: 'var(--accent)' }}
          className="transition-transform duration-200 group-hover:scale-105"
        />
        </button>
        <span
          className="text-[9.5px] font-extrabold uppercase tracking-[0.22em]"
          style={{ color: 'color-mix(in oklab, var(--muted-foreground) 75%, transparent)' }}
        >
          ERP
        </span>
      </div>

      <nav className="flex-1 overflow-y-auto pt-3 pb-4 px-4 space-y-7 scrollbar-none">
        {NAV_SECTIONS.map((section) => {
          // Filtro por permisos del usuario actual. El admin ve todo; las secciones
          // fuera de la matriz (Panel general, Configuración) siempre se ven.
          const items = section.items.filter((item) =>
            window.MicosPuedeVer ? window.MicosPuedeVer(item.href) : true
          );
          if (items.length === 0) return null;
          return (
          <div key={section.title} className="flex flex-col gap-1">
            <p className="px-3 pb-2.5 text-[10.5px] font-bold uppercase tracking-[0.18em]" style={{ color: 'color-mix(in oklab, var(--muted-foreground) 75%, transparent)' }}>
              {section.title}
            </p>
            {items.map((item) => {
              const active = activeKey === item.href || (item.href === 'expedientes' && activeKey?.startsWith('expedientes'));
              return (
                <button
                  key={item.href}
                  onClick={() => onNav(item.href)}
                  className="nav-item group relative flex items-center gap-3 pl-3 pr-3 py-2.5 text-[13.5px] font-semibold rounded-xl cursor-pointer transition-all duration-200"
                  style={{
                    background: active ? 'color-mix(in oklab, var(--accent) 12%, transparent)' : 'transparent',
                    color: active ? 'var(--accent)' : 'color-mix(in oklab, var(--foreground) 75%, transparent)',
                  }}
                  onMouseEnter={(e) => { if (!active) { e.currentTarget.style.background = 'var(--surface-hover)'; e.currentTarget.style.color = 'var(--foreground)'; } }}
                  onMouseLeave={(e) => { if (!active) { e.currentTarget.style.background = 'transparent'; e.currentTarget.style.color = 'color-mix(in oklab, var(--foreground) 75%, transparent)'; } }}
                >
                  {active && <span className="nav-active-indicator" />}
                  <span
                    className="flex h-9 w-9 items-center justify-center rounded-lg transition-all duration-200 flex-shrink-0"
                    style={{
                      background: active ? 'color-mix(in oklab, var(--accent) 18%, transparent)' : 'color-mix(in oklab, var(--muted-foreground) 6%, transparent)',
                      color: active ? 'var(--accent)' : 'var(--muted-foreground)',
                    }}
                  >
                    <item.icon size={17} />
                  </span>
                  <span className="flex-1 text-left">{item.label}</span>
                </button>
              );
            })}
          </div>
          );
        })}
      </nav>
    </aside>
  );
}

// ─── Botón de correo (CRM) con badge de no-leídos ──
// Puente ERP→CRM (carril B-erp, top10 #8): trae los hilos SIN LEER del usuario
// (/api/crm-unread, poll cada 60s + al volver a la pestaña) y los muestra como
// contador discreto en el topbar. Además prefija el título de la pestaña
// "(N) …" para que se vea el pendiente aunque el ERP no esté en foco (patrón de
// cualquier cliente de correo). Click → abre el CRM (/crm es otro entry point:
// navegación full-page, no ruta interna del ERP).
function CrmMailButton() {
  const [unread, setUnread] = useState(0);
  useEffect(() => {
    let cancel = false;
    const pull = () => {
      fetch('/api/crm-unread', { credentials: 'same-origin' })
        .then((r) => (r.ok ? r.json() : null))
        .then((d) => { if (!cancel && d && typeof d.unread === 'number') setUnread(d.unread); })
        .catch(() => {}); // sin sesión / red caída: dejamos el contador como está, sin romper el topbar
    };
    pull();
    const iv = setInterval(pull, 60000);
    const onVis = () => { if (document.visibilityState === 'visible') pull(); };
    document.addEventListener('visibilitychange', onVis);
    return () => { cancel = true; clearInterval(iv); document.removeEventListener('visibilitychange', onVis); };
  }, []);
  // Título de la pestaña: "(N) <título base>". El base se captura una vez (sin el
  // prefijo previo) — nada más en el ERP toca document.title, así que es estable.
  useEffect(() => {
    if (window.__erpTituloBase == null) window.__erpTituloBase = document.title.replace(/^\(\d+\)\s*/, '');
    const base = window.__erpTituloBase;
    document.title = unread > 0 ? `(${unread}) ${base}` : base;
  }, [unread]);

  return (
    <button
      className="btn btn-icon relative"
      style={{ background: 'var(--card)', color: 'var(--muted-foreground)', border: '1px solid var(--border)' }}
      title={unread > 0 ? `Correo — ${unread} sin leer` : 'Correo'}
      onClick={() => { window.location.href = '/crm'; }}
    >
      <IconMail size={16} />
      {unread > 0 && (
        <span
          className="absolute -top-1.5 -right-1.5 min-w-[17px] h-[17px] px-1 rounded-full flex items-center justify-center text-[10px] font-extrabold leading-none tabular-nums"
          style={{ background: 'var(--accent)', color: 'var(--accent-foreground)', boxShadow: '0 0 0 2px var(--card)' }}
        >
          {unread > 99 ? '99+' : unread}
        </span>
      )}
    </button>
  );
}

// ─── Header (sticky top bar) ────────────────────────
function Header({ breadcrumbs, theme, onToggleTheme, onNav, onSearchOpen, user }) {
  return (
    <header className="sticky top-0 z-20 px-4 sm:px-6 lg:px-8 py-3.5 flex items-center justify-between gap-4 no-print"
      style={{
        background: 'color-mix(in oklab, var(--background) 78%, transparent)',
        backdropFilter: 'saturate(150%) blur(14px)',
        WebkitBackdropFilter: 'saturate(150%) blur(14px)',
        borderBottom: '1px solid color-mix(in oklab, var(--border) 55%, transparent)',
      }}
    >
      {/* Breadcrumbs — flex-1 lets it absorb space; min-w-0 enables truncation */}
      <nav className="flex items-center gap-1.5 text-[13px] font-semibold flex-1 min-w-0" aria-label="Breadcrumb">
        {breadcrumbs.map((b, i) => {
          const last = i === breadcrumbs.length - 1;
          // Only last item gets `flex-1 truncate`; prior items stay compact and may overflow naturally.
          return (
            <div key={i} className={`flex items-center gap-1.5 ${last ? 'min-w-0 flex-shrink' : 'flex-shrink-0'}`}>
              {i > 0 && (
                <IconChevronRight size={12} className="flex-shrink-0" style={{ color: 'color-mix(in oklab, var(--muted-foreground) 55%, transparent)' }} />
              )}
              {last ? (
                <span className="truncate font-bold" style={{ color: 'var(--foreground)' }}>{b.label}</span>
              ) : (
                <button
                  onClick={() => b.href && onNav(b.href)}
                  className={'whitespace-nowrap transition-colors ' + (b.href ? 'hover:text-foreground hover:underline cursor-pointer' : 'cursor-default')}
                  style={{ color: 'var(--muted-foreground)' }}
                  disabled={!b.href}
                >
                  {b.label}
                </button>
              )}
            </div>
          );
        })}
      </nav>

      {/* Tools cluster */}
      <div className="flex items-center gap-1.5 flex-shrink-0">
        {/* Buscador global (P21): antes un botón decorativo sin estado ni handler — ver
            ui/global-search.jsx para el diagnóstico completo y la implementación real. */}
        <GlobalSearch onOpen={onSearchOpen} />

        {/* Theme toggle */}
        <button
          onClick={onToggleTheme}
          className="btn btn-icon"
          style={{ background: 'var(--card)', color: 'var(--muted-foreground)', border: '1px solid var(--border)' }}
          title={theme === 'light' ? 'Cambiar a oscuro' : 'Cambiar a claro'}
        >
          {theme === 'light' ? <IconMoon size={16} /> : <IconSun size={16} />}
        </button>

        {/* Correo (CRM) con badge de no-leídos — gateado por permiso: llave crm */}
        {(!window.MicosPuedeVer || window.MicosPuedeVer('crm')) && (
          <CrmMailButton />
        )}

        {/* Notificaciones de margen (campanita) — gateado por permiso: llave notificaciones-margen */}
        {(!window.MicosPuedeVer || window.MicosPuedeVer('notificaciones-margen')) && (
        <button
          className="btn btn-icon relative"
          style={{ background: 'var(--card)', color: 'var(--muted-foreground)', border: '1px solid var(--border)' }}
          title={`Notificaciones de margen (${(window.APROBACIONES || []).length})`}
          onClick={() => onNav('aprobaciones')}
        >
          <IconBell size={16} />
          {(window.APROBACIONES || []).length > 0 && (
          <span className="absolute top-1 right-1 flex items-center justify-center">
            <span className="absolute inline-flex h-3 w-3 rounded-full opacity-60 animate-ping" style={{ background: 'var(--warning-soft)' }} />
            <span className="relative inline-flex h-2 w-2 rounded-full" style={{ background: 'var(--warning-soft)', boxShadow: '0 0 0 2px var(--card)' }} />
          </span>
          )}
        </button>
        )}

        {/* Ajustes de inventario (check/paquete) — gateado por permiso: llave ajustes-inventario */}
        {(!window.MicosPuedeVer || window.MicosPuedeVer('ajustes-inventario')) && (
        <button
          className="btn btn-icon relative"
          style={{ background: 'var(--card)', color: 'var(--muted-foreground)', border: '1px solid var(--border)' }}
          title={`Ajustes de inventario (${(window.AJUSTES_ENTREGA || []).length})`}
          onClick={() => onNav('ajustes-inventario')}
        >
          <IconCheckCircle size={16} />
          {(window.AJUSTES_ENTREGA || []).length > 0 && (
          <span className="absolute top-1 right-1 flex items-center justify-center">
            <span className="absolute inline-flex h-3 w-3 rounded-full opacity-60 animate-ping" style={{ background: 'var(--warning-soft)' }} />
            <span className="relative inline-flex h-2 w-2 rounded-full" style={{ background: 'var(--warning-soft)', boxShadow: '0 0 0 2px var(--card)' }} />
          </span>
          )}
        </button>
        )}

        {/* Configuración (datos de empresa, permisos, datos/respaldo) */}
        <button
          onClick={() => onNav('configuracion')}
          className="btn btn-icon"
          style={{ background: 'var(--card)', color: 'var(--muted-foreground)', border: '1px solid var(--border)' }}
          title="Configuración"
        >
          <IconSettings size={16} />
        </button>

        <div className="w-px h-5 mx-0.5" style={{ background: 'var(--border)' }} />

        {/* Avatar + menú de usuario */}
        <HeaderUserMenu user={user} />
      </div>
    </header>
  );
}

// ─── Menú del avatar (header): nombre + cerrar sesión ──
function HeaderUserMenu({ user }) {
  const [open, setOpen] = useState(false);
  const ref = useRef(null);
  useEffect(() => {
    if (!open) return;
    const onDoc = (e) => { if (ref.current && !ref.current.contains(e.target)) setOpen(false); };
    document.addEventListener('mousedown', onDoc);
    return () => document.removeEventListener('mousedown', onDoc);
  }, [open]);

  const name = (user && user.name) || 'Usuario';
  const initials = (user && user.initials) || (name.split(' ').map((s) => s[0]).slice(0, 2).join('').toUpperCase()) || '?';
  const logout = async () => {
    try { await fetch('/api/logout', { method: 'POST', credentials: 'same-origin' }); } catch (_) {}
    try { localStorage.removeItem('micos-user'); sessionStorage.removeItem('micos-user'); } catch (_) {}
    window.location.replace((window.ROUTES && window.ROUTES.LOGIN) || '/login');
  };

  return (
    <div className="relative" ref={ref}>
      <button
        className="flex items-center gap-2 pl-1 pr-2 h-9 rounded-xl transition-all"
        style={{ background: 'var(--card)', border: '1px solid ' + (open ? 'color-mix(in oklab, var(--accent) 35%, var(--border))' : 'var(--border)') }}
        onMouseEnter={(e) => { e.currentTarget.style.borderColor = 'color-mix(in oklab, var(--accent) 35%, var(--border))'; }}
        onMouseLeave={(e) => { e.currentTarget.style.borderColor = open ? 'color-mix(in oklab, var(--accent) 35%, var(--border))' : 'var(--border)'; }}
        title={name}
        aria-haspopup="true"
        aria-expanded={open}
        onClick={() => setOpen((v) => !v)}
      >
        <div className="h-7 w-7 rounded-lg flex items-center justify-center text-[11px] font-extrabold"
          style={{ background: 'color-mix(in oklab, var(--accent) 14%, transparent)', color: 'var(--accent)' }}>
          {initials}
        </div>
        <IconChevronDown size={13} style={{ color: 'var(--muted-foreground)', transform: open ? 'rotate(180deg)' : 'none', transition: 'transform 0.2s ease' }} />
      </button>
      {open && (
        <div className="absolute right-0 mt-2 w-64 rounded-xl overflow-hidden z-50 animate-fade-in-up"
          style={{ background: 'var(--card)', border: '1px solid var(--border)', boxShadow: '0 18px 50px -14px rgba(8,20,24,0.5)' }}>
          <div className="px-3.5 py-3 flex items-center gap-3" style={{ borderBottom: '1px solid var(--border)' }}>
            <div className="h-10 w-10 rounded-lg flex items-center justify-center text-[13px] font-extrabold flex-shrink-0"
              style={{ background: 'color-mix(in oklab, var(--accent) 14%, transparent)', color: 'var(--accent)' }}>
              {initials}
            </div>
            <div className="min-w-0">
              <p className="text-[13px] font-bold truncate" style={{ color: 'var(--foreground)' }}>{name}</p>
              {user && (user.email || user.rol) && (
                <p className="text-[11px] truncate font-mono mt-0.5" style={{ color: 'var(--muted-foreground)' }}>{user.email || user.rol}</p>
              )}
            </div>
          </div>
          <button
            onClick={() => { setOpen(false); logout(); }}
            className="w-full flex items-center gap-2.5 px-3.5 py-2.5 text-[13px] font-semibold text-left transition-colors cursor-pointer"
            style={{ color: 'var(--destructive)' }}
            onMouseEnter={(e) => { e.currentTarget.style.background = 'color-mix(in oklab, var(--destructive) 8%, transparent)'; }}
            onMouseLeave={(e) => { e.currentTarget.style.background = 'transparent'; }}
          >
            <svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2.2" strokeLinecap="round" strokeLinejoin="round">
              <path d="M9 21H5a2 2 0 0 1-2-2V5a2 2 0 0 1 2-2h4" />
              <polyline points="16 17 21 12 16 7" />
              <line x1="21" y1="12" x2="9" y2="12" />
            </svg>
            <span>Cerrar sesión</span>
          </button>
        </div>
      )}
    </div>
  );
}

Object.assign(window, { Sidebar, Header });

