// Componentes compartidos — ALMACO v2.0 (conectado a API real)

const { useState, useEffect, useRef, useMemo, useCallback } = React;

// ─── Helpers ─────────────────────────────────────────────────────────────────
const fmt = (n) => "$" + Number(n||0).toLocaleString("en-US", {minimumFractionDigits:2, maximumFractionDigits:2});
const fmtShort = (n) => {
  const v = Number(n || 0);
  if (v >= 1000000) return "$" + (v/1000000).toFixed(1) + "M";
  if (v >= 1000) return "$" + (v/1000).toFixed(1) + "k";
  return "$" + v.toFixed(0);
};
const toDateOnly = (s) => {
  if (!s) return null;
  const str = String(s).slice(0, 10);
  const d = new Date(str + "T00:00:00");
  return isNaN(d.getTime()) ? null : d;
};
const fmtDate = (s) => {
  const d = toDateOnly(s);
  return d ? d.toLocaleDateString("es-SV", { day:"2-digit", month:"short" }) : "—";
};
const fmtDateFull = (s) => {
  const d = toDateOnly(s);
  return d ? d.toLocaleDateString("es-SV", { day:"2-digit", month:"long", year:"numeric" }) : "—";
};

// ─── Icons ────────────────────────────────────────────────────────────────────
const Icon = ({name, size=16}) => {
  const s = {width:size, height:size, fill:"none", stroke:"currentColor", strokeWidth:"1.7", strokeLinecap:"round", strokeLinejoin:"round"};
  const paths = {
    dashboard: <><rect x="3" y="3"  width="7" height="7"/><rect x="14" y="3" width="7" height="7"/><rect x="3" y="14" width="7" height="7"/><rect x="14" y="14" width="7" height="7"/></>,
    building:  <><path d="M3 21h18"/><path d="M5 21V7l8-4v18"/><path d="M19 21V11l-6-4"/><path d="M9 9v.01"/><path d="M9 12v.01"/><path d="M9 15v.01"/><path d="M9 18v.01"/></>,
    expense:   <><path d="M12 2v20"/><path d="M17 5H9.5a3.5 3.5 0 0 0 0 7h5a3.5 3.5 0 0 1 0 7H6"/></>,
    bank:      <><path d="M3 21h18"/><path d="M3 10h18"/><path d="M5 6l7-4 7 4"/><path d="M4 10v11"/><path d="M20 10v11"/><path d="M8 14v3"/><path d="M12 14v3"/><path d="M16 14v3"/></>,
    users:     <><path d="M16 21v-2a4 4 0 0 0-4-4H6a4 4 0 0 0-4 4v2"/><circle cx="9" cy="7" r="4"/><path d="M22 21v-2a4 4 0 0 0-3-3.87"/><path d="M16 3.13a4 4 0 0 1 0 7.75"/></>,
    folder:    <path d="M3 7a2 2 0 0 1 2-2h4l2 2h8a2 2 0 0 1 2 2v9a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2V7Z"/>,
    chart:     <><path d="M3 3v18h18"/><path d="M7 14l3-3 3 3 5-5"/></>,
    bot:       <><rect x="3" y="8" width="18" height="12" rx="2"/><circle cx="9" cy="14" r="1"/><circle cx="15" cy="14" r="1"/><path d="M12 4v4"/><path d="M9 4h6"/><path d="M3 14h-1"/><path d="M21 14h1"/></>,
    bell:      <><path d="M6 8a6 6 0 0 1 12 0c0 7 3 9 3 9H3s3-2 3-9"/><path d="M10.3 21a1.94 1.94 0 0 0 3.4 0"/></>,
    search:    <><circle cx="11" cy="11" r="7"/><path d="m21 21-4.3-4.3"/></>,
    plus:      <><path d="M12 5v14"/><path d="M5 12h14"/></>,
    filter:    <path d="M22 3H2l8 9.5V19l4 2v-8.5L22 3Z"/>,
    download:  <><path d="M21 15v4a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-4"/><path d="m7 10 5 5 5-5"/><path d="M12 15V3"/></>,
    upload:    <><path d="M21 15v4a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-4"/><path d="m17 8-5-5-5 5"/><path d="M12 3v12"/></>,
    settings:  <><circle cx="12" cy="12" r="3"/><path d="M19.4 15a1.7 1.7 0 0 0 .3 1.8l.1.1a2 2 0 1 1-2.8 2.8l-.1-.1a1.7 1.7 0 0 0-1.8-.3 1.7 1.7 0 0 0-1 1.5V21a2 2 0 0 1-4 0v-.1a1.7 1.7 0 0 0-1-1.5 1.7 1.7 0 0 0-1.8.3l-.1.1a2 2 0 1 1-2.8-2.8l.1-.1a1.7 1.7 0 0 0 .3-1.8 1.7 1.7 0 0 0-1.5-1H3a2 2 0 0 1 0-4h.1a1.7 1.7 0 0 0 1.5-1 1.7 1.7 0 0 0-.3-1.8l-.1-.1a2 2 0 1 1 2.8-2.8l.1.1a1.7 1.7 0 0 0 1.8.3h.1a1.7 1.7 0 0 0 1-1.5V3a2 2 0 0 1 4 0v.1a1.7 1.7 0 0 0 1 1.5 1.7 1.7 0 0 0 1.8-.3l.1-.1a2 2 0 1 1 2.8 2.8l-.1.1a1.7 1.7 0 0 0-.3 1.8v.1a1.7 1.7 0 0 0 1.5 1H21a2 2 0 0 1 0 4h-.1a1.7 1.7 0 0 0-1.5 1Z"/></>,
    logout:    <><path d="M9 21H5a2 2 0 0 1-2-2V5a2 2 0 0 1 2-2h4"/><path d="m16 17 5-5-5-5"/><path d="M21 12H9"/></>,
    chevdown:  <path d="m6 9 6 6 6-6"/>,
    chevright: <path d="m9 18 6-6-6-6"/>,
    arrowright:<><path d="M5 12h14"/><path d="m12 5 7 7-7 7"/></>,
    arrowup:   <><path d="M7 17 17 7"/><path d="M7 7h10v10"/></>,
    arrowdown: <><path d="M7 7l10 10"/><path d="M17 7v10H7"/></>,
    check:     <path d="M20 6 9 17l-5-5"/>,
    x:         <><path d="M18 6 6 18"/><path d="m6 6 12 12"/></>,
    clock:     <><circle cx="12" cy="12" r="10"/><path d="M12 6v6l4 2"/></>,
    location:  <><path d="M21 10c0 7-9 13-9 13s-9-6-9-13a9 9 0 0 1 18 0Z"/><circle cx="12" cy="10" r="3"/></>,
    calendar:  <><rect x="3" y="4" width="18" height="18" rx="2"/><path d="M16 2v4"/><path d="M8 2v4"/><path d="M3 10h18"/></>,
    send:      <><path d="m22 2-7 20-4-9-9-4Z"/><path d="M22 2 11 13"/></>,
    sparkles:  <><path d="m12 3-2 6-6 2 6 2 2 6 2-6 6-2-6-2Z"/></>,
    refresh:   <><path d="M3 12a9 9 0 0 1 15-6.7L21 8"/><path d="M21 3v5h-5"/><path d="M21 12a9 9 0 0 1-15 6.7L3 16"/><path d="M3 21v-5h5"/></>,
    eye:       <><path d="M2 12s3-7 10-7 10 7 10 7-3 7-10 7-10-7-10-7Z"/><circle cx="12" cy="12" r="3"/></>,
    eyeoff:    <><path d="M17.94 17.94A10.07 10.07 0 0 1 12 20c-7 0-11-8-11-8a18.45 18.45 0 0 1 5.06-5.94"/><path d="M9.9 4.24A9.12 9.12 0 0 1 12 4c7 0 11 8 11 8a18.5 18.5 0 0 1-2.16 3.19"/><path d="m1 1 22 22"/></>,
    pencil:    <><path d="M11 4H4a2 2 0 0 0-2 2v14a2 2 0 0 0 2 2h14a2 2 0 0 0 2-2v-7"/><path d="m18.5 2.5 3 3L12 15l-4 1 1-4Z"/></>,
    trash:     <><path d="M3 6h18"/><path d="M19 6v14a2 2 0 0 1-2 2H7a2 2 0 0 1-2-2V6"/><path d="M8 6V4a2 2 0 0 1 2-2h4a2 2 0 0 1 2 2v2"/></>,
    dots:      <><circle cx="12" cy="5" r="1.5"/><circle cx="12" cy="12" r="1.5"/><circle cx="12" cy="19" r="1.5"/></>,
    file:      <><path d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8Z"/><path d="M14 2v6h6"/></>,
    flow:      <><circle cx="6" cy="6" r="3"/><circle cx="18" cy="18" r="3"/><path d="M6 21V9"/><path d="M18 9v12"/><path d="M3 9h18"/></>,
    paperclip: <path d="M21.4 11 12.5 19.9a5 5 0 0 1-7.1-7.1l8.5-8.5a3.5 3.5 0 0 1 5 5l-8.6 8.5a2 2 0 0 1-2.8-2.8L15 7.4"/>,
    mic:       <><rect x="9" y="2" width="6" height="13" rx="3"/><path d="M5 10v2a7 7 0 0 0 14 0v-2"/><path d="M12 19v4"/></>,
    lock:      <><rect x="3" y="11" width="18" height="11" rx="2"/><path d="M7 11V7a5 5 0 0 1 10 0v4"/></>,
    key:       <><circle cx="7.5" cy="15.5" r="5.5"/><path d="m21 2-9.6 9.6"/><path d="m15.5 7.5 3 3L22 7l-3-3"/></>,
    shieldcheck: <><path d="M12 22s8-4 8-10V5l-8-3-8 3v7c0 6 8 10 8 10z"/><path d="m9 12 2 2 4-4"/></>,
    user:      <><path d="M20 21v-2a4 4 0 0 0-4-4H8a4 4 0 0 0-4 4v2"/><circle cx="12" cy="7" r="4"/></>,
    globe:     <><circle cx="12" cy="12" r="10"/><path d="M2 12h20"/><path d="M12 2a15.3 15.3 0 0 1 4 10 15.3 15.3 0 0 1-4 10 15.3 15.3 0 0 1-4-10 15.3 15.3 0 0 1 4-10z"/></>,
    cpu:       <><rect x="4" y="4" width="16" height="16" rx="2"/><rect x="9" y="9" width="6" height="6"/><path d="M9 1v3"/><path d="M15 1v3"/><path d="M9 20v3"/><path d="M15 20v3"/><path d="M20 9h3"/><path d="M20 14h3"/><path d="M1 9h3"/><path d="M1 14h3"/></>,
    sliders:   <><path d="M4 21v-7"/><path d="M4 10V3"/><path d="M12 21v-9"/><path d="M12 8V3"/><path d="M20 21v-5"/><path d="M20 12V3"/><path d="M1 14h6"/><path d="M9 8h6"/><path d="M17 16h6"/></>,
    link:      <><path d="M10 13a5 5 0 0 0 7.5.5l3-3a5 5 0 0 0-7-7L11.5 5.5"/><path d="M14 11a5 5 0 0 0-7.5-.5l-3 3a5 5 0 0 0 7 7l1.5-1.5"/></>,
    edit:      <><path d="M11 4H4a2 2 0 0 0-2 2v14a2 2 0 0 0 2 2h14a2 2 0 0 0 2-2v-7"/><path d="m18.5 2.5 3 3L12 15l-4 1 1-4Z"/></>,
    'user-plus': <><path d="M16 21v-2a4 4 0 0 0-4-4H5a4 4 0 0 0-4 4v2"/><circle cx="8.5" cy="7" r="4"/><path d="M20 8v6"/><path d="M23 11h-6"/></>,
    shield:    <><path d="M12 22s8-4 8-10V5l-8-3-8 3v7c0 6 8 10 8 10z"/></>,
    'eye-off': <><path d="M17.94 17.94A10.07 10.07 0 0 1 12 20c-7 0-11-8-11-8a18.45 18.45 0 0 1 5.06-5.94"/><path d="M9.9 4.24A9.12 9.12 0 0 1 12 4c7 0 11 8 11 8a18.5 18.5 0 0 1-2.16 3.19"/><path d="m1 1 22 22"/></>,
    'bar-chart-2': <><path d="M18 20V10"/><path d="M12 20V4"/><path d="M6 20v-6"/></>,
    'hard-drive': <><path d="M22 12H2"/><path d="M5.45 5.11 2 12v6a2 2 0 0 0 2 2h16a2 2 0 0 0 2-2v-6l-3.45-6.89A2 2 0 0 0 16.76 4H7.24a2 2 0 0 0-1.79 1.11Z"/><circle cx="6.5" cy="16.5" r=".5"/></>,
    'message-square': <path d="M21 15a2 2 0 0 1-2 2H7l-4 4V5a2 2 0 0 1 2-2h14a2 2 0 0 1 2 2Z"/>,
    zap:       <path d="M13 2 3 14h9l-1 8 10-12h-9Z"/>,
  };
  return <svg viewBox="0 0 24 24" style={s}>{paths[name] || null}</svg>;
};

