/* global React, Icon, Card, Badge, Button, PageHeader, ProgressBar, Modal, Field, Input, Select, Textarea */
const { useState: _useStateC } = React;

// ============================================================================
// 11 · CONTROL DE COSTOS
// ============================================================================

const COSTOS_PERIODO = {
  hoy: {
    kpis: {total:'$95 USD', deltaTot:'−4% vs ayer', inv:'4.821', deltaInv:'↑12% vs ayer', fallback:'0', alert:'1'},
    rows: [
      {wf:'WF-ADH',  tipo:'NLU + Agente WA',   inv:'1.608',  cost:'$42',  pct:44.2, delta:'+11%', techo:'$50/día', estado:'atencion'},
      {wf:'WF-VVOZ', tipo:'Agente de voz',      inv:'126',    cost:'$21',  pct:22.1, delta:'+33%', techo:'$27/día', estado:'creciendo'},
      {wf:'WF-DOC',  tipo:'Lector docs IA',     inv:'402',    cost:'$16',  pct:16.8, delta:'−3%',  techo:'$20/día', estado:'normal'},
      {wf:'WF-REC',  tipo:'Validación receta',  inv:'280',    cost:'$9',   pct:9.5,  delta:'−6%',  techo:'$14/día', estado:'normal'},
      {wf:'WF-FIN',  tipo:'Clasificador econ.', inv:'205',    cost:'$5',   pct:5.3,  delta:'+0%',  techo:'$8/día',  estado:'normal'},
      {wf:'WF-ALT',  tipo:'Enriquecimiento',    inv:'82',     cost:'$2',   pct:2.1,  delta:'−9%',  techo:'$5/día',  estado:'normal'},
    ],
  },
  semana: {
    kpis: {total:'$654 USD', deltaTot:'−3% vs semana anterior', inv:'33.720', deltaInv:'↑9% vs sem.', fallback:'0', alert:'1'},
    rows: [
      {wf:'WF-ADH',  tipo:'NLU + Agente WA',   inv:'11.240',  cost:'$288', pct:44.0, delta:'+9%',  techo:'$350/sem', estado:'atencion'},
      {wf:'WF-VVOZ', tipo:'Agente de voz',      inv:'880',     cost:'$144', pct:22.0, delta:'+30%', techo:'$186/sem', estado:'creciendo'},
      {wf:'WF-DOC',  tipo:'Lector docs IA',     inv:'2.820',   cost:'$112', pct:17.1, delta:'−2%',  techo:'$140/sem', estado:'normal'},
      {wf:'WF-REC',  tipo:'Validación receta',  inv:'1.960',   cost:'$65',  pct:9.9,  delta:'−5%',  techo:'$93/sem',  estado:'normal'},
      {wf:'WF-FIN',  tipo:'Clasificador econ.', inv:'1.440',   cost:'$33',  pct:5.0,  delta:'+1%',  techo:'$58/sem',  estado:'normal'},
      {wf:'WF-ALT',  tipo:'Enriquecimiento',    inv:'580',     cost:'$18',  pct:2.8,  delta:'−8%',  techo:'$35/sem',  estado:'normal'},
    ],
  },
  mes: {
    kpis: {total:'$2.840 USD', deltaTot:'−4% vs mes anterior', inv:'4.821', deltaInv:'↑12% vs ayer', fallback:'0', alert:'1'},
    rows: [
      {wf:'WF-ADH',  tipo:'NLU + Agente WA',   inv:'48.240',  cost:'$1.240', pct:43.7, delta:'+8%',  techo:'$1.500', estado:'atencion'},
      {wf:'WF-VVOZ', tipo:'Agente de voz',      inv:'3.800',   cost:'$620',   pct:21.8, delta:'+31%', techo:'$800',   estado:'creciendo'},
      {wf:'WF-DOC',  tipo:'Lector docs IA',     inv:'12.100',  cost:'$480',   pct:16.9, delta:'−2%',  techo:'$600',   estado:'normal'},
      {wf:'WF-REC',  tipo:'Validación receta',  inv:'8.400',   cost:'$280',   pct:9.9,  delta:'−5%',  techo:'$400',   estado:'normal'},
      {wf:'WF-FIN',  tipo:'Clasificador econ.', inv:'6.200',   cost:'$140',   pct:4.9,  delta:'+1%',  techo:'$250',   estado:'normal'},
      {wf:'WF-ALT',  tipo:'Enriquecimiento',    inv:'2.480',   cost:'$80',    pct:2.8,  delta:'−8%',  techo:'$150',   estado:'normal'},
    ],
  },
};

