/* SISTEMA · KPIs · Saúde do Agente
   4 quadrants × 4 KPIs = 16 cards. Each card has status dot, value, target,
   sparkline, delta, severity pill. Click → drill-down side panel. */

const KPI_DATA = {
  qualidade: {
    icon: '🎯',
    title: 'Qualidade de Resposta',
    accent: '#22d3ee',
    items: [
      { id: 'rag', nome: 'Precisão das respostas', tech: 'RAG accuracy', valor: 92.3, unit: '%', target: '>90%', status: 'green', severidade: 'Crítico', delta: '+1.2%', deltaDir: 'up', spark: [88,89,90,91.5,91,92,92.3] },
      { id: 'halu', nome: 'Taxa de alucinações', tech: 'Hallucination rate', valor: 1.4, unit: '%', target: '<2%', status: 'green', severidade: 'Crítico', delta: '-0.3%', deltaDir: 'down-good', spark: [1.7,1.8,1.6,1.5,1.5,1.4,1.4] },
      { id: 'csat', nome: 'CSAT', tech: 'Satisfação utilizador', valor: 4.5, unit: '/5', target: '>4.2', status: 'green', severidade: 'Importante', delta: '+0.1', deltaDir: 'up', spark: [4.3,4.3,4.4,4.4,4.4,4.5,4.5] },
      { id: 'ooc', nome: 'Respostas fora de contexto', tech: 'Out-of-context rate', valor: 4.2, unit: '%', target: '<5%', status: 'amber', severidade: 'Importante', delta: '+0.8%', deltaDir: 'up-bad', spark: [3.4,3.5,3.6,3.8,4.0,4.1,4.2] },
    ],
  },
  performance: {
    icon: '⚡',
    title: 'Performance & Disponibilidade',
    accent: '#a78bfa',
    items: [
      { id: 'lat', nome: 'Latência média de resposta', tech: 'p50 latency', valor: 2.1, unit: 's', target: '<3s', status: 'green', severidade: 'Crítico', delta: '-0.2s', deltaDir: 'down-good', spark: [2.4,2.3,2.3,2.2,2.2,2.1,2.1] },
      { id: 'uptime', nome: 'Uptime do sistema', tech: 'Uptime 30d', valor: 99.7, unit: '%', target: '>99%', status: 'green', severidade: 'Crítico', delta: '+0.2%', deltaDir: 'up', spark: [99.5,99.5,99.6,99.7,99.7,99.7,99.7] },
      { id: 'subagent', nome: 'Taxa de sucesso de sub-agentes', tech: 'Sub-agent success', valor: 96.8, unit: '%', target: '>95%', status: 'green', severidade: 'Importante', delta: '+0.4%', deltaDir: 'up', spark: [96.2,96.3,96.5,96.6,96.7,96.7,96.8] },
      { id: 'mttr', nome: 'Tempo de recuperação de falha', tech: 'MTTR', valor: 4.2, unit: ' min', target: '<5 min', status: 'amber', severidade: 'Importante', delta: '+0.5 min', deltaDir: 'up-bad', spark: [3.5,3.6,3.8,4.0,4.1,4.2,4.2] },
    ],
  },
  comercial: {
    icon: '📈',
    title: 'Impacto Comercial',
    accent: '#10b981',
    items: [
      { id: 'leads', nome: 'Leads qualificados/mês', tech: 'Qualified leads · MoM', valor: 47, unit: '', target: 'TBD', status: 'orange', severidade: 'Monitorizar', delta: 'baseline', deltaDir: 'flat', spark: [38,42,40,44,45,46,47] },
      { id: 'qualtime', nome: 'Tempo médio de qualificação', tech: 'Avg qualification time', valor: 7.3, unit: ' min', target: '<10 min', status: 'green', severidade: 'Importante', delta: '-1.2 min', deltaDir: 'down-good', spark: [9.0,8.7,8.4,8.0,7.8,7.5,7.3] },
      { id: 'conv', nome: 'Conversão lead → Stage 65', tech: 'Conversion rate', valor: 12.4, unit: '%', target: 'TBD', status: 'orange', severidade: 'Monitorizar', delta: 'baseline', deltaDir: 'flat', spark: [11.8,12.0,12.1,12.2,12.3,12.4,12.4] },
      { id: 'engage', nome: 'Interações activas/utilizador', tech: 'Active interactions/mo', valor: 23, unit: '', target: 'TBD', status: 'orange', severidade: 'Monitorizar', delta: 'baseline', deltaDir: 'flat', spark: [18,19,20,21,22,22,23] },
    ],
  },
  seguranca: {
    icon: '🔒',
    title: 'Segurança & Conformidade',
    accent: '#f59e0b',
    tier: 'executivo',
    items: [
      { id: 'leak', nome: 'Escapes de dados entre modos', tech: 'Mode-cross leaks', valor: 0, unit: '', target: '0', status: 'green', severidade: 'Crítico', delta: '0', deltaDir: 'flat', spark: [0,0,0,0,0,0,0] },
      { id: 'expose', nome: 'Dados internos expostos', tech: 'Internal data leaks', valor: 0, unit: '', target: '0', status: 'green', severidade: 'Crítico', delta: '0', deltaDir: 'flat', spark: [0,0,0,0,0,0,0] },
      { id: 'rgpd', nome: 'RGPD · consentimentos registados', tech: 'GDPR consent rate', valor: 100, unit: '%', target: '100%', status: 'green', severidade: 'Crítico', delta: '0', deltaDir: 'flat', spark: [100,100,100,100,100,100,100] },
      { id: 'aiact', nome: 'Identificação AI Act', tech: 'AI Act disclosure', valor: 100, unit: '%', target: '100%', status: 'green', severidade: 'Crítico', delta: '0', deltaDir: 'flat', spark: [100,100,100,100,100,100,100] },
    ],
  },
  kb: {
    icon: '📚',
    title: 'KB & Conteúdo',
    accent: '#60a5fa',
    tier: 'operacional',
    items: [
      { id: 'kbchunks', nome: 'Chunks totais na KB', tech: 'Total chunks indexed', valor: '101.453', unit: '', target: '>100k', status: 'green', severidade: 'Crítico', delta: '+2.103', deltaDir: 'up', spark: [97000,98100,99000,99800,100400,101000,101453] },
      { id: 'kbcobertura', nome: 'Cobertura por marca (média)', tech: 'Avg brand coverage', valor: 97.2, unit: '%', target: '>95%', status: 'green', severidade: 'Importante', delta: '+0.3%', deltaDir: 'up', spark: [96.9,97.0,97.1,97.1,97.2,97.2,97.2] },
      { id: 'kbfresh', nome: 'Freshness · sources <30d', tech: 'Source freshness', valor: 73, unit: '%', target: '>80%', status: 'amber', severidade: 'Importante', delta: '-4%', deltaDir: 'down', spark: [80,79,78,76,75,74,73] },
      { id: 'kbstale', nome: 'Sources sem update >60d', tech: 'Stale sources', valor: 5, unit: '', target: '<3', status: 'red', severidade: 'Monitorizar', delta: '+2', deltaDir: 'up-bad', spark: [2,2,3,3,4,4,5] },
    ],
  },
  custos: {
    icon: '💰',
    title: 'Custos & Eficiência',
    accent: '#facc15',
    tier: 'operacional',
    crossLink: { label: 'Ver detalhe completo em SISTEMA › Costs', target: 'costs' },
    items: [
      { id: 'cps', nome: 'Custo por sessão', tech: 'Cost per session', valor: '€0,21', unit: '', target: '<€0.30', status: 'green', severidade: 'Crítico', delta: '-€0,02', deltaDir: 'down-good', spark: [0.24,0.23,0.23,0.22,0.22,0.21,0.21] },
      { id: 'monthly', nome: 'Custo total mês', tech: 'Claude API · MTD', valor: '€1.641', unit: '', target: '<€2.000', status: 'amber', severidade: 'Importante', delta: 'parcial · 25/30', deltaDir: 'up', spark: [180,420,640,840,1080,1320,1641] },
      { id: 'tokens', nome: 'Tokens médios por conversa', tech: 'Avg tokens/session', valor: '6.420', unit: '', target: '<8.000', status: 'green', severidade: 'Importante', delta: '-310', deltaDir: 'down-good', spark: [6800,6720,6650,6580,6510,6450,6420] },
      { id: 'cache', nome: 'Cache hit rate', tech: 'Prompt cache hits', valor: 54, unit: '%', target: '>60%', status: 'amber', severidade: 'Monitorizar', delta: '+3%', deltaDir: 'up', spark: [48,50,51,52,53,54,54] },
    ],
  },
  subagentes: {
    icon: '🤖',
    title: 'Sub-agentes',
    accent: '#c084fc',
    tier: 'operacional',
    items: [
      { id: 'topagent', nome: 'Top performer', tech: 'SP_CLIENTES', valor: '98,7', unit: '%', target: '—', status: 'green', severidade: 'Importante', delta: '+0.4%', deltaDir: 'up', spark: [97.9,98.0,98.2,98.4,98.5,98.6,98.7], badgeName: 'SP_CLIENTES' },
      { id: 'bottomagent', nome: 'Pior performer', tech: 'SP_COLAB_OPS', valor: '87,3', unit: '%', target: '>90%', status: 'red', severidade: 'Crítico', delta: '-1.8%', deltaDir: 'down', spark: [89.1,88.8,88.4,88.0,87.7,87.5,87.3], badgeName: 'SP_COLAB_OPS' },
      { id: 'agentlat', nome: 'Latência por agente (pior)', tech: 'SP_COLAB_SAT', valor: 3.4, unit: 's', target: '<3s', status: 'amber', severidade: 'Importante', delta: '+0.3s', deltaDir: 'up-bad', spark: [3.1,3.1,3.2,3.3,3.3,3.4,3.4], badgeName: 'SP_COLAB_SAT' },
      { id: 'agenterr', nome: 'Erros últimos 7d', tech: 'Sub-agent errors · 7d', valor: 4, unit: '', target: '<10', status: 'green', severidade: 'Importante', delta: '-2', deltaDir: 'down-good', spark: [1,0,1,0,1,0,1] },
    ],
  },
  pipeline: {
    icon: '🔄',
    title: 'Pipeline & CRM',
    accent: '#34d399',
    tier: 'operacional',
    waitingBadge: 'ℹ Aguarda Walter · GestorConnect WRITE',
    items: [
      { id: 'funnel', nome: 'Conversão Stage 10→65 (full funnel)', tech: 'Full funnel rate', valor: '—', unit: '', target: '>25%', status: 'orange', severidade: 'Crítico', delta: 'baseline', deltaDir: 'flat', spark: [12,13,14,14,15,15,16] },
      { id: 'velocity', nome: 'Deal velocity médio', tech: 'Lead → Won', valor: '—', unit: '', target: '<90 dias', status: 'orange', severidade: 'Importante', delta: 'baseline', deltaDir: 'flat', spark: [115,112,110,108,105,103,102] },
      { id: 'syncerr', nome: 'Sync errors com Gestor (24h)', tech: 'CRM sync errors', valor: 0, unit: '', target: '<5', status: 'green', severidade: 'Crítico', delta: '0', deltaDir: 'flat', spark: [0,0,0,0,0,0,0] },
      { id: 'atrisk', nome: 'Pipeline value at risk', tech: 'Stages 80–92 · €', valor: '€312k', unit: '', target: '—', status: 'amber', severidade: 'Monitorizar', delta: '+€42k', deltaDir: 'up-bad', spark: [240,255,268,278,290,302,312] },
    ],
  },
};