// ─── Avatar ───────────────────────────────────────────────────────────────────
const Avatar = ({user, size=30}) => {
  if(!user) return null;
  return (
    <div className="sb-user-avatar" style={{width:size,height:size,fontSize:size/2.7,background:user.color || "var(--yellow)"}}>
      {user.iniciales}
    </div>
  );
};

// ─── Pill ─────────────────────────────────────────────────────────────────────
const Pill = ({color="gray", dot=false, children}) => (
  <span className={`pill pill-${color}${dot?" pill-dot":""}`}>{children}</span>
);

const estadoPill = (e) => {
  const map = {
    aprobado:   {c:"green", l:"Aprobado"},
    pendiente:  {c:"yellow", l:"Pendiente"},
    rechazado:  {c:"red", l:"Rechazado"},
    enviada:    {c:"green", l:"Enviada"},
    recibida:   {c:"blue", l:"Recibida"},
    denegada:   {c:"red", l:"Denegada"},
    pagada:     {c:"green", l:"Pagada"},
    completada: {c:"green", l:"Completada"},
    "en-proceso":{c:"yellow", l:"En proceso"},
    activo:     {c:"green", l:"Activo"},
    finalizado: {c:"blue", l:"Finalizado"},
  };
  const m = map[e] || {c:"gray", l:e};
  return <Pill color={m.c} dot>{m.l}</Pill>;
};

