/* global React, Icon, Badge, Button, Avatar */
const { useState } = React;

// Shell: Sidebar + TopBar
const NAV = [
  {route:'torre',label:'Torre de control',iconKey:'home',group:'Principal'},
  {route:'casos',label:'Bandeja de casos',iconKey:'inbox',group:'Principal',badge:31},
  {route:'workflows',label:'Workflows',iconKey:'wfs',group:'Principal'},
  {route:'adherencia',label:'Adherencia',iconKey:'heart',group:'Clínico'},
  {route:'dispensa',label:'Dispensa',iconKey:'pill',group:'Clínico'},
  {route:'facturacion',label:'Facturación',iconKey:'doc',group:'Operación'},
  {route:'analitica',label:'Analítica',iconKey:'chart',group:'Operación'},
  {route:'trazabilidad',label:'Trazabilidad',iconKey:'act',group:'Sistema'},
  {route:'costos',label:'Control de costos',iconKey:'money',group:'Sistema'},
  {route:'configuracion',label:'Configuración',iconKey:'settings',group:'Sistema'},
  {route:'portal',label:'Portal financiadores',iconKey:'briefcase',group:'Financiador'},
];

function Sidebar({route, onNav, collapsed, onToggle}) {
  const groups = Array.from(new Set(NAV.map(n=>n.group)));
  const W = collapsed ? 64 : 224;

  return <aside
    className="relative shrink-0 bg-white border-r border-slate-100 flex flex-col"
    style={{
      width: W+'px',
      transition: 'width 200ms ease-in-out',
      boxShadow: '1px 0 0 rgba(15,23,42,0.05)'
    }}>

    {/* Toggle button — sits on the right edge, vertically centered. Low opacity
        at rest, fully visible on hover. */}
    <button
      type="button"
      aria-label={collapsed ? 'Expandir sidebar' : 'Colapsar sidebar'}
      onClick={onToggle}
      className="absolute top-1/2 -translate-y-1/2 -right-3 z-30 w-6 h-6 rounded-full bg-white border border-slate-200 flex items-center justify-center text-ink-500 hover:text-helios-700 hover:border-helios-300 opacity-30 hover:opacity-100 transition-opacity duration-200 shadow-sm">
      {collapsed
        ? <Icon.chevR c="w-3.5 h-3.5"/>
        : <Icon.chevL c="w-3.5 h-3.5"/>}
    </button>

    {/* Logo — full lockup when expanded, isotipo only when collapsed */}
    <div className={'pt-5 pb-3 flex items-center overflow-hidden '+(collapsed?'justify-center px-0':'px-5')}
         style={{transition:'padding 200ms ease-in-out'}}>
      {collapsed
        ? <img src={(window.__resources && window.__resources.logoIso) || 'assets/helios-isotipo.jpg'} alt="Helios Salud" className="w-9 h-9 object-contain rounded-md"
               style={{transition:'opacity 200ms ease-in-out'}}/>
        : <img src={(window.__resources && window.__resources.logoFull) || 'assets/helios-color.jpg'} alt="Helios Salud" className="h-9 w-auto object-contain"
               style={{transition:'opacity 200ms ease-in-out', opacity:1}}/>}
    </div>

    <nav className={'flex-1 overflow-y-auto overflow-x-hidden pb-4 '+(collapsed?'px-2':'px-3')}
         style={{transition:'padding 200ms ease-in-out'}}>
      {groups.map((g, gi) => <div key={g} className="mb-1">
        {collapsed
          ? (gi>0 && <div className="mx-2 my-2 h-px bg-slate-100"/>)
          : <div className="px-2 pt-3 pb-1 font-mono text-[9.5px] font-semibold tracking-wider uppercase text-ink-400 transition-opacity duration-200">{g}</div>}
        {NAV.filter(n=>n.group===g).map(item => {
          const I = Icon[item.iconKey];
          const active = item.route===route
            || (route==='caso' && item.route==='casos')
            || (route==='workflow' && item.route==='workflows');
          return <button
            key={item.route}
            onClick={()=>onNav(item.route)}
            title={collapsed ? item.label : undefined}
            className={['group relative w-full flex items-center rounded-lg text-[12.5px] leading-[18px] font-medium text-left transition-colors',
              collapsed ? 'justify-center px-0 py-2.5' : 'gap-2.5 px-2 py-2',
              active
                ? 'bg-helios-50 text-helios-700 font-semibold'
                : 'text-ink-700 hover:bg-slate-50'].join(' ')}>

            {/* Active indicator bar (3px) on the left, visible in both states */}
            {active && <span
              className="absolute left-0 top-1.5 bottom-1.5 w-[3px] rounded-r-full bg-helios-600"
              aria-hidden="true"/>}

            <span className={'w-[18px] h-[18px] inline-flex items-center justify-center shrink-0 relative '+(active?'text-helios-600':'')}>
              <I c="w-4 h-4"/>
              {collapsed && item.badge && <span className="absolute -top-0.5 -right-0.5 w-2 h-2 rounded-full bg-[#E04B4B] ring-2 ring-white" aria-label={`${item.badge} pendientes`}/>}
            </span>

            {!collapsed && <>
              <span className="flex-1 truncate transition-opacity duration-200">{item.label}</span>
              {item.badge && <span className="bg-[#E04B4B] text-white text-[10px] font-bold font-mono px-1.5 rounded-full leading-[14px]">{item.badge}</span>}
              {item.pill && <span className="bg-helios-100 text-helios-700 text-[9.5px] font-bold px-1.5 py-0.5 rounded-full leading-[14px]">{item.pill}</span>}
            </>}

            {/* Tooltip shown on hover when collapsed */}
            {collapsed && <span
              role="tooltip"
              className="pointer-events-none absolute left-full top-1/2 -translate-y-1/2 ml-3 px-2 py-1 rounded-md bg-ink-800 text-white text-[11px] font-medium whitespace-nowrap opacity-0 group-hover:opacity-100 transition-opacity duration-150 z-40 shadow-lg">
              {item.label}
              {item.badge && <span className="ml-1.5 bg-[#E04B4B] px-1 rounded text-[9px] font-mono">{item.badge}</span>}
            </span>}
          </button>;
        })}
      </div>)}
    </nav>

    {/* Footer: full user card when expanded, avatar only when collapsed */}
    <SidebarUserCard collapsed={collapsed}/>
  </aside>;
}