// Insert tier on the first 4 quadrants too
['qualidade','performance','comercial'].forEach(k => { if (KPI_DATA[k]) KPI_DATA[k].tier = 'executivo'; });

const KPI_STATUS_COLORS = {
  green:  { dot: '#10b981', text: '#34d399', glow: 'rgba(16,185,129,0.15)' },
  amber:  { dot: '#f59e0b', text: '#fbbf24', glow: 'rgba(245,158,11,0.15)' },
  red:    { dot: '#ef4444', text: '#f87171', glow: 'rgba(239,68,68,0.15)' },
  orange: { dot: '#fb923c', text: '#fb923c', glow: 'rgba(251,146,60,0.15)' },
};

const KPI_SEVERITY = {
  'Crítico':     { bg: 'rgba(34,211,238,0.12)',  border: 'rgba(34,211,238,0.32)',  color: '#67e8f9' },
  'Importante':  { bg: 'rgba(96,165,250,0.12)',  border: 'rgba(96,165,250,0.32)',  color: '#93c5fd' },
  'Monitorizar': { bg: 'rgba(245,158,11,0.12)',  border: 'rgba(245,158,11,0.32)',  color: '#fbbf24' },
};

// SVG mini sparkline
const Sparkline = ({ data, color, w = 110, h = 28 }) => {
  if (!data || !data.length) return null;
  const min = Math.min(...data), max = Math.max(...data);
  const span = max - min || 1;
  const stepX = w / (data.length - 1 || 1);
  const points = data.map((v, i) => {
    const x = i * stepX;
    const y = h - ((v - min) / span) * (h - 4) - 2;
    return [x, y];
  });
  const path = points.map((p, i) => (i === 0 ? `M${p[0].toFixed(1)},${p[1].toFixed(1)}` : `L${p[0].toFixed(1)},${p[1].toFixed(1)}`)).join('');
  const areaPath = path + ` L${w},${h} L0,${h} Z`;
  return (
    <svg width={w} height={h} viewBox={`0 0 ${w} ${h}`} style={{ overflow: 'visible' }}>
      <defs>
        <linearGradient id={`grad-${color.replace(/[^a-z0-9]/gi,'')}`} x1="0" y1="0" x2="0" y2="1">
          <stop offset="0%" stopColor={color} stopOpacity="0.32" />
          <stop offset="100%" stopColor={color} stopOpacity="0" />
        </linearGradient>
      </defs>
      <path d={areaPath} fill={`url(#grad-${color.replace(/[^a-z0-9]/gi,'')})`} />
      <path d={path} fill="none" stroke={color} strokeWidth="1.4" strokeLinecap="round" strokeLinejoin="round" opacity="0.9" />
      <circle cx={points[points.length-1][0]} cy={points[points.length-1][1]} r="2" fill={color} />
    </svg>
  );
};