// ─── Brand Logo ───────────────────────────────────────────────────────────────
const BrandLogo = ({size="md"}) => {
  const map = { sm:{box:30, fs1:11}, md:{box:34, fs1:13}, lg:{box:46, fs1:18} };
  const c = map[size];
  return (
    <>
      <div className="sb-logo" style={{width:c.box, height:c.box, borderRadius:Math.round(c.box*0.22)}}>
        <img src="assets/logo-almaco.png" alt="ALMACO" />
      </div>
      <div className="sb-brand-text">
        <div className="l1" style={{fontSize:c.fs1}}>app<span className="acc">.almaco</span></div>
        <div className="l2">Control de Gastos</div>
      </div>
    </>
  );
};

// ─── Donut SVG ────────────────────────────────────────────────────────────────
const Donut = ({segments, size=160, stroke=18}) => {
  const total = segments.reduce((a,s)=>a+s.value,0);
  const r = (size - stroke) / 2;
  const c = 2 * Math.PI * r;
  let offset = 0;
  return (
    <svg width={size} height={size} viewBox={`0 0 ${size} ${size}`} style={{transform:"rotate(-90deg)"}}>
      <circle cx={size/2} cy={size/2} r={r} fill="none" stroke="var(--bg-3)" strokeWidth={stroke}/>
      {segments.map((s,i) => {
        const len = total > 0 ? (s.value/total) * c : 0;
        const el = (
          <circle key={i} cx={size/2} cy={size/2} r={r} fill="none"
            stroke={s.color} strokeWidth={stroke}
            strokeDasharray={`${len} ${c}`}
            strokeDashoffset={-offset}
            strokeLinecap="butt"
          />
        );
        offset += len;
        return el;
      })}
    </svg>
  );
};