const INVOCACIONES = [
  {t:'hoy 11:42', tipo:'NLU', caso:'P-0428', tok:'1.240 tok', cost:'$0.002', res:'efecto_adverso 92%',   mod:'claude-haiku', tone:'ok'},
  {t:'hoy 11:30', tipo:'Voz', caso:'P-0221', tok:'2:14 min',  cost:'$0.089', res:'Derivado clínica',     mod:'Voz v2',       tone:'sun'},
  {t:'hoy 10:15', tipo:'Voz', caso:'P-0428', tok:'0:00 min',  cost:'$0.008', res:'No atendió',           mod:'Voz v2',       tone:'slate'},
  {t:'hoy 09:45', tipo:'Voz', caso:'P-0811', tok:'3:02 min',  cost:'$0.121', res:'Retiro confirmado',    mod:'Voz v2',       tone:'ok'},
  {t:'hoy 09:20', tipo:'NLU', caso:'P-0703', tok:'890 tok',   cost:'$0.001', res:'barrera_logistica 88%',mod:'claude-haiku', tone:'ok'},
  {t:'hoy 08:55', tipo:'NLU', caso:'P-0517', tok:'1.100 tok', cost:'$0.002', res:'olvido 74%',           mod:'claude-haiku', tone:'ok'},
  {t:'hoy 08:30', tipo:'Voz', caso:'P-0634', tok:'1:48 min',  cost:'$0.072', res:'Reagendó retiro',      mod:'Voz v2',       tone:'ok'},
  {t:'hoy 08:10', tipo:'NLU', caso:'P-0920', tok:'760 tok',   cost:'$0.001', res:'costo_cobertura 81%',  mod:'claude-haiku', tone:'ok'},
];