// ---------- User card + menu (logout) ----------
function SidebarUserCard({collapsed}) {
  const [open, setOpen] = React.useState(false);
  const rootRef = React.useRef(null);
  React.useEffect(()=>{
    if (!open) return;
    const onDoc = (e)=>{ if (rootRef.current && !rootRef.current.contains(e.target)) setOpen(false); };
    const onEsc = (e)=>{ if (e.key==='Escape') setOpen(false); };
    document.addEventListener('mousedown', onDoc);
    document.addEventListener('keydown', onEsc);
    return ()=>{ document.removeEventListener('mousedown', onDoc); document.removeEventListener('keydown', onEsc); };
  },[open]);
  const logout = () => {
    try { sessionStorage.removeItem('helios_os_logged_in'); } catch(e){}
    if (typeof window.__heliosLogout === 'function') window.__heliosLogout();
    else window.location.reload();
  };
  return <div ref={rootRef} className="relative">
    <div className={'border-t border-slate-100 flex items-center '+(collapsed?'justify-center px-0 py-3':'gap-2.5 px-4 py-3')}
         style={{transition:'padding 200ms ease-in-out'}}>
      {collapsed
        ? <button
            type="button"
            onClick={()=>setOpen(o=>!o)}
            aria-label="Menú de usuario"
            className="rounded-full hover:ring-2 hover:ring-helios-200 transition focus:outline-none focus:ring-2 focus:ring-helios-300">
            <Avatar name="Juan Cruz" size="sm"/>
          </button>
        : <>
            <Avatar name="Juan Cruz" size="sm"/>
            <div className="min-w-0 flex-1 transition-opacity duration-200">
              <div className="text-[12px] font-semibold text-ink-800 truncate">Juan Cruz</div>
              <div className="text-[10.5px] text-ink-400">Operación · Obispo Trejo</div>
            </div>
            <button
              type="button"
              onClick={()=>setOpen(o=>!o)}
              aria-label="Abrir menú de usuario"
              aria-expanded={open}
              className={'w-7 h-7 rounded-md flex items-center justify-center transition '+(open?'bg-slate-100 text-ink-700':'text-ink-400 hover:bg-slate-100 hover:text-ink-600')}>
              <svg viewBox="0 0 24 24" className="w-4 h-4" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round">
                <circle cx="12" cy="5" r="1.4"/><circle cx="12" cy="12" r="1.4"/><circle cx="12" cy="19" r="1.4"/>
              </svg>
            </button>
          </>}
    </div>
    {open && <div
      role="menu"
      className={'absolute z-40 bg-white border border-slate-200 rounded-lg shadow-pop py-1 min-w-[200px] '+(collapsed?'left-full ml-2 bottom-2':'left-3 right-3 bottom-full mb-1.5')}
      style={{boxShadow:'0 12px 40px -12px rgba(8,11,18,0.22), 0 4px 12px -4px rgba(8,11,18,0.08)'}}>
      <div className="px-3 py-2 border-b border-slate-100">
        <div className="text-[11.5px] font-semibold text-ink-800 truncate">Juan Cruz</div>
        <div className="text-[10px] text-ink-400 truncate">juancruz@heliossalud.com</div>
      </div>
      <button
        role="menuitem"
        onClick={()=>{ setOpen(false); /* perfil placeholder */ }}
        className="w-full text-left px-3 py-1.5 text-[11.5px] text-ink-700 hover:bg-slate-50 flex items-center gap-2 transition">
        <svg viewBox="0 0 24 24" className="w-3.5 h-3.5 text-ink-500" fill="none" stroke="currentColor" strokeWidth="1.8" strokeLinecap="round" strokeLinejoin="round">
          <circle cx="12" cy="8" r="4"/><path d="M4 21c0-4 4-6 8-6s8 2 8 6"/>
        </svg>
        Mi perfil
      </button>
      <button
        role="menuitem"
        onClick={()=>{ setOpen(false); /* settings placeholder */ }}
        className="w-full text-left px-3 py-1.5 text-[11.5px] text-ink-700 hover:bg-slate-50 flex items-center gap-2 transition">
        <svg viewBox="0 0 24 24" className="w-3.5 h-3.5 text-ink-500" fill="none" stroke="currentColor" strokeWidth="1.8" strokeLinecap="round" strokeLinejoin="round">
          <circle cx="12" cy="12" r="3"/>
          <path d="M19.4 15a1.65 1.65 0 0 0 .33 1.82l.06.06a2 2 0 1 1-2.83 2.83l-.06-.06a1.65 1.65 0 0 0-1.82-.33 1.65 1.65 0 0 0-1 1.51V21a2 2 0 1 1-4 0v-.09A1.65 1.65 0 0 0 9 19.4a1.65 1.65 0 0 0-1.82.33l-.06.06a2 2 0 1 1-2.83-2.83l.06-.06a1.65 1.65 0 0 0 .33-1.82 1.65 1.65 0 0 0-1.51-1H3a2 2 0 1 1 0-4h.09A1.65 1.65 0 0 0 4.6 9a1.65 1.65 0 0 0-.33-1.82l-.06-.06a2 2 0 1 1 2.83-2.83l.06.06a1.65 1.65 0 0 0 1.82.33H9a1.65 1.65 0 0 0 1-1.51V3a2 2 0 1 1 4 0v.09a1.65 1.65 0 0 0 1 1.51 1.65 1.65 0 0 0 1.82-.33l.06-.06a2 2 0 1 1 2.83 2.83l-.06.06a1.65 1.65 0 0 0-.33 1.82V9a1.65 1.65 0 0 0 1.51 1H21a2 2 0 1 1 0 4h-.09a1.65 1.65 0 0 0-1.51 1z"/>
        </svg>
        Preferencias
      </button>
      <div className="h-px bg-slate-100 my-1"/>
      <button
        role="menuitem"
        onClick={logout}
        className="w-full text-left px-3 py-1.5 text-[11.5px] text-[#B93535] hover:bg-red-50 flex items-center gap-2 transition font-medium">
        <svg viewBox="0 0 24 24" className="w-3.5 h-3.5" fill="none" stroke="currentColor" strokeWidth="1.8" 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>
        Cerrar sesión
      </button>
    </div>}
  </div>;
}