// ─── Sparkline ────────────────────────────────────────────────────────────────
const Sparkline = ({data, color="var(--yellow)", width=80, height=36}) => {
  if (!data || !data.length) return null;
  const max = Math.max(...data);
  const min = Math.min(...data);
  const range = max - min || 1;
  const pts = data.map((v,i) => {
    const x = (i/(data.length-1)) * width;
    const y = height - ((v - min)/range) * height;
    return `${x},${y}`;
  }).join(" ");
  const fill = `${pts} ${width},${height} 0,${height}`;
  return (
    <svg viewBox={`0 0 ${width} ${height}`} width={width} height={height} preserveAspectRatio="none" className="kpi-spark">
      <polygon points={fill} fill={color} opacity="0.08"/>
      <polyline points={pts} fill="none" stroke={color} strokeWidth="1.6" strokeLinecap="round"/>
    </svg>
  );
};

// ─── KPI Card ─────────────────────────────────────────────────────────────────
const KpiCard = ({label, value, delta, deltaDir="neutral", icon, featured=false, spark, sparkColor, meta}) => (
  <div className={`kpi-card${featured?" featured":""}`}>
    <div className="kpi-head">
      <div className="kpi-label">{label}</div>
      <div className="kpi-icon"><Icon name={icon} size={14}/></div>
    </div>
    <div className="kpi-value">{value}</div>
    <div className="kpi-meta">
      {delta && <span className={`kpi-delta ${deltaDir}`}>
        {deltaDir==="up" && <Icon name="arrowup" size={11}/>}
        {deltaDir==="down" && <Icon name="arrowdown" size={11}/>}
        {delta}
      </span>}
      {meta && <span>{meta}</span>}
    </div>
    {spark && <Sparkline data={spark} color={sparkColor || "var(--yellow)"}/>}
  </div>
);