const StatusDot = ({ status, size = 8, glow = true }) => {
  const c = KPI_STATUS_COLORS[status] || KPI_STATUS_COLORS.green;
  return (
    <span style={{
      display: 'inline-block', width: size, height: size, borderRadius: '50%',
      background: c.dot,
      boxShadow: glow ? `0 0 0 3px ${c.glow}` : 'none',
      flexShrink: 0,
    }} />
  );
};

const SeverityPill = ({ severidade }) => {
  const s = KPI_SEVERITY[severidade] || KPI_SEVERITY.Importante;
  return (
    <span style={{
      display: 'inline-block',
      padding: '1px 7px',
      fontSize: 9.5, fontFamily: 'var(--font-mono)', letterSpacing: '0.04em',
      background: s.bg, border: `1px solid ${s.border}`, color: s.color,
      borderRadius: 3, textTransform: 'uppercase', fontWeight: 600,
    }}>{severidade}</span>
  );
};

const DeltaBadge = ({ delta, dir }) => {
  const colors = {
    'up':       '#10b981',
    'down-good':'#10b981',
    'up-bad':   '#f59e0b',
    'down':     '#ef4444',
    'flat':     'var(--text-dim)',
  };
  const arrow = dir === 'flat' ? '·' : (dir === 'up' || dir === 'up-bad' ? '↑' : '↓');
  return (
    <span style={{ fontSize: 11, fontFamily: 'var(--font-mono)', color: colors[dir] || 'var(--text-muted)', display: 'inline-flex', alignItems: 'center', gap: 3 }}>
      <span>{arrow}</span><span>{delta}</span><span style={{ color: 'var(--text-dim)' }}>vs anterior</span>
    </span>
  );
};

