// ============================================================
// CONTAX · LAYOUT + SHARED UI COMPONENTS
// ============================================================

const { useState, useEffect, useRef, useMemo, useCallback } = React;
const { motion, AnimatePresence } = window.framerMotion || {};

const NAV = [
  { id: 'dashboard', label: 'Panel ejecutivo', icon: 'Home',     section: 'Operación' },
  { id: 'inventario', label: 'Inventario',     icon: 'Box',      section: 'Operación' },
  { id: 'gastos',     label: 'Gastos',         icon: 'Receipt',  section: 'Operación' },
  { id: 'informe',    label: 'Informe del mes', icon: 'FileText', section: 'Reportes' },
  { id: 'nomina',     label: 'Sueldos',         icon: 'Building', section: 'Reportes' },
  { id: 'operario',   label: 'Vista Operario',  icon: 'Smartphone', section: 'Captura', badge: 'PWA' },
];

function Sidebar({ active, onNav, collapsed, onToggle }) {
  const grouped = useMemo(() => {
    const out = {};
    NAV.forEach(n => { (out[n.section] = out[n.section] || []).push(n); });
    return out;
  }, []);
  return (
    <aside className="sidebar">
      <div className="sidebar-brand">
        <div className="sidebar-brand-mark"><img src="assets/contax-mark.png" alt="Contax" /></div>
        <div className="sidebar-brand-text">
          <span className="sidebar-brand-name">CONTAX</span>
          <span className="sidebar-brand-sub">Cash Flow</span>
        </div>
      </div>
      <nav className="sidebar-nav">
        {Object.entries(grouped).map(([section, items]) => (
          <React.Fragment key={section}>
            <div className="sidebar-section-label">{section}</div>
            {items.map(item => {
              const IC = window.I[item.icon];
              return (
                <button key={item.id} className={`nav-item ${active === item.id ? 'active' : ''}`} onClick={() => onNav(item.id)}>
                  <IC className="nav-icon" size={17} />
                  <span className="nav-label">{item.label}</span>
                  {item.badge && <span className="nav-badge">{item.badge}</span>}
                </button>
              );
            })}
          </React.Fragment>
        ))}
      </nav>
      <div className="sidebar-footer">
        <button className="user-chip">
          <div className="user-avatar">AG</div>
          <div className="user-meta">
            <span className="user-name">Andres Gallon</span>
            <span className="user-role">Dueño · Barranquilla</span>
          </div>
        </button>
      </div>
      <button className="collapse-btn" onClick={onToggle} title={collapsed ? 'Expandir' : 'Colapsar'}>
        {collapsed ? <window.I.ChevronRight size={12}/> : <window.I.ChevronLeft size={12}/>}
      </button>
    </aside>
  );
}

const PERIODS = [
  { id: 'day', label: 'Hoy' },
  { id: 'week', label: 'Semana' },
  { id: 'month', label: 'Mes' },
  { id: 'quarter', label: 'Trimestre' },
];

function PeriodSwitcher({ value, onChange }) {
  return (
    <div className="period-switcher" role="tablist">
      {PERIODS.map(p => (
        <button key={p.id} className={value === p.id ? 'active' : ''} onClick={() => onChange(p.id)}>{p.label}</button>
      ))}
    </div>
  );
}

function TopBar({ crumbs, period, setPeriod, theme, setTheme, onSwitchMode }) {
  const [notifOpen, setNotifOpen] = useState(false);
  return (
    <div className="topbar">
      <div className="breadcrumb">
        {crumbs.map((c, i) => (
          <React.Fragment key={i}>
            {i > 0 && <span className="breadcrumb-sep">/</span>}
            <span className={i === crumbs.length - 1 ? 'crumb-current' : ''}>{c}</span>
          </React.Fragment>
        ))}
      </div>
      <span className="pill neutral" style={{ marginRight: 'auto' }}><window.I.Building size={11}/> Sede Barranquilla</span>
      <PeriodSwitcher value={period} onChange={setPeriod}/>
      <div style={{ position: 'relative' }}>
        <button className="icon-btn" onClick={() => setNotifOpen(o => !o)} title="Notificaciones">
          <window.I.Bell size={16}/>
          <span className="dot"/>
        </button>
        {notifOpen && <NotifDropdown onClose={() => setNotifOpen(false)}/>}
      </div>
      <button className="icon-btn" onClick={() => setTheme(theme === 'dark' ? 'light' : 'dark')} title="Cambiar tema">
        {theme === 'dark' ? <window.I.Sun size={16}/> : <window.I.Moon size={16}/>}
      </button>
      {onSwitchMode && (
        <button className="icon-btn" onClick={onSwitchMode} title="Cambiar vista" style={{ marginLeft: 2 }}>
          <svg width="15" height="15" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="1.6" strokeLinecap="round" strokeLinejoin="round">
            <rect x="6" y="2" width="12" height="20" rx="2"/><path d="M11 18h2"/>
          </svg>
        </button>
      )}
    </div>
  );
}