// ─── Spinner ──────────────────────────────────────────────────────────────────
const Spinner = ({size=20, color="var(--yellow)"}) => (
  <svg width={size} height={size} viewBox="0 0 24 24" fill="none" stroke={color} strokeWidth="2" strokeLinecap="round"
    style={{animation:"spin 0.8s linear infinite"}}>
    <style>{`@keyframes spin{from{transform:rotate(0deg)}to{transform:rotate(360deg)}}`}</style>
    <path d="M12 2a10 10 0 0 1 0 20A10 10 0 0 1 12 2" opacity="0.25"/>
    <path d="M12 2a10 10 0 0 1 9.95 9" opacity="1"/>
  </svg>
);

// ─── Empty State ──────────────────────────────────────────────────────────────
const EmptyState = ({icon="file", title, sub, action}) => (
  <div style={{display:"flex",flexDirection:"column",alignItems:"center",justifyContent:"center",padding:"60px 20px",gap:14}}>
    <div style={{width:52,height:52,borderRadius:12,background:"var(--bg-3)",border:"1px solid var(--border)",display:"flex",alignItems:"center",justifyContent:"center",color:"var(--text-3)"}}>
      <Icon name={icon} size={22}/>
    </div>
    <div style={{textAlign:"center"}}>
      <div style={{fontWeight:600,fontSize:14,marginBottom:6}}>{title}</div>
      {sub && <div style={{fontSize:12.5,color:"var(--text-3)",maxWidth:320}}>{sub}</div>}
    </div>
    {action}
  </div>
);

// ─── Error Banner ─────────────────────────────────────────────────────────────
const ErrorBanner = ({msg, onRetry}) => (
  <div style={{margin:"0 0 16px",padding:"12px 16px",background:"var(--red-dim)",border:"1px solid rgba(248,81,73,0.25)",borderRadius:8,display:"flex",alignItems:"center",justifyContent:"space-between",gap:12}}>
    <div style={{display:"flex",alignItems:"center",gap:10,color:"var(--red)",fontSize:13}}>
      <Icon name="x" size={15}/> {msg}
    </div>
    {onRetry && <button className="btn-ghost" style={{fontSize:12,color:"var(--red)"}} onClick={onRetry}>Reintentar</button>}
  </div>
);

// ─── Modal base ───────────────────────────────────────────────────────────────
const Modal = ({title, sub, onClose, children, width=480}) => (
  <div className="modal-overlay" onClick={e=>e.target===e.currentTarget&&onClose()}>
    <div className="modal" style={{width, maxWidth:"96vw"}}>
      <div className="modal-head">
        <div>
          <div className="modal-title">{title}</div>
          {sub && <div style={{fontSize:12,color:"var(--text-3)",marginTop:3}}>{sub}</div>}
        </div>
        <button className="modal-close" onClick={onClose}><Icon name="x" size={16}/></button>
      </div>
      <div className="modal-body">{children}</div>
    </div>
  </div>
);

// ─── Topbar ───────────────────────────────────────────────────────────────────
const Topbar = ({crumbs=[], user, setRoute}) => (
  <div className="topbar">
    <div className="tb-breadcrumb">
      {crumbs.map((c,i) => (
        <React.Fragment key={i}>
          {i>0 && <span className="sep"><Icon name="chevright" size={12}/></span>}
          <span className={i===crumbs.length-1?"crumb":""}>{c}</span>
        </React.Fragment>
      ))}
    </div>
    <div className="tb-search">
      <Icon name="search" size={14}/>
      <input placeholder="Buscar gastos, proveedores, proyectos…" />
      <span className="kbd">⌘ K</span>
    </div>
    <div className="tb-actions">
      <button className="tb-icon-btn" title="Configuración" onClick={()=>setRoute&&setRoute("config")}><Icon name="settings" size={16}/></button>
    </div>
  </div>
);