// ---------- KPI Card ----------
const KPICard = ({ kpi, onClick }) => {
  const c = KPI_STATUS_COLORS[kpi.status] || KPI_STATUS_COLORS.green;
  return (
    <button onClick={onClick} style={{
      width: '100%', textAlign: 'left',
      background: 'var(--bg-elev)',
      border: '1px solid var(--border)',
      borderRadius: 10,
      padding: '12px 14px',
      display: 'flex', flexDirection: 'column', gap: 8,
      transition: 'all 0.15s',
      cursor: 'pointer',
      position: 'relative',
    }}
    onMouseEnter={e => {
      e.currentTarget.style.borderColor = c.dot;
      e.currentTarget.style.transform = 'translateY(-1px)';
      e.currentTarget.style.boxShadow = `0 4px 12px ${c.glow}`;
    }}
    onMouseLeave={e => {
      e.currentTarget.style.borderColor = 'var(--border)';
      e.currentTarget.style.transform = 'translateY(0)';
      e.currentTarget.style.boxShadow = 'none';
    }}
    >
      {/* Row 1: status + name + tech */}
      <div style={{ display: 'flex', alignItems: 'flex-start', gap: 8, minHeight: 30 }}>
        <StatusDot status={kpi.status} />
        <div style={{ flex: 1, minWidth: 0, lineHeight: 1.25 }}>
          <div style={{ fontSize: 12.5, fontWeight: 500, color: 'var(--text)' }}>{kpi.nome}</div>
          <div style={{ fontSize: 10.5, fontFamily: 'var(--font-mono)', color: 'var(--text-dim)', marginTop: 1 }}>{kpi.tech}</div>
        </div>
      </div>

      {/* Row 2: big value + target */}
      <div style={{ display: 'flex', alignItems: 'baseline', gap: 10, marginTop: 2 }}>
        <span style={{ fontFamily: 'var(--font-display)', fontSize: 26, fontWeight: 700, color: c.text, letterSpacing: '-0.01em', lineHeight: 1 }}>
          {typeof kpi.valor === 'number' ? kpi.valor.toString().replace('.', ',') : kpi.valor}<span style={{ fontSize: 14, fontWeight: 500, color: c.text, opacity: 0.85 }}>{kpi.unit}</span>
        </span>
        <span style={{ fontSize: 10.5, color: 'var(--text-dim)', fontFamily: 'var(--font-mono)', marginLeft: 'auto' }}>
          target {kpi.target}
        </span>
      </div>

      {/* Row 3: sparkline + delta */}
      <div style={{ display: 'flex', alignItems: 'center', gap: 10 }}>
        <Sparkline data={kpi.spark} color={c.dot} w={120} h={26} />
        <DeltaBadge delta={kpi.delta} dir={kpi.deltaDir} />
      </div>

      {/* Row 4: severity + arrow */}
      <div style={{ display: 'flex', alignItems: 'center', justifyContent: 'space-between', marginTop: 2 }}>
        <SeverityPill severidade={kpi.severidade} />
        <Icon name="arrowRight" size={12} style={{ color: 'var(--text-dim)' }} />
      </div>
    </button>
  );
};

// ---------- Quadrant Card (group of 4 KPIs) ----------
const QuadrantCard = ({ group, data, onSelect }) => {
  const greenCount = data.items.filter(i => i.status === 'green').length;
  const amberCount = data.items.filter(i => i.status === 'amber' || i.status === 'orange').length;
  const redCount = data.items.filter(i => i.status === 'red').length;
  return (
    <section style={{
      background: 'rgba(255,255,255,0.015)',
      border: '1px solid var(--border)',
      borderRadius: 12,
      padding: 14,
      display: 'flex', flexDirection: 'column', gap: 10,
      minHeight: 0,
    }}>
      <header style={{ display: 'flex', alignItems: 'center', gap: 10, paddingBottom: 8, borderBottom: '1px solid var(--border)', flexWrap: 'wrap' }}>
        <span style={{ fontSize: 18 }}>{data.icon}</span>
        <h3 className="font-display" style={{ margin: 0, fontSize: 13.5, fontWeight: 600, letterSpacing: '0.02em', flex: 1 }}>{data.title}</h3>
        <div style={{ display: 'inline-flex', alignItems: 'center', gap: 6, fontSize: 10.5, fontFamily: 'var(--font-mono)', color: 'var(--text-muted)' }}>
          {greenCount > 0 && <span style={{ display: 'inline-flex', alignItems: 'center', gap: 3 }}><StatusDot status="green" size={6} glow={false} />{greenCount}</span>}
          {amberCount > 0 && <span style={{ display: 'inline-flex', alignItems: 'center', gap: 3 }}><StatusDot status="amber" size={6} glow={false} />{amberCount}</span>}
          {redCount > 0 && <span style={{ display: 'inline-flex', alignItems: 'center', gap: 3 }}><StatusDot status="red" size={6} glow={false} />{redCount}</span>}
        </div>
        {data.waitingBadge && (
          <span style={{
            width: '100%', marginTop: 2,
            display: 'inline-flex', alignItems: 'center', gap: 6,
            padding: '3px 8px',
            fontSize: 10, fontFamily: 'var(--font-mono)',
            background: 'rgba(245,158,11,0.10)', border: '1px solid rgba(245,158,11,0.32)',
            color: '#fbbf24', borderRadius: 4,
          }}>{data.waitingBadge}</span>
        )}
      </header>
      <div style={{ display: 'grid', gridTemplateColumns: '1fr 1fr', gap: 8, flex: 1 }}>
        {data.items.map(kpi => (
          <KPICard key={kpi.id} kpi={kpi} onClick={() => onSelect({ group, kpi })} />
        ))}
      </div>
      {data.crossLink && (
        <a href={`#screen=sistema`} onClick={(e) => { e.preventDefault(); try { localStorage.setItem('digi-sistema-sub', data.crossLink.target); window.dispatchEvent(new CustomEvent('digi-subnav', { detail: { storageKey: 'digi-sistema-sub', val: data.crossLink.target } })); } catch {} }} style={{
          display: 'flex', alignItems: 'center', justifyContent: 'space-between',
          padding: '8px 10px', marginTop: 4,
          background: 'var(--bg-sunken)', border: '1px solid var(--border)', borderRadius: 6,
          fontSize: 11, color: 'var(--text-muted)',
          fontFamily: 'var(--font-mono)',
        }}>
          <span>{data.crossLink.label}</span>
          <Icon name="arrowRight" size={12} />
        </a>
      )}
    </section>
  );
};