function NotifDropdown({ onClose }) {
  const items = window.CONTAX.NOTIFICACIONES;
  const nuevos = items.filter(i => i.nuevo).length;
  const isMobile = window.innerWidth <= 768;
  const dropStyle = isMobile ? {
    position: 'fixed', top: 56, left: 8, right: 8,
    background: 'var(--bg-elevated)', border: '1px solid var(--border-default)',
    borderRadius: 12, padding: 4, zIndex: 40,
    boxShadow: '0 12px 32px rgba(0,0,0,0.5)',
    animation: 'fadeUp .15s cubic-bezier(0.16,1,0.3,1) both',
  } : {
    position: 'absolute', top: 'calc(100% + 8px)', right: 0,
    width: 320, background: 'var(--bg-elevated)', border: '1px solid var(--border-default)',
    borderRadius: 12, padding: 4, zIndex: 40,
    boxShadow: '0 12px 32px rgba(0,0,0,0.4)',
    animation: 'fadeUp .15s cubic-bezier(0.16,1,0.3,1) both',
  };
  return (
    <>
      <div onClick={onClose} style={{ position: 'fixed', inset: 0, zIndex: 30 }}/>
      <div style={dropStyle}>
        <div style={{ padding: '10px 12px', display: 'flex', justifyContent: 'space-between', alignItems: 'center', borderBottom: '1px solid var(--border-subtle)' }}>
          <span style={{ fontSize: 13, fontWeight: 500 }}>Notificaciones</span>
          <span className="pill accent">{nuevos} nuevas</span>
        </div>
        {items.map(n => {
          const C = n.tipo === 'success' ? 'var(--success)' : n.tipo === 'warning' ? 'var(--warning)' : 'var(--accent)';
          return (
            <button key={n.id} className="user-chip" style={{ alignItems: 'flex-start', padding: 10 }}>
              <span style={{ width: 6, height: 6, borderRadius: 999, background: C, marginTop: 6, boxShadow: `0 0 0 3px color-mix(in srgb, ${C} 18%, transparent)` }}/>
              <div style={{ display: 'flex', flexDirection: 'column', gap: 2, flex: 1, minWidth: 0 }}>
                <span style={{ fontSize: 12.5, color: 'var(--text-primary)', fontWeight: 500 }}>{n.titulo}</span>
                <span style={{ fontSize: 11.5, color: 'var(--text-secondary)' }}>{n.sub}</span>
                <span style={{ fontSize: 10.5, color: 'var(--text-tertiary)', marginTop: 2 }}>{n.cuando}</span>
              </div>
            </button>
          );
        })}
      </div>
    </>
  );
}

// =============== Metric Card ===============
function MetricCard({ label, value, currency = '$', delta, deltaLabel = 'vs anterior', status, statusLabel, sparkline, pulse, hint }) {
  const ref = useRef();
  useEffect(() => {
    if (pulse && ref.current) {
      ref.current.classList.remove('pulse');
      void ref.current.offsetWidth;
      ref.current.classList.add('pulse');
    }
  }, [pulse]);
  const statusColor = status === 'success' ? 'var(--success)' : status === 'warning' ? 'var(--warning)' : status === 'danger' ? 'var(--danger)' : null;
  return (
    <div ref={ref} className={`metric ${status ? 'has-status' : ''}`} style={status ? { '--metric-status': statusColor } : {}}>
      <div className="metric-label">
        <span>{label}</span>
        {hint && <window.I.AlertCircle size={11}/>}
      </div>
      <div className="metric-value tnum">
        {currency && <span className="currency">{currency}</span>}{value}
      </div>
      <div className="metric-row">
        {delta !== undefined && (
          <span className={`metric-delta ${delta > 0 ? 'up' : delta < 0 ? 'down' : 'neutral'}`}>
            {delta > 0 ? <window.I.ArrowUpRight size={11}/> : delta < 0 ? <window.I.ArrowDownRight size={11}/> : null}
            {delta > 0 ? '+' : ''}{delta}%
            <span className="metric-delta-vs">{deltaLabel}</span>
          </span>
        )}
        {statusLabel && <span className={`pill ${status}`}><span className="dot-status"/> {statusLabel}</span>}
        {sparkline && <Sparkline data={sparkline} status={status} />}
      </div>
    </div>
  );
}