const INITIAL_NOTIFS = [
  {id:1, tipo:'CRÍTICA', cat:'clinico', icon:'danger', unread:true, titulo:'Escalamiento urgente · P-0221 Roberto Tonini', desc:'HbA1c 9.2% + IC estadio B. Requiere llamada médica en las próximas 4 hs.', tiempo:'hace 8 min', go:['caso','P-0221']},
  {id:2, tipo:'ADHERENCIA', cat:'adherencia', icon:'sun', unread:true, titulo:'Gap de adherencia detectado · P-0428 María Elena Fernández Rossi', desc:'22 días sin retirar Dulaglutida. WF-ADH iniciado automáticamente.', tiempo:'hace 42 min', go:['caso','P-0428']},
  {id:3, tipo:'RECETA', cat:'adherencia', icon:'sun', unread:true, titulo:'3 recetas vencen en menos de 7 días', desc:'P-0517 Pedro Alvarado · P-0634 Javier Ramírez · P-0703 Verónica Colombo.', tiempo:'hace 1 hs', go:['adherencia']},
  {id:4, tipo:'FACTURACIÓN', cat:'facturacion', icon:'danger', unread:true, titulo:'Diferencia de precio detectada · P-0189 Carolina Mazzanti', desc:'Insulina Glargina fuera de rango OSDE (+6.2%). Requiere revisión antes del cierre.', tiempo:'hace 2 hs', go:['facturacion']},
  {id:5, tipo:'SISTEMA', cat:'sistema', icon:'danger', unread:true, titulo:'Integración caída · Droguería Nacional', desc:'Timeout en consulta de stock. Sin sincronización hace 2 hs. 5 dispensas Interior en riesgo.', tiempo:'hace 2 hs', go:['configuracion']},
  {id:6, tipo:'ADHERENCIA', cat:'adherencia', icon:'sun', unread:true, titulo:'Sin respuesta tras 3 intentos · P-0811 Esteban Funes', desc:'WhatsApp + SMS sin respuesta. Considerar llamada directa o escalamiento.', tiempo:'hace 3 hs', go:['adherencia']},
  {id:7, tipo:'FACTURACIÓN', cat:'facturacion', icon:'helios', unread:true, titulo:'8 días para el cierre mensual', desc:'18 casos con documentación incompleta. $1.180.000 ARS en riesgo.', tiempo:'hace 5 hs', go:['facturacion']},
  {id:8, tipo:'SISTEMA', cat:'sistema', icon:'ok', unread:false, titulo:'WF-ADH resolvió 48 casos esta semana', desc:'Tasa de resolución automática: 78%. +4pp respecto a la semana anterior.', tiempo:'ayer', go:['workflows','WF-ADH']},
  {id:9, tipo:'ADHERENCIA', cat:'adherencia', icon:'ok', unread:false, titulo:'Caso resuelto · P-0312 Jorge Benítez', desc:'Paciente confirmó retiro para hoy 15:00–18:00 · Farmacity Caballito.', tiempo:'ayer', go:['caso','P-0312']},
  {id:10, tipo:'FACTURACIÓN', cat:'facturacion', icon:'ok', unread:false, titulo:'Legajo armado automáticamente · P-0402 Lucía Bravo', desc:'$186.400 ARS listos para facturar a OSDE 310.', tiempo:'ayer', go:['facturacion']},
  {id:11, tipo:'SISTEMA', cat:'sistema', icon:'helios', unread:false, titulo:'Precios actualizados · 3 financiadores', desc:'OSDE, Swiss Medical y Galeno sincronizaron nuevos valores de referencia.', tiempo:'hace 2 días', go:['configuracion']},
  {id:12, tipo:'SISTEMA', cat:'sistema', icon:'ok', unread:false, titulo:'Backup del sistema completado', desc:'Snapshot diario generado correctamente. 4.2 GB almacenados.', tiempo:'hace 2 días', go:['trazabilidad']},
];