function ControlCostosPage() {
  const [periodo, setPeriodo] = _useStateC('mes');
  const [techosOpen, setTechosOpen] = _useStateC(false);
  const [techosFocus, setTechosFocus] = _useStateC(null);
  const [detalleWf, setDetalleWf] = _useStateC(null);
  const [desestimar, setDesestimar] = _useStateC(false);
  const [toast, setToast] = _useStateC(null);

  const showToast = (msg) => {
    setToast(msg);
    setTimeout(()=>setToast(null), 2400);
  };

  const D = COSTOS_PERIODO[periodo];

  return <div className="px-7 py-6 max-w-[1480px]">
    <PageHeader
      titulo="Control de costos"
      subtitulo="Consumo de IA por workflow · techos y fallbacks configurados"
      action={<div className="flex items-center gap-2">
        <PeriodoPicker value={periodo} onChange={setPeriodo}/>
        <Badge tone="ok" size="sm" dot pulse>Monitoreo activo</Badge>
        <Button variant="outline" size="sm" icon={<Icon.settings c="w-3.5 h-3.5"/>}
          onClick={()=>{setTechosFocus(null); setTechosOpen(true);}}>Configurar techos</Button>
      </div>}/>

    {/* KPI STRIP */}
    <div className="grid grid-cols-4 gap-3 mb-5">
      <CostKpi l="Consumo total" subLabel={periodo==='hoy'?'hoy':periodo==='semana'?'esta semana':'este mes'}
        v={D.kpis.total} sub={D.kpis.deltaTot} tone="ok"/>
      <CostKpi l="Invocaciones IA" subLabel="hoy"
        v={D.kpis.inv} sub={D.kpis.deltaInv}/>
      <CostKpi l="Flujos en fallback" subLabel="ahora"
        v={D.kpis.fallback} sub="Todos en modo principal" tone="ok"/>
      <CostKpi l="Alertas de desvío" subLabel="activas"
        v={D.kpis.alert} sub="WF-ADH supera patrón esperado" tone="warn"/>
    </div>

    {/* ALERTA ACTIVA */}
    <div className="relative bg-white rounded-xl overflow-hidden mb-5"
      style={{boxShadow:'0 1px 3px rgba(15,23,42,0.05)', border:'1px solid #F3D9A8', borderLeft:'3px solid #D28513'}}>
      <div className="px-5 py-4">
        <div className="flex items-start gap-3">
          <div className="w-7 h-7 rounded-lg bg-[#FDF2DC] flex items-center justify-center shrink-0 mt-0.5">
            <Icon.alert c="w-4 h-4 text-[#D28513]"/>
          </div>
          <div className="flex-1 min-w-0">
            <div className="flex items-baseline gap-2">
              <span className="text-[10px] font-mono uppercase tracking-wider text-[#D28513] font-semibold">Alerta de desvío</span>
              <span className="text-[10.5px] text-ink-400">hace 18 min · auto-generado</span>
            </div>
            <div className="text-[13.5px] text-ink-800 font-semibold mt-1 font-display">
              WF-ADH consumió $1.240 vs patrón esperado $1.050 <span className="text-[#D28513]">(+18,1%)</span>
            </div>
            <div className="text-[12px] text-ink-600 mt-0.5">Causa: +31% en derivaciones al agente de voz este mes.</div>

            {/* mini bars */}
            <AlertaMiniBars/>
          </div>
          <div className="flex flex-col gap-1.5 shrink-0">
            <Button variant="primary" size="sm" onClick={()=>setDetalleWf('WF-ADH')}>Ver invocaciones</Button>
            <Button variant="outline" size="sm" onClick={()=>{setTechosFocus('WF-ADH'); setTechosOpen(true);}}>Ajustar techo</Button>
            <Button variant="ghost" size="sm" onClick={()=>setDesestimar(true)}>Desestimar</Button>
          </div>
        </div>
      </div>
    </div>

    {/* SECCIÓN 1 — Tabla consumo por flujo */}
    <Card title="Consumo por flujo"
      subtitle={periodo==='hoy'?'Hoy':periodo==='semana'?'Esta semana':'Este mes · abril 2026'}
      footer="El resto de flujos corre con lógica determinística. Sin costo variable."
      className="mb-4">
      <div className="grid grid-cols-[100px_1fr_90px_90px_80px_80px_100px_110px] gap-2 px-2 py-2 border-b border-slate-100 text-[10px] font-mono uppercase tracking-wider text-ink-400 font-semibold">
        <span>Workflow</span>
        <span>Tipo agente</span>
        <span className="text-right">Invocaciones</span>
        <span className="text-right">Costo USD</span>
        <span className="text-right">% total</span>
        <span className="text-right">vs prev.</span>
        <span className="text-right">Techo</span>
        <span className="text-center">Estado</span>
      </div>
      {D.rows.map(r => <button key={r.wf} type="button" onClick={()=>setDetalleWf(r.wf)}
        className="w-full grid grid-cols-[100px_1fr_90px_90px_80px_80px_100px_110px] gap-2 items-center px-2 py-2.5 border-b border-slate-100 last:border-0 text-[12px] text-left hover:bg-slate-50">
        <span className="font-mono font-bold text-ink-800">{r.wf}</span>
        <span className="text-ink-600">{r.tipo}</span>
        <span className="font-mono tabular-nums text-right">{r.inv}</span>
        <span className="font-mono font-bold tabular-nums text-right text-ink-800">{r.cost}</span>
        <span className="font-mono tabular-nums text-right text-ink-500">{r.pct.toFixed(1)}%</span>
        <span className={'font-mono tabular-nums text-right '+(r.delta.startsWith('+')&&parseInt(r.delta)>=10?'text-[#D28513] font-semibold':r.delta.startsWith('−')?'text-[#1E8057]':'text-ink-500')}>{r.delta}</span>
        <span className="font-mono text-[11px] tabular-nums text-right text-ink-500">{r.techo}</span>
        <div className="flex justify-center">
          {r.estado==='atencion'  && <Badge tone="warn"  size="sm" dot>Atención</Badge>}
          {r.estado==='creciendo' && <Badge tone="warn"  size="sm" dot>Creciendo</Badge>}
          {r.estado==='normal'    && <Badge tone="ok"    size="sm">Normal</Badge>}
        </div>
      </button>)}
    </Card>

    {/* SECCIÓN 2 — Evolución + donut */}
    <div className="grid grid-cols-3 gap-3 mb-4">
      <Card title="Evolución 6 meses" subtitle="Costo total mensual · USD" className="col-span-2">
        <StackedAreaCost/>
      </Card>
      <Card title="Distribución por tipo de agente" subtitle={periodo==='mes'?'Este mes':periodo==='semana'?'Esta semana':'Hoy'}>
        <CostDonut/>
      </Card>
    </div>

    {/* Panel techos */}
    {techosOpen && <ConfigurarTechos onClose={()=>setTechosOpen(false)} focus={techosFocus} onSave={()=>{setTechosOpen(false); showToast('Techo actualizado. Aplica desde la próxima invocación.');}}/>}

    {/* Drawer invocaciones */}
    {detalleWf && <DetalleInvocaciones wf={detalleWf} onClose={()=>setDetalleWf(null)}/>}

    {/* Modal desestimar */}
    <Modal open={desestimar} onClose={()=>setDesestimar(false)} title="¿Desestimar alerta?"
      subtitle="El sistema seguirá monitoreando el consumo de WF-ADH, pero la alerta actual se marcará como revisada."
      footer={<>
        <Button variant="outline" size="sm" onClick={()=>setDesestimar(false)}>Cancelar</Button>
        <Button variant="primary" size="sm" onClick={()=>{setDesestimar(false); showToast('Alerta desestimada. Monitoreo continúa activo.');}}>Confirmar</Button>
      </>}>
      <div className="text-[12.5px] text-ink-700 leading-relaxed">
        La alerta quedará registrada en Trazabilidad como revisada por tu usuario. Si el desvío persiste la próxima semana, el sistema volverá a alertar.
      </div>
    </Modal>

    {/* Toast */}
    {toast && <div className="fixed bottom-6 left-1/2 -translate-x-1/2 z-[60] bg-ink-800 text-white text-[12.5px] px-4 py-2.5 rounded-lg shadow-[0_8px_24px_-6px_rgba(15,23,42,0.4)] flex items-center gap-2">
      <Icon.check c="w-4 h-4 text-[#6EDBAB]"/>
      {toast}
    </div>}
  </div>;
}