function Sparkline({ data, status }) {
  const w = 80, h = 28;
  const min = Math.min(...data), max = Math.max(...data);
  const range = max - min || 1;
  const pts = data.map((v, i) => `${(i/(data.length-1))*w},${h - ((v - min)/range) * (h-2) - 1}`).join(' ');
  const color = status === 'danger' ? 'var(--danger)' : status === 'warning' ? 'var(--warning)' : 'var(--accent)';
  return (
    <svg width={w} height={h} className="metric-spark">
      <polyline fill="none" stroke={color} strokeWidth="1.5" points={pts} strokeLinecap="round" strokeLinejoin="round"/>
      <circle cx={w} cy={h - ((data[data.length-1] - min)/range) * (h-2) - 1} r="2" fill={color}/>
    </svg>
  );
}

// =============== Charts (Recharts) ===============
const R = window.Recharts;
const tickStyle = { fontSize: 11, fontFamily: 'Geist Mono, monospace' };

function ChartArea({ data, dataKey, xKey = 'idx', height = 260 }) {
  return (
    <div className="chart-frame" style={{ height }}>
      <R.ResponsiveContainer>
        <R.AreaChart data={data} margin={{ top: 8, right: 8, left: -8, bottom: 0 }}>
          <defs>
            <linearGradient id="grad-area" x1="0" y1="0" x2="0" y2="1">
              <stop offset="0%" stopColor="var(--accent)" stopOpacity={0.42}/>
              <stop offset="100%" stopColor="var(--accent)" stopOpacity={0}/>
            </linearGradient>
          </defs>
          <R.CartesianGrid stroke="var(--grid)" vertical={false}/>
          <R.XAxis dataKey={xKey} stroke="var(--text-tertiary)" tick={tickStyle} tickLine={false} axisLine={false}/>
          <R.YAxis stroke="var(--text-tertiary)" tick={tickStyle} tickLine={false} axisLine={false} tickFormatter={(v) => window.CONTAX.COPK(v)} width={56}/>
          <R.Tooltip content={<ChartTooltip/>}/>
          <R.Area type="monotone" dataKey={dataKey} stroke="var(--accent)" strokeWidth={1.6} fill="url(#grad-area)" dot={false} activeDot={{ r: 4, strokeWidth: 0, fill: 'var(--accent)' }}/>
        </R.AreaChart>
      </R.ResponsiveContainer>
    </div>
  );
}

function ChartTooltip({ active, payload, label }) {
  if (!active || !payload || !payload.length) return null;
  return (
    <div style={{
      background: 'var(--bg-overlay)', border: '1px solid var(--border-default)',
      borderRadius: 8, padding: '8px 10px', fontSize: 12,
      boxShadow: '0 4px 16px rgba(0,0,0,0.4)',
    }}>
      <div style={{ color: 'var(--text-tertiary)', fontSize: 10.5, letterSpacing: '0.06em', textTransform: 'uppercase', marginBottom: 4 }}>{label}</div>
      {payload.map((p, i) => (
        <div key={i} style={{ display: 'flex', alignItems: 'center', gap: 6, fontFamily: 'Geist Mono, monospace' }}>
          <span style={{ width: 8, height: 8, borderRadius: 2, background: p.color || p.fill }}/>
          <span style={{ color: 'var(--text-secondary)' }}>{p.name}</span>
          <span style={{ marginLeft: 'auto', color: 'var(--text-primary)', fontVariantNumeric: 'tabular-nums' }}>{typeof p.value === 'number' ? window.CONTAX.COP(p.value) : p.value}</span>
        </div>
      ))}
    </div>
  );
}