const NOTIF_ICON_STYLES = {
  danger: {bg:'bg-[#FBE8E8]', fg:'text-[#B93535]'},
  sun:    {bg:'bg-[#FDF0D9]', fg:'text-[#A06A12]'},
  helios: {bg:'bg-helios-100', fg:'text-helios-700'},
  ok:     {bg:'bg-[#DDF1E4]', fg:'text-[#1E8057]'},
};

function NotifIcon({kind, c='w-4 h-4'}) {
  if (kind==='danger') return <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round" className={c}><path d="M12 9v4"/><path d="M12 17h.01"/><path d="M10.29 3.86 1.82 18a2 2 0 0 0 1.71 3h16.94a2 2 0 0 0 1.71-3L13.71 3.86a2 2 0 0 0-3.42 0Z"/></svg>;
  if (kind==='sun')    return <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round" className={c}><circle cx="12" cy="12" r="4"/><path d="M12 3v2M12 19v2M5 12H3M21 12h-2M6.3 6.3 4.9 4.9M19.1 19.1l-1.4-1.4M6.3 17.7l-1.4 1.4M19.1 4.9l-1.4 1.4"/></svg>;
  if (kind==='helios') return <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round" className={c}><circle cx="12" cy="12" r="9"/><path d="M12 7v5l3 2"/></svg>;
  return <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2.2" strokeLinecap="round" strokeLinejoin="round" className={c}><path d="M20 6 9 17l-5-5"/></svg>;
}