// ---- Mini bars · alerta WF-ADH
function AlertaMiniBars() {
  const bars = [{s:'S1',r:280,e:262},{s:'S2',r:330,e:262},{s:'S3',r:380,e:262},{s:'S4',r:250,e:262}];
  const [progress, setProgress] = _useStateC(0);
  const [hover, setHover] = _useStateC(null);
  React.useEffect(() => {
    let raf; const t0 = performance.now(); const dur = 800;
    const tick = () => {
      const e = Math.min(1, (performance.now()-t0)/dur);
      const eased = 1 - Math.pow(1-e, 3);
      setProgress(eased);
      if (e<1) raf = requestAnimationFrame(tick);
    };
    raf = requestAnimationFrame(tick);
    return () => cancelAnimationFrame(raf);
  }, []);
  return <>
    <div className="flex items-end gap-5 mt-3 px-1">
      {bars.map((w, i) => {
        const over = w.r > w.e;
        const diff = w.r - w.e;
        const isHover = hover===i;
        return <div key={w.s} className="flex-1 flex flex-col gap-1 relative"
          onMouseEnter={()=>setHover(i)} onMouseLeave={()=>setHover(null)}>
          {isHover && <div className="absolute bottom-[calc(100%+4px)] left-1/2 -translate-x-1/2 z-10 bg-ink-800 text-white rounded-md px-2.5 py-1.5 text-[10.5px] whitespace-nowrap shadow-[0_6px_16px_-4px_rgba(15,23,42,0.4)]">
            <div className="font-mono text-white/60 text-[9.5px] uppercase tracking-wider">{w.s}</div>
            <div className="flex items-center gap-2 mt-0.5">
              <span className="font-mono">Real <span className={'font-bold tabular-nums '+(over?'text-[#F0A858]':'text-[#6EDBAB]')}>${w.r}</span></span>
              <span className="text-white/40">·</span>
              <span className="font-mono">Esp. <span className="font-bold tabular-nums">${w.e}</span></span>
            </div>
            <div className={'font-mono text-[10px] mt-0.5 '+(over?'text-[#F0A858]':'text-white/60')}>{over?'+':''}{diff>0?'+':''}${Math.abs(diff)} {over?'sobre':'bajo'} patrón</div>
          </div>}
          <div className="flex items-end gap-1 h-10">
            <div className="flex-1 rounded-t transition-all duration-200" style={{
              background: over?'#D28513':'#268AA6',
              height:(w.r/400*100*progress)+'%',
              opacity: hover===null?0.85:(isHover?1:0.45),
              transform: isHover?'scaleY(1.04)':'scaleY(1)',
              transformOrigin:'bottom'
            }}/>
            <div className="flex-1 rounded-t bg-slate-200 transition-all duration-200" style={{
              height:(w.e/400*100*progress)+'%',
              opacity: hover===null?1:(isHover?1:0.45)
            }}/>
          </div>
          <div className={'text-[9.5px] font-mono text-center '+(isHover?'text-ink-800 font-semibold':'text-ink-400')}>{w.s}</div>
          <div className="text-[9.5px] font-mono tabular-nums text-center">
            <span className={over?'text-[#D28513] font-semibold':'text-ink-700 font-semibold'}>${w.r}</span>
            <span className="text-ink-400"> / ${w.e}</span>
          </div>
        </div>;
      })}
    </div>
    <div className="flex items-center gap-4 mt-2 text-[10.5px]">
      <span className="flex items-center gap-1.5"><span className="w-2.5 h-2.5 rounded-sm bg-[#D28513]/85"/><span className="text-ink-500">Real</span></span>
      <span className="flex items-center gap-1.5"><span className="w-2.5 h-2.5 rounded-sm bg-slate-200"/><span className="text-ink-500">Esperado</span></span>
    </div>
  </>;
}

// ---- Periodo picker
function PeriodoPicker({value, onChange}) {
  const opts = [{k:'hoy',l:'Hoy'},{k:'semana',l:'Semana'},{k:'mes',l:'Este mes'}];
  return <div className="flex items-center bg-slate-100 rounded-lg p-0.5">
    {opts.map(o => <button key={o.k} type="button" onClick={()=>onChange(o.k)}
      className={'px-3 py-1 text-[11.5px] font-medium rounded-md transition-colors '+(value===o.k?'bg-white text-ink-800 shadow-sm':'text-ink-500 hover:text-ink-700')}>{o.l}</button>)}
  </div>;
}

function CostKpi({l, subLabel, v, sub, tone}) {
  const fg = tone==='ok'?'text-[#1E8057]':tone==='warn'?'text-[#D28513]':'text-ink-800';
  const subFg = tone==='ok'?'text-[#1E8057]':tone==='warn'?'text-[#D28513]':'text-ink-500';
  return <div className="bg-white rounded-xl border border-slate-100 px-4 py-3" style={{boxShadow:'0 1px 2px rgba(15,23,42,0.04)'}}>
    <div className="flex items-center justify-between">
      <div className="text-[10px] font-mono uppercase tracking-wider text-ink-400 font-semibold">{l}</div>
      <span className="text-[9.5px] font-mono text-ink-400">{subLabel}</span>
    </div>
    <div className={'font-display font-extrabold text-[26px] tabular-nums leading-none mt-1.5 '+fg}>{v}</div>
    {sub && <div className={'text-[11px] mt-1.5 '+subFg}>{sub}</div>}
  </div>;
}