// ---------- Drill-down panel ----------
const KPIDrillPanel = ({ entry, onClose }) => {
  if (!entry) return null;
  const { kpi } = entry;
  const c = KPI_STATUS_COLORS[kpi.status];
  // 30-day extended sparkline (mock: tile the 7-day with slight noise)
  const long = [];
  for (let i = 0; i < 30; i++) {
    const base = kpi.spark[i % kpi.spark.length];
    long.push(typeof base === 'number' ? base + (Math.sin(i * 0.7) * 0.05 * (Math.abs(base) || 1)) : base);
  }

  // Mock contributing factors
  const factors = {
    rag: [
      { label: 'Mimaki', value: '94.1%', bar: 0.94 },
      { label: 'HP Latex', value: '93.2%', bar: 0.93 },
      { label: 'Roland', value: '92.5%', bar: 0.92 },
      { label: 'EFI', value: '90.8%', bar: 0.90 },
      { label: 'Outras marcas', value: '88.4%', bar: 0.88 },
    ],
  };
  const subkpis = [
    { label: 'RAG · top-k retrieval hit', value: '96.4%' },
    { label: 'Citations correctas', value: '91.2%' },
    { label: 'Resposta termina sem fallback', value: '94.7%' },
    { label: 'Top-1 chunk relevância (avg)', value: '0.78' },
    { label: 'Reformulações pelo utilizador', value: '4.1%' },
  ];
  const incidents = [
    { when: 'há 14 min', what: 'Latência subiu 8% após deploy SP_CLIENTES.v1.4.2 às 14:32', sev: 'amber' },
    { when: 'há 2h', what: 'quality_kb pendente — 3.420 chunks por reindexar (Sónia Casimiro)', sev: 'red' },
  ];

  return (
    <>
      <div onClick={onClose} style={{ position: 'fixed', inset: 0, background: 'rgba(0,0,0,0.42)', zIndex: 90 }} />
      <aside style={{
        position: 'fixed', top: 0, right: 0, bottom: 0,
        width: 480, maxWidth: '92vw',
        background: 'var(--bg-elev)',
        borderLeft: '1px solid var(--border)',
        zIndex: 91,
        display: 'flex', flexDirection: 'column',
        boxShadow: '-12px 0 40px rgba(0,0,0,0.4)',
      }}>
        <header style={{ padding: '14px 18px', borderBottom: '1px solid var(--border)', display: 'flex', alignItems: 'flex-start', gap: 12 }}>
          <StatusDot status={kpi.status} size={10} />
          <div style={{ flex: 1, minWidth: 0 }}>
            <div style={{ fontSize: 10, fontFamily: 'var(--font-mono)', color: 'var(--text-dim)', letterSpacing: '0.08em', textTransform: 'uppercase' }}>{entry.group} · {kpi.tech}</div>
            <h3 className="font-display" style={{ margin: '4px 0 0', fontSize: 17, fontWeight: 600 }}>{kpi.nome}</h3>
          </div>
          <button onClick={onClose} className="btn btn-sm btn-ghost" style={{ padding: 6 }}><Icon name="close" size={14} /></button>
        </header>

        <div style={{ flex: 1, overflow: 'auto', padding: 18, display: 'flex', flexDirection: 'column', gap: 18 }} className="scrollbar">
          {/* Big value */}
          <div style={{ display: 'flex', alignItems: 'baseline', gap: 14 }}>
            <span style={{ fontFamily: 'var(--font-display)', fontSize: 40, fontWeight: 700, color: c.text, letterSpacing: '-0.02em', lineHeight: 1 }}>
              {typeof kpi.valor === 'number' ? kpi.valor.toString().replace('.', ',') : kpi.valor}<span style={{ fontSize: 22, opacity: 0.8 }}>{kpi.unit}</span>
            </span>
            <div style={{ display: 'flex', flexDirection: 'column', gap: 3 }}>
              <span style={{ fontSize: 11, fontFamily: 'var(--font-mono)', color: 'var(--text-dim)' }}>target {kpi.target}</span>
              <DeltaBadge delta={kpi.delta} dir={kpi.deltaDir} />
            </div>
            <div style={{ marginLeft: 'auto' }}><SeverityPill severidade={kpi.severidade} /></div>
          </div>

          {/* 30-day chart */}
          <div>
            <div style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'baseline', marginBottom: 6 }}>
              <span style={{ fontSize: 11, fontFamily: 'var(--font-mono)', color: 'var(--text-muted)', textTransform: 'uppercase', letterSpacing: '0.06em' }}>30 dias</span>
              <span style={{ fontSize: 10, color: 'var(--text-dim)' }}>linha tracejada = target</span>
            </div>
            <div style={{ background: 'var(--bg-sunken)', border: '1px solid var(--border)', borderRadius: 8, padding: '10px 8px' }}>
              <Sparkline data={long} color={c.dot} w={420} h={80} />
            </div>
          </div>

          {/* Top contributing factors */}
          <section>
            <h4 className="font-display" style={{ margin: '0 0 8px', fontSize: 12, fontWeight: 600, letterSpacing: '0.04em', color: 'var(--text-muted)', textTransform: 'uppercase' }}>Top 5 factores contributivos</h4>
            <div style={{ display: 'flex', flexDirection: 'column', gap: 6 }}>
              {(factors[kpi.id] || subkpis.slice(0,5).map(s => ({ label: s.label, value: s.value, bar: 0.6 + Math.random()*0.4 }))).map(f => (
                <div key={f.label} style={{ display: 'flex', alignItems: 'center', gap: 10, fontSize: 12 }}>
                  <span style={{ width: 130, color: 'var(--text-muted)', overflow: 'hidden', textOverflow: 'ellipsis', whiteSpace: 'nowrap' }}>{f.label}</span>
                  <div style={{ flex: 1, height: 6, background: 'var(--bg-sunken)', borderRadius: 3, overflow: 'hidden' }}>
                    <div style={{ height: '100%', width: `${(f.bar || 0.7) * 100}%`, background: c.dot, opacity: 0.7, borderRadius: 3 }} />
                  </div>
                  <span style={{ fontFamily: 'var(--font-mono)', fontSize: 11, color: 'var(--text)', minWidth: 50, textAlign: 'right' }}>{f.value}</span>
                </div>
              ))}
            </div>
          </section>

          {/* Sub-KPIs */}
          <section>
            <h4 className="font-display" style={{ margin: '0 0 8px', fontSize: 12, fontWeight: 600, letterSpacing: '0.04em', color: 'var(--text-muted)', textTransform: 'uppercase' }}>Sub-KPIs relacionados</h4>
            <div style={{ display: 'flex', flexDirection: 'column', gap: 1, border: '1px solid var(--border)', borderRadius: 8, overflow: 'hidden' }}>
              {subkpis.map((s, i) => (
                <div key={s.label} style={{ display: 'flex', justifyContent: 'space-between', padding: '8px 12px', background: i % 2 ? 'transparent' : 'var(--bg-sunken)', fontSize: 11.5 }}>
                  <span style={{ color: 'var(--text-muted)' }}>{s.label}</span>
                  <span style={{ fontFamily: 'var(--font-mono)', color: 'var(--text)' }}>{s.value}</span>
                </div>
              ))}
              <div style={{ padding: '6px 12px', textAlign: 'center', fontSize: 10.5, fontFamily: 'var(--font-mono)', color: 'var(--text-dim)', borderTop: '1px solid var(--border)' }}>
                + 234 sub-KPIs no detalhe →
              </div>
            </div>
          </section>

          {/* Incidents */}
          <section>
            <h4 className="font-display" style={{ margin: '0 0 8px', fontSize: 12, fontWeight: 600, letterSpacing: '0.04em', color: 'var(--text-muted)', textTransform: 'uppercase' }}>Eventos recentes</h4>
            <div style={{ display: 'flex', flexDirection: 'column', gap: 6 }}>
              {incidents.map((inc, i) => (
                <div key={i} style={{ display: 'flex', alignItems: 'flex-start', gap: 10, padding: '8px 10px', background: 'var(--bg-sunken)', borderRadius: 6, border: '1px solid var(--border)' }}>
                  <StatusDot status={inc.sev} size={7} />
                  <div style={{ flex: 1, fontSize: 11.5, lineHeight: 1.4 }}>
                    <div style={{ color: 'var(--text)' }}>{inc.what}</div>
                    <div style={{ color: 'var(--text-dim)', fontFamily: 'var(--font-mono)', fontSize: 10, marginTop: 2 }}>{inc.when}</div>
                  </div>
                </div>
              ))}
            </div>
          </section>
        </div>

        <footer style={{ padding: '12px 18px', borderTop: '1px solid var(--border)', display: 'flex', gap: 8 }}>
          <button className="btn btn-sm" style={{ flex: 1 }}><Icon name="history" size={12} /> Investigar no Replay</button>
          <button className="btn btn-sm btn-ai" style={{ flex: 1 }}><Icon name="sparkle" size={12} /> Editar Prompt</button>
        </footer>
      </aside>
    </>
  );
};