function NotificationsPanel({notifs, onClose, onMarkRead, onMarkAllRead, onNavigate}) {
  const [tab, setTab] = React.useState('todas');
  const unreadCount = notifs.filter(n=>n.unread).length;
  const filtered = tab==='todas' ? notifs : tab==='noleidas' ? notifs.filter(n=>n.unread) : notifs.filter(n=>n.cat==='sistema');

  return <div className="absolute top-full right-0 mt-2 w-[400px] max-h-[560px] bg-white border border-slate-200 rounded-xl shadow-[0_18px_40px_-12px_rgba(15,23,42,0.25),0_4px_10px_-3px_rgba(15,23,42,0.08)] z-50 flex flex-col overflow-hidden"
    style={{animation:'slideUp 150ms ease-out both'}}>
    <div className="px-4 pt-4 pb-3 border-b border-slate-100">
      <div className="flex items-center justify-between mb-3">
        <div className="flex items-baseline gap-1.5">
          <h3 className="text-[14px] font-semibold text-ink-800">Notificaciones</h3>
          {unreadCount>0 && <span className="text-[11.5px] font-mono text-ink-400">({unreadCount})</span>}
        </div>
        <button onClick={onMarkAllRead} disabled={unreadCount===0}
          className="text-[11.5px] font-medium text-helios-600 hover:text-helios-700 disabled:text-ink-300 disabled:cursor-not-allowed transition-colors">
          Marcar todas como leídas
        </button>
      </div>
      <div className="flex items-center gap-0.5 bg-slate-50 rounded-lg p-0.5">
        {[{k:'todas',l:'Todas'},{k:'noleidas',l:'No leídas'},{k:'sistema',l:'Sistema'}].map(t =>
          <button key={t.k} onClick={()=>setTab(t.k)}
            className={'flex-1 px-2.5 py-1.5 text-[11.5px] font-medium rounded-md transition-colors '+(tab===t.k?'bg-white text-ink-800 shadow-sm':'text-ink-500 hover:text-ink-700')}>
            {t.l}{t.k==='noleidas' && unreadCount>0 && <span className="ml-1 font-mono text-[10px] text-helios-600">{unreadCount}</span>}
          </button>)}
      </div>
    </div>
    <div className="flex-1 overflow-y-auto">
      {filtered.length === 0
        ? <div className="px-6 py-12 text-center">
            <div className="w-12 h-12 mx-auto mb-3 rounded-full bg-[#DDF1E4] flex items-center justify-center">
              <NotifIcon kind="ok" c="w-6 h-6 text-[#1E8057]"/>
            </div>
            <div className="text-[13px] font-semibold text-ink-800 mb-1">Todo al día</div>
            <div className="text-[11.5px] text-ink-500">No tenés notificaciones pendientes.</div>
          </div>
        : filtered.map(n => {
            const st = NOTIF_ICON_STYLES[n.icon] || NOTIF_ICON_STYLES.helios;
            return <button key={n.id} onClick={()=>{ onMarkRead(n.id); onNavigate(n.go); onClose(); }}
              className={'w-full text-left px-4 py-3 border-b border-slate-100 last:border-0 flex items-start gap-3 hover:bg-slate-50 transition-colors '+(n.unread?'bg-helios-50/30':'')}>
              <div className={'w-8 h-8 rounded-full flex items-center justify-center shrink-0 '+st.bg+' '+st.fg}>
                <NotifIcon kind={n.icon} c="w-4 h-4"/>
              </div>
              <div className="flex-1 min-w-0">
                <div className="flex items-start gap-2">
                  <div className="flex-1 min-w-0">
                    <div className="text-[9px] font-mono uppercase tracking-wider font-semibold text-ink-400 mb-0.5">{n.tipo}</div>
                    <div className="text-[12.5px] font-semibold text-ink-800 leading-snug mb-0.5">{n.titulo}</div>
                    <div className="text-[11.5px] text-ink-500 leading-snug">{n.desc}</div>
                    <div className="text-[10.5px] font-mono text-ink-400 mt-1.5">{n.tiempo}</div>
                  </div>
                  {n.unread && <span className="w-2 h-2 rounded-full bg-helios-600 shrink-0 mt-1" aria-label="No leída"/>}
                </div>
              </div>
            </button>;
          })}
    </div>
    <div className="border-t border-slate-100 px-4 py-2.5 bg-slate-50/50">
      <button onClick={()=>{ onNavigate(['trazabilidad']); onClose(); }}
        className="w-full text-[12px] font-medium text-helios-600 hover:text-helios-700 py-1 transition-colors">
        Ver historial completo →
      </button>
    </div>
  </div>;
}