// ---- Stacked area chart · 6 meses
function StackedAreaCost() {
  const meses = ['oct/25','nov/25','dic/25','ene/26','feb/26','mar/26'];
  const total = [1840, 2100, 2280, 2560, 2710, 2960];
  const layers = [
    {name:'WF-ADH',  color:'#268AA6', pcts:[0.48,0.47,0.46,0.45,0.44,0.44]},
    {name:'WF-VVOZ', color:'#F0A858', pcts:[0.08,0.09,0.11,0.16,0.20,0.22]},
    {name:'WF-DOC',  color:'#0B4A5F', pcts:[0.20,0.19,0.18,0.17,0.17,0.17]},
    {name:'WF-REC',  color:'#7FB4C4', pcts:[0.12,0.12,0.11,0.10,0.10,0.10]},
    {name:'WF-FIN',  color:'#B7D4DD', pcts:[0.07,0.07,0.07,0.06,0.05,0.05]},
    {name:'WF-ALT',  color:'#E2EBEF', pcts:[0.05,0.06,0.07,0.06,0.04,0.02]},
  ];
  const h = 200, w = 600;
  const max = 3200, min = 0;
  const y = v => h - ((v-min)/(max-min))*h;
  const step = w/(total.length-1);

  // entry animation
  const [progress, setProgress] = _useStateC(0);
  React.useEffect(() => {
    let raf; const t0 = performance.now(); const dur = 900;
    const tick = () => {
      const e = Math.min(1, (performance.now()-t0)/dur);
      const eased = 1 - Math.pow(1-e, 3);
      setProgress(eased);
      if (e<1) raf = requestAnimationFrame(tick);
    };
    raf = requestAnimationFrame(tick);
    return () => cancelAnimationFrame(raf);
  }, []);

  const [hoverIdx, setHoverIdx] = _useStateC(null);
  const svgRef = React.useRef(null);
  const wrapRef = React.useRef(null);
  const [tipPos, setTipPos] = _useStateC({x:0,y:0});

  const stacked = total.map((t,i) => {
    const vals = layers.map(L => t*L.pcts[i]);
    const cum = []; let acc = 0;
    for (let k=0;k<vals.length;k++){ acc += vals[k]; cum.push(acc); }
    return {vals, cum};
  });

  const fIdx = 4;
  const fX = fIdx*step;

  const onMove = (e) => {
    const rect = svgRef.current.getBoundingClientRect();
    const wrap = wrapRef.current.getBoundingClientRect();
    const scaleX = rect.width / (w+96);
    const svgX = (e.clientX - rect.left) / scaleX - 44;
    let best = 0, bestD = Infinity;
    for (let i=0;i<total.length;i++){
      const d = Math.abs(i*step - svgX);
      if (d<bestD){ bestD = d; best = i; }
    }
    setHoverIdx(best);
    setTipPos({x: e.clientX - wrap.left, y: e.clientY - wrap.top});
  };

  return <div ref={wrapRef} className="mt-2 relative" onMouseLeave={()=>setHoverIdx(null)}>
    <svg ref={svgRef} viewBox={'-44 -12 '+(w+96)+' '+(h+50)} className="w-full" onMouseMove={onMove}>
      {/* grid */}
      {[1000,2000,3000].map(g => <g key={g}>
        <line x1={0} x2={w} y1={y(g)} y2={y(g)} stroke="#E5E8EC" strokeWidth="1" strokeDasharray="2 3"/>
        <text x={-10} y={y(g)+4} textAnchor="end" fontSize="10" fontFamily="monospace" fill="#94A3B8" fontWeight="500">${(g/1000).toFixed(1)}k</text>
      </g>)}
      {/* clip for entry animation (wipe left→right) */}
      <defs>
        <clipPath id="sa-clip"><rect x={-12} y={-12} width={w*progress+12} height={h+24}/></clipPath>
      </defs>
      <g clipPath="url(#sa-clip)">
        {layers.map((L, li) => {
          const prevCum = stacked.map(s => li===0 ? 0 : s.cum[li-1]);
          const thisCum = stacked.map(s => s.cum[li]);
          let d = '';
          thisCum.forEach((v,i) => { d += (i===0?'M':'L')+(i*step)+','+y(v); });
          for (let i=prevCum.length-1;i>=0;i--) d += 'L'+(i*step)+','+y(prevCum[i]);
          d += 'Z';
          return <path key={L.name} d={d} fill={L.color} opacity="0.92"/>;
        })}
      </g>
      {/* marcador feb/26 */}
      <line x1={fX} x2={fX} y1={-2} y2={h} stroke="#B93535" strokeWidth="1.5" strokeDasharray="3 3" style={{opacity:progress}}/>
      <g style={{opacity:progress,transform:`translateY(${(1-progress)*-6}px)`,transition:'all 200ms'}}>
        <rect x={fX-78} y={h-30} width="156" height="20" rx="10" fill="#B93535"/>
        <circle cx={fX-66} cy={h-20} r="3" fill="#fff"/>
        <text x={fX-55} y={h-16} textAnchor="start" fontSize="10" fontFamily="monospace" fill="#fff" fontWeight="700" letterSpacing="0.3">
          ACTIVACIÓN <tspan fontWeight="400" opacity="0.85">agente voz</tspan>
        </text>
      </g>
      {/* totales + puntos hover */}
      {total.map((v,i) => {
        const active = hoverIdx===i;
        return <g key={i}>
          <text x={i*step} y={y(v)-14} textAnchor="middle" fontSize="11" fontFamily="Inter, system-ui, sans-serif" letterSpacing="-0.2" fill="#0F172A" fontWeight="700" style={{opacity:progress, fontVariantNumeric:'tabular-nums'}}>${v.toLocaleString()}</text>
          <text x={i*step} y={h+22} textAnchor="middle" fontSize="10.5" fontFamily="monospace" fill={active?'#0F172A':'#94A3B8'} fontWeight={active?700:500}>{meses[i]}</text>
          {active && <>
            <line x1={i*step} x2={i*step} y1={0} y2={h} stroke="#0F172A" strokeWidth="1" strokeDasharray="2 2" opacity="0.3"/>
            <circle cx={i*step} cy={y(v)} r="5" fill="#0F172A" stroke="#fff" strokeWidth="2"/>
          </>}
        </g>;
      })}
    </svg>
    {hoverIdx!==null && progress>0.5 && <div
      className="absolute pointer-events-none z-10 bg-ink-800 text-white rounded-lg px-3 py-2 shadow-[0_8px_24px_-6px_rgba(15,23,42,0.4)] min-w-[160px]"
      style={{left:Math.min(tipPos.x+12, 380), top:tipPos.y-10}}>
      <div className="text-[10px] font-mono uppercase tracking-wider text-white/60 font-semibold">{meses[hoverIdx]}</div>
      <div className="font-display font-extrabold text-[16px] tabular-nums leading-none mt-0.5">${total[hoverIdx]}</div>
      <div className="border-t border-white/15 mt-1.5 pt-1.5 space-y-0.5">
        {layers.map((L, li) => <div key={L.name} className="flex items-center gap-1.5 text-[10.5px]">
          <span className="w-1.5 h-1.5 rounded-sm shrink-0" style={{background:L.color}}/>
          <span className="font-mono text-white/70 flex-1">{L.name}</span>
          <span className="font-mono tabular-nums font-bold">${Math.round(stacked[hoverIdx].vals[li])}</span>
        </div>)}
      </div>
    </div>}
    <div className="flex flex-wrap gap-x-4 gap-y-1.5 mt-4 pt-3 border-t border-slate-100 text-[11px]">
      {layers.map(L => <span key={L.name} className="flex items-center gap-1.5">
        <span className="w-3 h-3 rounded-sm" style={{background:L.color}}/>
        <span className="text-ink-600 font-mono font-medium">{L.name}</span>
      </span>)}
    </div>
  </div>;
}