// ---------- Top summary strip ----------
const SummaryStrip = ({ groups, onFilterRisk, lastUpdate, onRefresh }) => {
  const allItems = Object.values(groups).flatMap(g => g.items);
  const totalCount = allItems.length;
  const risk = allItems.filter(i => i.status === 'amber' || i.status === 'red').length;
  const onTarget = allItems.filter(i => i.status === 'green').length;
  const critical = allItems.filter(i => i.severidade === 'Crítico');
  const important = allItems.filter(i => i.severidade === 'Importante');
  const slosOk = critical.filter(i => i.status === 'green').length;
  const slosTotal = critical.length;
  const impOk = important.filter(i => i.status === 'green').length;
  const impTotal = important.length;
  const groupCount = Object.keys(groups).length;

  const tile = (label, value, sub, accent, onClick) => (
    <button onClick={onClick} style={{
      flex: 1, minWidth: 0,
      background: 'var(--bg-elev)', border: '1px solid var(--border)',
      borderRadius: 10, padding: '12px 14px',
      display: 'flex', flexDirection: 'column', gap: 4,
      textAlign: 'left',
      transition: 'all 0.15s',
    }}
    onMouseEnter={e => { if (onClick) { e.currentTarget.style.borderColor = accent; e.currentTarget.style.background = 'var(--bg-hover)'; } }}
    onMouseLeave={e => { e.currentTarget.style.borderColor = 'var(--border)'; e.currentTarget.style.background = 'var(--bg-elev)'; }}
    >
      <span style={{ fontSize: 10, fontFamily: 'var(--font-mono)', color: 'var(--text-dim)', textTransform: 'uppercase', letterSpacing: '0.06em' }}>{label}</span>
      <span style={{ fontFamily: 'var(--font-display)', fontSize: 18, fontWeight: 600, color: accent }}>{value}</span>
      {sub && <span style={{ fontSize: 11, color: 'var(--text-muted)' }}>{sub}</span>}
    </button>
  );

  return (
    <div style={{ display: 'grid', gridTemplateColumns: 'repeat(4, 1fr)', gap: 10, marginBottom: 14 }}>
      {/* Sistema — 1 dot per group */}
      <div style={{ background: 'var(--bg-elev)', border: '1px solid var(--border)', borderRadius: 10, padding: '12px 14px', display: 'flex', flexDirection: 'column', gap: 4 }}>
        <span style={{ fontSize: 10, fontFamily: 'var(--font-mono)', color: 'var(--text-dim)', textTransform: 'uppercase', letterSpacing: '0.06em' }}>Sistema</span>
        <div style={{ display: 'flex', alignItems: 'center', gap: 4, flexWrap: 'wrap' }}>
          {Object.values(groups).map((g, i) => {
            const has = g.items.some(it => it.status === 'red') ? 'red'
              : g.items.some(it => it.status === 'amber' || it.status === 'orange') ? 'amber' : 'green';
            return <StatusDot key={i} status={has} size={8} glow={false} />;
          })}
          <span style={{ marginLeft: 6, fontFamily: 'var(--font-display)', fontSize: 16, fontWeight: 600, color: risk === 0 ? '#34d399' : '#fbbf24' }}>
            {risk === 0 ? 'Saudável' : 'Atenção'}
          </span>
        </div>
        <span style={{ fontSize: 11, color: 'var(--text-muted)' }}>{groupCount} grupos · {totalCount} KPIs</span>
      </div>

      {tile('KPIs em risco', `${risk}`, risk === 0 ? 'tudo dentro do alvo' : 'amber + red de ' + totalCount, risk === 0 ? '#34d399' : '#fbbf24', onFilterRisk)}

      {/* SLOs cumpridos — totais + breakdown */}
      <div style={{ background: 'var(--bg-elev)', border: '1px solid var(--border)', borderRadius: 10, padding: '12px 14px', display: 'flex', flexDirection: 'column', gap: 4 }}>
        <span style={{ fontSize: 10, fontFamily: 'var(--font-mono)', color: 'var(--text-dim)', textTransform: 'uppercase', letterSpacing: '0.06em' }}>SLOs cumpridos</span>
        <span style={{ fontFamily: 'var(--font-display)', fontSize: 18, fontWeight: 600, color: '#67e8f9' }}>
          {onTarget}/{totalCount} <span style={{ fontSize: 11, color: 'var(--text-dim)', fontFamily: 'var(--font-mono)', fontWeight: 400 }}>no target</span>
        </span>
        <span style={{ fontSize: 11, color: 'var(--text-muted)', fontFamily: 'var(--font-mono)' }}>{slosOk}/{slosTotal} críticos · {impOk}/{impTotal} importantes</span>
      </div>

      <div style={{ background: 'var(--bg-elev)', border: '1px solid var(--border)', borderRadius: 10, padding: '12px 14px', display: 'flex', flexDirection: 'column', gap: 4 }}>
        <span style={{ fontSize: 10, fontFamily: 'var(--font-mono)', color: 'var(--text-dim)', textTransform: 'uppercase', letterSpacing: '0.06em' }}>Última actualização</span>
        <div style={{ display: 'flex', alignItems: 'baseline', gap: 8 }}>
          <span style={{ fontFamily: 'var(--font-display)', fontSize: 18, fontWeight: 600 }}>há 2 min</span>
          <button onClick={onRefresh} className="btn btn-xs btn-ghost" style={{ padding: '2px 6px', marginLeft: 'auto' }} title="Refresh"><Icon name="refresh" size={12} /></button>
        </div>
        <span style={{ fontSize: 11, color: 'var(--text-muted)', fontFamily: 'var(--font-mono)' }}>{lastUpdate}</span>
      </div>
    </div>
  );
};