// ─── Permisos por rol ─────────────────────────────────────────────────────────
// admin/gerencia: todo. finanzas: + transferencias. rrhh: + planillas.
// campo/usuario: solo lo basico (dashboard, proyectos, gastos, archivos, reportes, ia).
const ROLE_ACCESS = {
  admin:    ["dashboard","proyectos","gastos","transferencias","planillas","archivos","reportes","ia","config"],
  gerencia: ["dashboard","proyectos","gastos","transferencias","planillas","archivos","reportes","ia","config"],
  finanzas: ["dashboard","proyectos","gastos","transferencias","archivos","reportes","ia"],
  rrhh:     ["dashboard","proyectos","planillas","archivos","reportes","ia"],
  campo:    ["dashboard","proyectos","gastos","archivos","reportes","ia"],
  usuario:  ["dashboard","proyectos","archivos","reportes","ia"],
};
const canSee = (rol, route) => (ROLE_ACCESS[rol] || []).includes(route);

// ─── Sidebar ──────────────────────────────────────────────────────────────────
const Sidebar = ({route, setRoute, user, onLogout}) => {
  const items = [
    { id:"dashboard",     label:"Dashboard",       icon:"dashboard" },
    { id:"proyectos",     label:"Proyectos",       icon:"building" },
    { id:"gastos",        label:"Gastos",          icon:"expense" },
    { id:"transferencias",label:"Transferencias",  icon:"bank" },
    { id:"planillas",     label:"Planillas",       icon:"users" },
  ].filter(it => canSee(user?.rol, it.id));
  const items2 = [
    { id:"archivos",      label:"Archivos",        icon:"folder" },
    { id:"reportes",      label:"Reportes",        icon:"chart" },
    { id:"ia",            label:"IA Asistente",    icon:"sparkles" },
  ].filter(it => canSee(user?.rol, it.id));
  const canSeeConfig = canSee(user?.rol, "config");

  return (
    <aside className="sidebar">
      <div className="sb-brand">
        <BrandLogo size="md"/>
      </div>

      <nav className="sb-nav">
        <div className="sb-nav-group">
          <div className="sb-nav-label">Gestión</div>
          {items.map(it => (
            <div key={it.id} className={`sb-nav-item${route===it.id?" active":""}`} onClick={()=>setRoute(it.id)}>
              <span className="ic"><Icon name={it.icon} size={15}/></span>
              <span className="lbl">{it.label}</span>
            </div>
          ))}
        </div>
        <div className="sb-nav-group">
          <div className="sb-nav-label">Herramientas</div>
          {items2.map(it => (
            <div key={it.id} className={`sb-nav-item${route===it.id?" active":""}`} onClick={()=>setRoute(it.id)}>
              <span className="ic"><Icon name={it.icon} size={15}/></span>
              <span className="lbl">{it.label}</span>
            </div>
          ))}
        </div>
        {canSeeConfig && (
          <div className="sb-nav-group">
            <div className="sb-nav-label">Sistema</div>
            <div className={`sb-nav-item${route==="config"?" active":""}`} onClick={()=>setRoute("config")}>
              <span className="ic"><Icon name="settings" size={15}/></span>
              <span className="lbl">Configuración</span>
            </div>
          </div>
        )}
      </nav>

      <div className="sb-user">
        <Avatar user={user} size={32}/>
        <div className="sb-user-info">
          <div className="sb-user-name">{user.nombre}</div>
          <div className="sb-user-role">{user.rol}</div>
        </div>
        <button className="sb-user-icon" onClick={onLogout} title="Cerrar sesión"><Icon name="logout" size={14}/></button>
      </div>
    </aside>
  );
};

Object.assign(window, {
  fmt, fmtShort, fmtDate, fmtDateFull, toDateOnly,
  Icon, Avatar, Pill, estadoPill, BrandLogo,
  Donut, Sparkline, KpiCard, Spinner, EmptyState, ErrorBanner, Modal,
  Topbar, Sidebar, ROLE_ACCESS, canSee,
});