// ---- Donut · distribución por tipo de agente
function CostDonut() {
  const segs = [
    {l:'Agentes WA',   v:43.7, color:'#268AA6', cost:'$1.240'},
    {l:'Agentes de voz',v:21.8, color:'#F0A858', cost:'$620'},
    {l:'Lectura docs', v:16.9, color:'#0B4A5F', cost:'$480'},
    {l:'Clasificadores',v:17.6,color:'#7FB4C4', cost:'$500'},
  ];
  const R = 62, r = 38, cx = 80, cy = 80;

  const [progress, setProgress] = _useStateC(0);
  const [hoverIdx, setHoverIdx] = _useStateC(null);
  React.useEffect(() => {
    let raf; const t0 = performance.now(); const dur = 900;
    const tick = () => {
      const e = Math.min(1, (performance.now()-t0)/dur);
      const eased = 1 - Math.pow(1-e, 3);
      setProgress(eased);
      if (e<1) raf = requestAnimationFrame(tick);
    };
    raf = requestAnimationFrame(tick);
    return () => cancelAnimationFrame(raf);
  }, []);

  const buildArc = (a0, a1, R, r) => {
    const large = (a1-a0) > Math.PI ? 1 : 0;
    const x0 = cx + R*Math.cos(a0), y0 = cy + R*Math.sin(a0);
    const x1 = cx + R*Math.cos(a1), y1 = cy + R*Math.sin(a1);
    const ix0 = cx + r*Math.cos(a0), iy0 = cy + r*Math.sin(a0);
    const ix1 = cx + r*Math.cos(a1), iy1 = cy + r*Math.sin(a1);
    return `M ${x0} ${y0} A ${R} ${R} 0 ${large} 1 ${x1} ${y1} L ${ix1} ${iy1} A ${r} ${r} 0 ${large} 0 ${ix0} ${iy0} Z`;
  };

  let acc = 0;
  const arcs = segs.map((s, i) => {
    const a0 = (acc/100) * Math.PI*2 * progress - Math.PI/2;
    acc += s.v;
    const a1 = (acc/100) * Math.PI*2 * progress - Math.PI/2;
    return {d: buildArc(a0, a1, hoverIdx===i ? R+5 : R, r), color:s.color, idx:i};
  });

  return <div className="flex flex-col items-center gap-4 mt-2">
    <svg viewBox="0 0 160 160" className="w-[170px] h-[170px] shrink-0" onMouseLeave={()=>setHoverIdx(null)}>
      {arcs.map((a,i) => <path key={i} d={a.d} fill={a.color} opacity={hoverIdx===null||hoverIdx===i?0.95:0.35}
        style={{transition:'all 180ms ease-out', cursor:'pointer'}}
        onMouseEnter={()=>setHoverIdx(i)}/>)}
      <text x="80" y="74" textAnchor="middle" fontSize="9.5" fontFamily="monospace" fill="#94A3B8" fontWeight="600" letterSpacing="0.5">
        {hoverIdx===null ? 'TOTAL' : segs[hoverIdx].l.toUpperCase()}
      </text>
      <text x="80" y="94" textAnchor="middle" fontSize="22" fontFamily="Inter, system-ui, sans-serif" fontWeight="800" letterSpacing="-0.5" fill="#0F172A" style={{fontVariantNumeric:'tabular-nums'}}>
        {hoverIdx===null ? '$2.840' : segs[hoverIdx].cost}
      </text>
      {hoverIdx!==null && <text x="80" y="105" textAnchor="middle" fontSize="10" fontFamily="monospace" fill="#94A3B8" fontWeight="600">
        {segs[hoverIdx].v}%
      </text>}
    </svg>
    <div className="w-full space-y-1.5">
      {segs.map((s, i) => <div key={s.l} className="flex items-center gap-2 text-[12px] cursor-pointer py-0.5"
        onMouseEnter={()=>setHoverIdx(i)} onMouseLeave={()=>setHoverIdx(null)}
        style={{opacity:hoverIdx===null||hoverIdx===i?1:0.35, transition:'opacity 150ms'}}>
        <span className="w-3 h-3 rounded-sm shrink-0" style={{background:s.color}}/>
        <span className="text-ink-700 flex-1 truncate font-medium">{s.l}</span>
        <span className="font-mono font-bold tabular-nums text-ink-800">{s.v}%</span>
      </div>)}
    </div>
  </div>;
}