// ---------- Right: Digi AI insight panel ----------
const DigiInsightsPanel = () => {
  const insights = [
    { tag: 'Latência', text: 'Latência subiu 8% após deploy de 24 Abr às 14:32 — Prompts grupo SP_CLIENTES. Sugiro revisar o último diff.', action: 'Abrir Replay' },
    { tag: 'Qualidade', text: 'Respostas fora de contexto +0,8% vs 7d anteriores. Cluster: queries sobre garantia HP Latex. KB sem chunks recentes.', action: 'Reindexar KB' },
    { tag: 'Comercial', text: 'Tempo de qualificação caiu 1,2 min. Frame F_DESCOBERTA optimizado por Daniel está a render dividendos.', action: 'Ver Frame' },
    { tag: 'KB Freshness', text: '5 sources com >60d sem updates: BiondFilmsKB, DecalKB-textil, AllDecorKB, Sensek, MimakiKB-3D. Sugestão: re-scrape próximas 2 semanas.', action: 'Programar update KB' },
  ];
  return (
    <aside style={{
      width: 320, flexShrink: 0,
      background: 'var(--bg-elev)',
      borderLeft: '1px solid var(--border)',
      display: 'flex', flexDirection: 'column',
      height: '100%',
    }}>
      <header style={{ padding: '14px 16px', borderBottom: '1px solid var(--border)', display: 'flex', alignItems: 'center', gap: 8 }}>
        <div style={{ width: 22, height: 22, borderRadius: 5, background: 'var(--ai-500)', display: 'grid', placeItems: 'center' }}>
          <Icon name="sparkle" size={12} style={{ color: '#fff' }} />
        </div>
        <div>
          <div className="font-display" style={{ fontSize: 12.5, fontWeight: 600 }}>Insights do Digi</div>
          <div style={{ fontSize: 10, color: 'var(--text-dim)', fontFamily: 'var(--font-mono)' }}>análise contínua · KPIs</div>
        </div>
      </header>
      <div style={{ flex: 1, overflow: 'auto', padding: 14, display: 'flex', flexDirection: 'column', gap: 10 }} className="scrollbar">
        {insights.map((ins, i) => (
          <article key={i} className="ai-surface" style={{ padding: 12, borderRadius: 8, display: 'flex', flexDirection: 'column', gap: 8 }}>
            <div style={{ display: 'flex', alignItems: 'center', gap: 6 }}>
              <span className="ai-dot" />
              <span style={{ fontSize: 10, fontFamily: 'var(--font-mono)', color: 'var(--ai-500)', letterSpacing: '0.06em', textTransform: 'uppercase', fontWeight: 600 }}>{ins.tag}</span>
            </div>
            <p style={{ margin: 0, fontSize: 12, lineHeight: 1.5, color: 'var(--text)' }}>{ins.text}</p>
            <button className="btn btn-xs" style={{ alignSelf: 'flex-start' }}>{ins.action} →</button>
          </article>
        ))}
      </div>
    </aside>
  );
};

// ---------- Section divider ----------
const SectionDivider = ({ label, count, hint }) => (
  <div style={{ display: 'flex', alignItems: 'center', gap: 12, margin: '4px 0 12px' }}>
    <span style={{ fontSize: 11, fontFamily: 'var(--font-display)', fontWeight: 600, color: 'var(--text-muted)', textTransform: 'uppercase', letterSpacing: '0.1em' }}>{label}</span>
    <span style={{ fontSize: 10.5, fontFamily: 'var(--font-mono)', color: 'var(--text-dim)' }}>· {count} KPIs · {hint}</span>
    <span style={{ flex: 1, height: 1, background: 'var(--border)' }} />
  </div>
);