function ChartDonut({ data, height = 260 }) {
  const total = data.reduce((a,b) => a + b.value, 0);
  return (
    <div style={{ position: 'relative', height }}>
      <R.ResponsiveContainer>
        <R.PieChart>
          <R.Pie data={data} dataKey="value" nameKey="name" innerRadius="62%" outerRadius="86%" paddingAngle={2} stroke="var(--bg-elevated)" strokeWidth={2}>
            {data.map((d,i) => <R.Cell key={i} fill={d.fill}/>)}
          </R.Pie>
          <R.Tooltip content={<ChartTooltip/>}/>
        </R.PieChart>
      </R.ResponsiveContainer>
      <div className="donut-center">
        <div>
          <div className="l">Total</div>
          <div className="v tnum">{window.CONTAX.COPK(total)}</div>
        </div>
      </div>
    </div>
  );
}

function ChartBars({ data, dataKey, xKey = 'size', height = 220, color = 'var(--accent)' }) {
  return (
    <div className="chart-frame" style={{ height }}>
      <R.ResponsiveContainer>
        <R.BarChart data={data} margin={{ top: 8, right: 8, left: -8, bottom: 0 }}>
          <R.CartesianGrid stroke="var(--grid)" vertical={false}/>
          <R.XAxis dataKey={xKey} stroke="var(--text-tertiary)" tick={tickStyle} tickLine={false} axisLine={false}/>
          <R.YAxis stroke="var(--text-tertiary)" tick={tickStyle} tickLine={false} axisLine={false} width={42}/>
          <R.Tooltip content={<ChartTooltip/>} cursor={{ fill: 'var(--bg-overlay)' }}/>
          <R.Bar dataKey={dataKey} fill={color} radius={[4,4,0,0]} maxBarSize={32}/>
        </R.BarChart>
      </R.ResponsiveContainer>
    </div>
  );
}

function CalendarHeatmap({ data }) {
  // 31 cells; map each ventas day to a date number
  const days = Array.from({ length: 31 }, (_, i) => i + 1);
  const byDay = {};
  data.forEach(d => { byDay[d.fecha.getDate()] = d; });
  return (
    <div>
      <div className="heatmap" style={{ marginBottom: 12 }}>
        {days.map(n => {
          const day = byDay[n];
          let cls = 'future';
          if (day) cls = day.estado;
          return (
            <div key={n} className={`heatmap-cell ${cls}`} title={day ? `Día ${n} · ${day.estado}${day.descuadre ? ' · ' + window.CONTAX.COP(day.descuadre) : ''}` : ''}>
              <span className="cell-label">{n}</span>
            </div>
          );
        })}
      </div>
      <div className="legend">
        <span><span className="legend-swatch" style={{ background: 'var(--success-bg)', boxShadow: 'inset 0 0 0 1px var(--success-border)' }}/> Cuadra</span>
        <span><span className="legend-swatch" style={{ background: 'var(--warning-bg)', boxShadow: 'inset 0 0 0 1px var(--warning-border)' }}/> Sobra</span>
        <span><span className="legend-swatch" style={{ background: 'var(--danger-bg)', boxShadow: 'inset 0 0 0 1px var(--danger-border)' }}/> Falta</span>
        <span><span className="legend-swatch" style={{ background: 'transparent', boxShadow: 'inset 0 0 0 1px var(--border-subtle)' }}/> Pendiente</span>
      </div>
    </div>
  );
}

// =============== Toasts ===============
const ToastContext = React.createContext({ push: () => {} });
function ToastProvider({ children }) {
  const [toasts, setToasts] = useState([]);
  const push = useCallback((msg) => {
    const id = Math.random().toString(36).slice(2);
    setToasts(t => [...t, { id, msg }]);
    setTimeout(() => setToasts(t => t.filter(x => x.id !== id)), 2400);
  }, []);
  return (
    <ToastContext.Provider value={{ push }}>
      {children}
      <div className="toast-container">
        {toasts.map(t => <div key={t.id} className="toast"><span className="toast-dot"/>{t.msg}</div>)}
      </div>
    </ToastContext.Provider>
  );
}

Object.assign(window, { Sidebar, TopBar, PeriodSwitcher, MetricCard, Sparkline, ChartArea, ChartDonut, ChartBars, ChartTooltip, CalendarHeatmap, ToastProvider, ToastContext });