// ---- Panel Configurar techos
function ConfigurarTechos({onClose, focus, onSave}) {
  const [rows, setRows] = _useStateC([
    {wf:'WF-ADH',  monto:1500, fb:'degradar', alerta:80},
    {wf:'WF-VVOZ', monto:800,  fb:'pausar',   alerta:70},
    {wf:'WF-DOC',  monto:600,  fb:'degradar', alerta:80},
    {wf:'WF-REC',  monto:400,  fb:'alertar',  alerta:80},
    {wf:'WF-FIN',  monto:250,  fb:'alertar',  alerta:80},
    {wf:'WF-ALT',  monto:150,  fb:'alertar',  alerta:90},
  ]);
  const consumo = 2840;
  const techoGlobal = rows.reduce((a,r)=>a+r.monto,0);
  const upd = (i,patch) => setRows(rs => rs.map((r,k)=>k===i?{...r,...patch}:r));

  return <div className="fixed inset-0 z-50 flex justify-end" onClick={onClose}>
    <div className="absolute inset-0 bg-ink-900/40 backdrop-blur-[1px]"/>
    <div onClick={e=>e.stopPropagation()} className="relative w-[640px] h-full bg-white shadow-[0_0_40px_rgba(0,0,0,0.15)] flex flex-col">
      <div className="px-6 pt-5 pb-4 border-b border-slate-100 flex items-start justify-between">
        <div>
          <h3 className="text-[16px] font-semibold text-ink-800 font-display">Configurar techos</h3>
          <p className="text-[12px] text-ink-500 mt-0.5">Límite de consumo y comportamiento de fallback por workflow.</p>
        </div>
        <Button variant="ghost" size="sm" onClick={onClose}>Cerrar</Button>
      </div>
      <div className="flex-1 overflow-y-auto px-6 py-4 space-y-3">
        {rows.map((r, i) => {
          const hi = focus===r.wf;
          return <div key={r.wf} className={'rounded-lg ring-1 px-4 py-3 '+(hi?'ring-helios-300 bg-helios-50':'ring-slate-200 bg-white')}>
            <div className="flex items-center justify-between">
              <div className="flex items-center gap-2">
                <span className="font-mono font-bold text-[12.5px] text-ink-800">{r.wf}</span>
                {hi && <Badge tone="helios" size="sm">Foco</Badge>}
              </div>
              <div className="flex items-center gap-2">
                <span className="text-[10.5px] font-mono uppercase tracking-wider text-ink-400 font-semibold">Techo</span>
                <div className="flex items-center bg-white rounded-md ring-1 ring-slate-200 focus-within:ring-helios-400">
                  <span className="pl-2 pr-1 text-[12px] text-ink-500">$</span>
                  <input type="number" value={r.monto} onChange={e=>upd(i,{monto:parseInt(e.target.value||0)})}
                    className="w-20 bg-transparent text-right pr-2 py-1 text-[12px] font-mono font-semibold tabular-nums text-ink-800 focus:outline-none"/>
                  <span className="px-2 text-[10.5px] font-mono text-ink-400 border-l border-slate-200">/mes</span>
                </div>
              </div>
            </div>

            <div className="mt-3">
              <div className="text-[10px] font-mono uppercase tracking-wider text-ink-400 font-semibold mb-1.5">Fallback al superar techo</div>
              <div className="grid grid-cols-3 gap-1.5">
                {[{k:'degradar',l:'Degradar a modelo más barato'},{k:'pausar',l:'Pausar y derivar a humano'},{k:'alertar',l:'Solo alertar'}].map(o => {
                  const sel = r.fb===o.k;
                  return <button key={o.k} type="button" onClick={()=>upd(i,{fb:o.k})}
                    className={'text-left rounded-md px-2.5 py-2 ring-1 text-[11px] leading-snug transition-colors '+(sel?'bg-helios-50 ring-helios-300 text-helios-800 font-medium':'bg-white ring-slate-200 text-ink-600 hover:bg-slate-50')}>
                    <div className="flex items-center gap-1.5">
                      <span className={'w-3 h-3 rounded-full ring-2 ring-inset shrink-0 '+(sel?'bg-helios-600 ring-helios-600':'bg-white ring-slate-300')}/>
                      <span>{o.l}</span>
                    </div>
                  </button>;
                })}
              </div>
            </div>

            <div className="mt-3 flex items-center justify-between pt-2 border-t border-slate-100">
              <span className="text-[11.5px] text-ink-600">Alertar al <span className="font-mono font-bold tabular-nums">{r.alerta}%</span> del techo</span>
              <input type="range" min="50" max="95" step="5" value={r.alerta}
                onChange={e=>upd(i,{alerta:parseInt(e.target.value)})}
                className="w-36 accent-helios-600"/>
            </div>
          </div>;
        })}
      </div>
      <div className="px-6 py-3 border-t border-slate-100 bg-slate-50">
        <div className="flex items-center justify-between text-[11.5px] text-ink-600 mb-2">
          <span>Techo global configurado</span>
          <span className="font-mono font-bold tabular-nums text-ink-800">${techoGlobal.toLocaleString()}/mes</span>
        </div>
        <div className="flex items-center gap-2">
          <div className="flex-1"><ProgressBar value={consumo} max={techoGlobal} tone={consumo/techoGlobal>0.8?'warn':'ok'}/></div>
          <span className="text-[11px] text-ink-500">Consumo actual <span className="font-mono font-bold text-ink-800">${consumo.toLocaleString()}</span> ({Math.round(consumo/techoGlobal*100)}%)</span>
        </div>
      </div>
      <div className="px-6 py-3 border-t border-slate-100 flex items-center justify-end gap-2">
        <Button variant="ghost" size="sm" onClick={onClose}>Cancelar</Button>
        <Button variant="primary" size="sm" onClick={onSave}>Guardar</Button>
      </div>
    </div>
  </div>;
}