// ---------- Bottom CTA ----------
const DetailCTA = () => (
  <button onClick={() => alert('SISTEMA › KPIs › Detalhe — em construção')} style={{
    width: '100%', padding: '16px 20px',
    background: 'linear-gradient(135deg, rgba(34,211,238,0.06), rgba(96,165,250,0.04))',
    border: '1px solid var(--border)',
    borderRadius: 12,
    display: 'flex', alignItems: 'center', gap: 14,
    textAlign: 'left',
    transition: 'all 0.2s',
    cursor: 'pointer',
  }}
  onMouseEnter={e => { e.currentTarget.style.borderColor = '#22d3ee'; e.currentTarget.style.background = 'linear-gradient(135deg, rgba(34,211,238,0.10), rgba(96,165,250,0.06))'; }}
  onMouseLeave={e => { e.currentTarget.style.borderColor = 'var(--border)'; e.currentTarget.style.background = 'linear-gradient(135deg, rgba(34,211,238,0.06), rgba(96,165,250,0.04))'; }}
  >
    <span style={{ fontSize: 24 }}>📊</span>
    <div style={{ flex: 1 }}>
      <div className="font-display" style={{ fontSize: 14, fontWeight: 600, color: 'var(--text)' }}>Ver todos os 239 KPIs detalhados</div>
      <div style={{ fontSize: 11.5, color: 'var(--text-muted)', fontFamily: 'var(--font-mono)', marginTop: 2 }}>29 sub-categorias · 140 KPIs por stage do Pipeline</div>
    </div>
    <Icon name="arrowRight" size={18} style={{ color: '#22d3ee' }} />
  </button>
);

// ---------- Main page ----------
const SistemaKPIs = ({ onOpenChat }) => {
  const [range, setRange] = React.useState('7d');
  const [selected, setSelected] = React.useState(null);

  const ranges = [
    { id: 'hoje', label: 'Hoje' },
    { id: '7d', label: '7d' },
    { id: '30d', label: '30d' },
    { id: '90d', label: '90d' },
  ];

  const groups = KPI_DATA;

  return (
    <div style={{ display: 'flex', height: '100%', minHeight: 0 }} data-screen-label="SISTEMA · KPIs">
      <div style={{ flex: 1, minWidth: 0, display: 'flex', flexDirection: 'column', height: '100%', overflow: 'hidden' }}>

        {/* Header */}
        <div style={{ padding: '14px 20px 10px', borderBottom: '1px solid var(--border)', display: 'flex', alignItems: 'center', gap: 14, flexShrink: 0 }}>
          <div style={{ flex: 1 }}>
            <div style={{ fontSize: 10, color: 'var(--text-dim)', fontFamily: 'var(--font-mono)', letterSpacing: '0.08em', textTransform: 'uppercase' }}>SISTEMA · RUN · OBSERVAR</div>
            <h2 className="font-display" style={{ margin: '4px 0 0', fontSize: 20, fontWeight: 600, letterSpacing: '-0.01em' }}>KPIs · Saúde do Agente</h2>
          </div>

          {/* Range pills */}
          <div style={{ display: 'inline-flex', gap: 2, padding: 2, background: 'var(--surface-muted)', borderRadius: 999, border: '1px solid var(--border)' }}>
            {ranges.map(r => (
              <button key={r.id} onClick={() => setRange(r.id)} style={{
                padding: '4px 12px', borderRadius: 999,
                fontSize: 11, fontFamily: 'var(--font-display)', fontWeight: 600, letterSpacing: '0.04em',
                background: range === r.id ? 'var(--bg-elev)' : 'transparent',
                color: range === r.id ? 'var(--text)' : 'var(--text-muted)',
                boxShadow: range === r.id ? 'var(--shadow-sm)' : 'none',
              }}>{r.label}</button>
            ))}
          </div>

          <button className="btn btn-sm btn-ghost" title="Refresh"><Icon name="refresh" size={14} /></button>
        </div>

        {/* Body */}
        <div style={{ flex: 1, overflow: 'auto', padding: '14px 20px 20px' }} className="scrollbar">
          <SummaryStrip groups={groups} lastUpdate={`snapshot ${new Date().toLocaleTimeString('pt-PT', { hour: '2-digit', minute: '2-digit' })} · ${range}`} />

          {/* EXECUTIVO section */}
          <SectionDivider label="Executivo" count={Object.values(groups).filter(g => g.tier === 'executivo').reduce((a, g) => a + g.items.length, 0)} hint="vista Board" />
          <div style={{ display: 'grid', gridTemplateColumns: 'repeat(2, 1fr)', gap: 12, alignItems: 'stretch', marginBottom: 18 }}>
            {Object.entries(groups).filter(([, g]) => g.tier === 'executivo').map(([gid, g]) => (
              <QuadrantCard key={gid} group={gid} data={g} onSelect={setSelected} />
            ))}
          </div>

          {/* OPERACIONAL section */}
          <SectionDivider label="Operacional" count={Object.values(groups).filter(g => g.tier === 'operacional').reduce((a, g) => a + g.items.length, 0)} hint="vista DEV" />
          <div style={{ display: 'grid', gridTemplateColumns: 'repeat(2, 1fr)', gap: 12, alignItems: 'stretch', marginBottom: 18 }}>
            {Object.entries(groups).filter(([, g]) => g.tier === 'operacional').map(([gid, g]) => (
              <QuadrantCard key={gid} group={gid} data={g} onSelect={setSelected} />
            ))}
          </div>

          {/* CTA full-width */}
          <DetailCTA />
        </div>
      </div>

      {/* Right insights panel */}
      <DigiInsightsPanel />

      {/* Drill-down */}
      {selected && <KPIDrillPanel entry={selected} onClose={() => setSelected(null)} />}
    </div>
  );
};

window.SistemaKPIs = SistemaKPIs;