function TopBar({crumbs=[], onNav}) {
  const [notifs, setNotifs] = React.useState(INITIAL_NOTIFS);
  const [open, setOpen] = React.useState(false);
  const bellRef = React.useRef(null);
  const unreadCount = notifs.filter(n=>n.unread).length;

  React.useEffect(() => {
    if (!open) return;
    const onDoc = (e) => { if (bellRef.current && !bellRef.current.contains(e.target)) setOpen(false); };
    const onKey = (e) => { if (e.key==='Escape') setOpen(false); };
    document.addEventListener('mousedown', onDoc);
    document.addEventListener('keydown', onKey);
    return () => { document.removeEventListener('mousedown', onDoc); document.removeEventListener('keydown', onKey); };
  }, [open]);

  const markRead = (id) => setNotifs(ns => ns.map(n => n.id===id ? {...n, unread:false} : n));
  const markAllRead = () => setNotifs(ns => ns.map(n => ({...n, unread:false})));
  const navigate = (args) => { if (onNav && args && args.length) onNav(...args); };

  return <header className="sticky top-0 z-20 border-b border-slate-200/70 px-7 py-3 flex items-center justify-between gap-4"
    style={{background:'rgba(255,255,255,0.72)', backdropFilter:'blur(10px)'}}>
    <div className="flex items-center gap-2 min-w-0">
      {crumbs.map((c,i) => {
        const label = typeof c === 'string' ? c : c.label;
        const route = typeof c === 'string' ? null : c.route;
        const last = i===crumbs.length-1;
        return <React.Fragment key={i}>
          {i>0 && <Icon.chevR c="w-3.5 h-3.5 text-ink-300"/>}
          {route && !last
            ? <button onClick={()=>onNav && onNav(route)} className="text-[12.5px] text-ink-400 hover:text-ink-700">{label}</button>
            : <span className={'text-[12.5px] '+(last?'text-ink-800 font-semibold':'text-ink-400')}>{label}</span>}
        </React.Fragment>;
      })}
    </div>
    <div className="flex items-center gap-2">
      <div className="relative">
        <Icon.search c="w-3.5 h-3.5 absolute left-2.5 top-1/2 -translate-y-1/2 text-ink-400"/>
        <input placeholder="Buscar paciente, ID, receta…" className="pl-8 pr-3 py-1.5 text-[12px] bg-slate-50 border border-slate-200 rounded-lg w-64 focus:outline-none focus:ring-2 focus:ring-helios-400/50 focus:bg-white"/>
      </div>
      <div className="relative" ref={bellRef}>
        <button onClick={()=>setOpen(o=>!o)}
          className={'relative p-2 rounded-lg transition-colors '+(open?'bg-slate-100':'hover:bg-slate-100')}
          aria-label={`Notificaciones · ${unreadCount} sin leer`}>
          <Icon.bell c="w-4 h-4 text-ink-600"/>
          {unreadCount>0 && <span className="absolute top-1 right-1 min-w-[14px] h-[14px] px-1 bg-[#E04B4B] text-white text-[9px] font-bold rounded-full flex items-center justify-center tabular-nums">{unreadCount}</span>}
        </button>
        {open && <NotificationsPanel
          notifs={notifs}
          onClose={()=>setOpen(false)}
          onMarkRead={markRead}
          onMarkAllRead={markAllRead}
          onNavigate={navigate}/>}
      </div>
    </div>
  </header>;
}

function PageHeader({titulo, subtitulo, chip, action}) {
  return <div className="mb-5">
    {chip && <div className="mb-1.5">{chip}</div>}
    <div className="flex items-end justify-between gap-4 flex-wrap">
      <div>
        <h1 className="text-[24px] font-display font-extrabold text-ink-800 leading-tight tracking-tight">{titulo}</h1>
        {subtitulo && <p className="text-[13px] text-ink-500 mt-0.5">{subtitulo}</p>}
      </div>
      {action}
    </div>
  </div>;
}

Object.assign(window, {Sidebar, TopBar, PageHeader, NAV});