// ---- Drawer detalle invocaciones
function DetalleInvocaciones({wf, onClose}) {
  return <div className="fixed inset-0 z-50 flex justify-end" onClick={onClose}>
    <div className="absolute inset-0 bg-ink-900/40 backdrop-blur-[1px]"/>
    <div onClick={e=>e.stopPropagation()} className="relative w-[820px] h-full bg-white shadow-[0_0_40px_rgba(0,0,0,0.15)] flex flex-col">
      <div className="px-6 pt-5 pb-4 border-b border-slate-100 flex items-start justify-between">
        <div>
          <div className="flex items-center gap-2">
            <h3 className="text-[16px] font-semibold text-ink-800 font-display">Detalle invocaciones</h3>
            <Badge tone="helios" size="sm">{wf}</Badge>
          </div>
          <p className="text-[12px] text-ink-500 mt-0.5">Últimas 8 invocaciones · filtradas por workflow</p>
        </div>
        <Button variant="ghost" size="sm" onClick={onClose}>Cerrar</Button>
      </div>
      <div className="flex-1 overflow-y-auto">
        <div className="grid grid-cols-[100px_60px_90px_90px_80px_1fr_100px] gap-2 px-6 py-2 border-b border-slate-100 text-[10px] font-mono uppercase tracking-wider text-ink-400 font-semibold bg-slate-50">
          <span>Timestamp</span><span>Tipo</span><span>Caso</span><span>Tokens/min</span><span className="text-right">Costo</span><span>Resultado</span><span>Modelo</span>
        </div>
        {INVOCACIONES.map((r, i) => <div key={i}
          className="grid grid-cols-[100px_60px_90px_90px_80px_1fr_100px] gap-2 items-center px-6 py-2.5 border-b border-slate-100 text-[12px] hover:bg-slate-50">
          <span className="font-mono text-[10.5px] text-ink-500">{r.t}</span>
          <Badge tone={r.tipo==='Voz'?'sun':'helios'} size="sm">{r.tipo}</Badge>
          <span className="font-mono text-[11px] font-semibold text-ink-700">{r.caso}</span>
          <span className="font-mono text-[11px] tabular-nums text-ink-600">{r.tok}</span>
          <span className="font-mono font-bold tabular-nums text-ink-800 text-right">{r.cost}</span>
          <span className="text-ink-600 truncate">{r.res}</span>
          <span className="font-mono text-[10.5px] text-ink-500">{r.mod}</span>
        </div>)}
      </div>
      <div className="px-6 py-3 border-t border-slate-100 text-[11px] text-ink-400">Cada invocación registrada también en Trazabilidad.</div>
    </div>
  </div>;
}

window.ControlCostosPage = ControlCostosPage;
