/* global React, DATA, Icon, ExtraIcons, Card, Badge, Button, Avatar, StatePill, RiskPill, ProgressBar, PageHeader, Tabs, Modal, Field, Input, Select, Textarea, useToast, ChartTooltip, useOnScreen */
const { useState, useMemo, useRef } = React;

// ---------- HbA1c animated + interactive line chart ----------
function HbA1cChart({data, objetivo}) {
  const wrapRef = useRef(null);
  const visible = useOnScreen(wrapRef);
  const [hover, setHover] = useState(null); // index or null
  const W = 400, H = 180, padL = 40, padR = 40, padT = 10, padB = 20;
  const innerW = W - padL - padR;
  const innerH = H - padT - padB;
  const max = Math.max(...data.map(h=>h.v), objetivo+1);
  const min = Math.min(...data.map(h=>h.v), objetivo) - 0.4;
  const range = max - min;
  const x = (i)=> padL + i*(innerW/(data.length-1));
  const y = (v)=> padT + innerH - ((v-min)/range)*innerH;

  // build path
  const pathD = data.map((h,i)=> (i===0?'M':'L') + x(i) + ',' + y(h.v)).join(' ');
  const pathLen = useMemo(()=> {
    let L=0; for (let i=1;i<data.length;i++){ const dx=x(i)-x(i-1), dy=y(data[i].v)-y(data[i-1].v); L+=Math.sqrt(dx*dx+dy*dy);} return L;
  },[data]);

  const objY = y(objetivo);
  const hoverIdx = hover;
  const hoverPoint = hoverIdx!=null ? data[hoverIdx] : null;
  const prev = hoverIdx!=null && hoverIdx>0 ? data[hoverIdx-1] : null;
  const delta = hoverPoint && prev ? +(hoverPoint.v - prev.v).toFixed(1) : null;
  const tooltipSide = hoverIdx!=null && hoverIdx<=0 ? 'right' : 'top';

  // Overlay tooltip position (convert svg x/y to % of container)
  const wrapW = wrapRef.current?.clientWidth || 0;
  const wrapH = wrapRef.current?.clientHeight || 0;
  const tX = hoverIdx!=null ? (x(hoverIdx)/W)*wrapW : 0;
  const tY = hoverIdx!=null ? (y(hoverPoint.v)/H)*wrapH : 0;

  return <div ref={wrapRef} className="h-[180px] relative">
    <svg viewBox={`0 0 ${W} ${H}`} className="w-full h-full" onMouseLeave={()=>setHover(null)}>
      {/* Objective line */}
      <line x1="0" y1={objY} x2={W} y2={objY} stroke="#2EA571" strokeDasharray="4 4" strokeWidth="1"/>
      <text x={W-2} y={objY-4} textAnchor="end" fontSize="10" fill="#1E8057" fontFamily="Inter" fontWeight="600">obj {objetivo}%</text>

      {/* Crosshair */}
      {hoverIdx!=null && <line x1={x(hoverIdx)} y1={y(hoverPoint.v)} x2={x(hoverIdx)} y2={H-padB} stroke="#D6DAE2" strokeDasharray="2 3" strokeWidth="1"/>}

      {/* Line path (animated draw) */}
      {visible && <path d={pathD} fill="none" stroke="#1B7690" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round"
        className="chart-line-anim" style={{'--dash': pathLen}}/>}

      {/* Month labels */}
      {data.map((h,i)=> <text key={'m'+i} x={x(i)} y={H-4} textAnchor="middle" fontSize="9" fontFamily="Inter" fill="#7E8798">{h.m}</text>)}

      {/* Dots + hit areas */}
      {data.map((h,i)=>{
        const cx=x(i), cy=y(h.v);
        const isHover = hoverIdx===i;
        const dim = hoverIdx!=null && !isHover ? 0.35 : 1;
        const r = isHover ? 7 : 4;
        return <g key={i} style={{opacity:dim, transition:'opacity 150ms'}}>
          {visible && <circle cx={cx} cy={cy} r={r} fill={h.v>objetivo?'#E04B4B':'#2EA571'}
            className="chart-dot-anim"
            style={{animationDelay:(0.6 + i*0.06)+'s', transition:'r 150ms'}}/>}
          {/* static label above dot */}
          <text x={cx} y={cy-10} textAnchor="middle" fontSize="10" fontFamily="Inter" fill="#272D39" fontWeight="700"
            style={{opacity: isHover?0:1, transition:'opacity 150ms'}}>{h.v}</text>
          {/* hit area */}
          <rect x={cx-16} y={padT} width="32" height={innerH+10} fill="transparent"
            onMouseEnter={()=>setHover(i)}/>
        </g>;
      })}
    </svg>

    {hoverIdx!=null && <ChartTooltip pos={{x:tX, y:tY}} side={tooltipSide}>
      <div className="text-[10px] font-mono uppercase tracking-wider text-ink-400 font-semibold">Período</div>
      <div className="text-[12.5px] font-semibold text-ink-800 mb-1.5">{hoverPoint.m}</div>
      <div className={'font-display font-extrabold text-[22px] tabular-nums leading-none '+(hoverPoint.v>objetivo?'text-[#B93535]':'text-[#1E8057]')}>
        {hoverPoint.v}%
      </div>
      <div className="text-[10.5px] text-ink-500 font-mono mt-0.5">obj: {objetivo}%</div>
      {delta!=null && <div className={'text-[10.5px] font-semibold mt-1 '+(delta>0?'text-[#B93535]':delta<0?'text-[#1E8057]':'text-ink-500')}>
        {delta>0?'▲ +':delta<0?'▼ ':''}{delta.toFixed(1)}pp vs {prev.m}
      </div>}
    </ChartTooltip>}
  </div>;
}

// ============================================================================
// 03 · DETALLE DE CASO
// ============================================================================
function CasoPage({id='P-0428', go, toast}) {
  const p = DATA.pacientes.find(x=>x.id===id) || DATA.pacientes[0];
  const [tab, setTab] = useState('resumen');
  const [dispOpen, setDispOpen] = useState(false);
  const [ctcOpen, setCtcOpen] = useState(false);
  const [filtroAct, setFiltroAct] = useState('todos');

  const tabs = [
    {key:'resumen',label:'Resumen'},
    {key:'clinico',label:'Clínico'},
    {key:'adherencia',label:'Adherencia'},
    {key:'journey',label:'Journey'},
    {key:'doc',label:'Documentación'},
    {key:'fact',label:'Facturación'},
    {key:'act',label:'Actividad'},
  ];

  return <div className="px-7 py-6 max-w-[1480px]">
    <button onClick={()=>go('casos')} className="flex items-center gap-1 text-[12px] text-ink-400 hover:text-ink-700 mb-3">
      <Icon.chevR c="w-3.5 h-3.5 rotate-180"/> Bandeja de casos
    </button>

    {/* HEADER (siempre visible) */}
    <div className="bg-white rounded-2xl border border-slate-100 p-5 mb-4 relative overflow-hidden" style={{boxShadow:'0 1px 2px rgba(15,23,42,0.04)'}}>
      <div className="absolute inset-0 bg-mesh opacity-70 pointer-events-none"/>
      <div className="relative flex items-start gap-4">
        <Avatar name={p.n} size="lg" tone={p.tone}/>
        <div className="flex-1 min-w-0">
          <div className="flex items-baseline gap-2 flex-wrap">
            <h1 className="text-[22px] font-display font-extrabold text-ink-800 leading-tight tracking-tight">{p.n}</h1>
            <span className="font-mono text-[11px] text-ink-400">{p.id}</span>
          </div>
          <div className="flex gap-2 text-[11.5px] text-ink-500 mt-1 font-mono flex-wrap">
            <span>DNI {p.dni}</span><span>·</span><span>{p.edad} años · {p.sexo}</span><span>·</span>
            <span>{p.dxDetalle}</span><span>·</span><span>{p.circuito} · {p.sede}</span><span>·</span>
            <span>{p.fin} · {p.plan}</span>
          </div>
          <div className="flex gap-2 mt-2.5 flex-wrap">
            <StatePill estado={p.estado}/>
            <RiskPill score={p.risk}/>
            <Badge tone="slate" size="sm"><ExtraIcons.calendar c="w-3 h-3"/> Próxima {p.proxima||'15/05 · Endocrinología'}</Badge>
            <Badge tone="helios" size="sm">Receta {p.receta} · vence {p.vencReceta}</Badge>
          </div>
        </div>
        <div className="flex gap-2 shrink-0">
          <Button variant="outline" size="sm" icon={<Icon.msg c="w-3.5 h-3.5"/>} onClick={()=>setCtcOpen(true)}>Contactar</Button>
          <Button variant="outline" size="sm" icon={<Icon.user c="w-3.5 h-3.5"/>}>Asignar</Button>
          <Button variant="primary" size="sm" icon={<ExtraIcons.pin c="w-3.5 h-3.5"/>} onClick={()=>setDispOpen(true)}>Registrar dispensa</Button>
        </div>
      </div>
      <div className="relative grid grid-cols-4 gap-3 mt-5">
        <HeaderKpi l="HbA1c actual"   v={p.hba1c+'%'}   sub={'Objetivo '+p.hba1cObj+'%'} tone={p.hba1c>p.hba1cObj?'danger':'ok'}/>
        <HeaderKpi l="Adherencia"     v={p.adh+'%'}     sub="Últimos 90 días" tone={p.adh<75?'warn':'ok'}/>
        <HeaderKpi l="Días sin dispensa" v={p.diasSinDisp+'d'} sub="Dulaglutida GLP-1" tone={p.diasSinDisp>14?'danger':'ok'}/>
        <HeaderKpi l="Score de riesgo" v={p.risk}       sub={p.risk>=80?'Crítico':p.risk>=60?'Alto':p.risk>=40?'Medio':'Bajo'} tone={p.risk>=80?'danger':p.risk>=60?'warn':'ok'}/>
      </div>
    </div>

    <div className="bg-white rounded-t-2xl border border-slate-100 border-b-0">
      <Tabs tabs={tabs} active={tab} onChange={setTab}/>
    </div>
    <div className="bg-white rounded-b-2xl border border-slate-100 p-5" style={{boxShadow:'0 1px 2px rgba(15,23,42,0.04)'}}>
      {tab==='resumen' && <TabResumen p={p} go={go}/>}
      {tab==='clinico' && <TabClinico p={p}/>}
      {tab==='adherencia' && <TabAdherencia p={p}/>}
      {tab==='journey' && <TabJourney p={p}/>}
      {tab==='doc' && <TabDoc p={p}/>}
      {tab==='fact' && <TabFact p={p}/>}
      {tab==='act' && <TabActividad p={p} filtro={filtroAct} setFiltro={setFiltroAct}/>}
    </div>

    <RegistrarDispensaModal open={dispOpen} onClose={()=>setDispOpen(false)} p={p} toast={toast}/>
    <ContactarModal open={ctcOpen} onClose={()=>setCtcOpen(false)} p={p} toast={toast}/>
  </div>;
}

function HeaderKpi({l, v, sub, tone}) {
  const fg = tone==='danger'?'text-[#B93535]':tone==='warn'?'text-[#D28513]':tone==='ok'?'text-[#1E8057]':'text-ink-800';
  return <div className="bg-white/80 rounded-xl border border-slate-100 px-3.5 py-2.5">
    <div className="text-[10px] font-mono uppercase tracking-wider text-ink-400 font-semibold">{l}</div>
    <div className={'font-display font-extrabold text-[22px] tabular-nums leading-none mt-1 '+fg}>{v}</div>
    <div className="text-[10.5px] text-ink-500 mt-1">{sub}</div>
  </div>;
}

// ---------- TAB: Resumen ----------
function TabResumen({p, go}) {
  const [execOpen, setExecOpen] = useState(false);
  return <div className="grid grid-cols-3 gap-4">
    <div className="col-span-2 space-y-4">
      <Section title="Estado del caso" sub="Fase actual y qué está haciendo el motor ahora">
        <div className="grid grid-cols-2 gap-3">
          <KV l="Fase actual" v={<StatePill estado={p.estado}/>}/>
          <KV l="Motivo" v={<span className="text-[12px]">Gap Dulaglutida &gt; 20 días</span>}/>
          <KV l="Workflow corriendo" v={
            <div className="flex items-center gap-2">
              <Badge tone="helios" size="sm" dot>WF-ADH · intento 2/3</Badge>
              <PlayExecButton onClick={()=>setExecOpen(true)}/>
            </div>
          }/>
          <KV l="Próxima acción" v={<span className="text-[12px]">{p.proxAccion}</span>}/>
        </div>
      </Section>
      <Section title="Datos del caso">
        <div className="grid grid-cols-2 gap-x-4 gap-y-2 text-[12px]">
          <KV l="Financiador · plan" v={p.fin+' · '+p.plan}/>
          <KV l="Circuito" v={p.circuito+' · '+p.sede}/>
          <KV l="Receta activa" v={<span className="font-mono text-[11.5px]">{p.receta}</span>}/>
          <KV l="Vencimiento receta" v={p.vencReceta}/>
          <KV l="Farmacia asignada" v={p.farmacia||'Helios Pharma Caballito'}/>
          <KV l="Teléfono · email" v={<span className="font-mono text-[11px]">{p.tel||'—'} · {p.email||'—'}</span>}/>
        </div>
      </Section>
      <Section title="Alertas activas" sub="3 alertas abiertas">
        <div className="space-y-2">
          <AlertRow tone="danger" tit="Gap Dulaglutida > 20 días" meta="Alta · detectada 21/04"/>
          <AlertRow tone="warn"   tit="HbA1c fuera de objetivo por 3 trimestres consecutivos" meta="Media · desde 10/2025"/>
          <AlertRow tone="sun"    tit="Autorización OSDE vence en 28 días" meta="Baja · renovar antes de 20/05"/>
        </div>
      </Section>
    </div>
    <div className="space-y-4">
      <Section title="Equipo asignado">
        {(p.equipo||DATA.pacientes[0].equipo).map(m => <div key={m.n} className="flex items-center gap-2.5 py-1.5">
          <Avatar name={m.n} size="sm" tone={m.t}/>
          <div className="min-w-0 flex-1">
            <div className="text-[12px] font-semibold text-ink-800 truncate">{m.n}</div>
            <div className="text-[10.5px] text-ink-400">{m.r}</div>
          </div>
          <button className="p-1.5 rounded-md hover:bg-slate-100 text-ink-500"><ExtraIcons.phone c="w-3.5 h-3.5"/></button>
          <button className="p-1.5 rounded-md hover:bg-slate-100 text-ink-500"><Icon.msg c="w-3.5 h-3.5"/></button>
        </div>)}
      </Section>
      <Section title="Próximos controles">
        {[
          {f:'15/05/2026',esp:'Endocrinología',mot:'Seguimiento DM2 · revisar ajuste Dulaglutida'},
          {f:'22/05/2026',esp:'Nutrición',mot:'Control mensual · plan alimentario'},
          {f:'12/06/2026',esp:'Oftalmología',mot:'Fondo de ojo anual'},
        ].map(c => <div key={c.f} className="py-2 border-b border-slate-100 last:border-0">
          <div className="flex items-center gap-2">
            <span className="font-mono text-[11px] font-semibold text-ink-700">{c.f}</span>
            <Badge tone="helios" size="sm">{c.esp}</Badge>
          </div>
          <div className="text-[11px] text-ink-500 mt-0.5">{c.mot}</div>
        </div>)}
      </Section>
    </div>
    <WorkflowExecModal open={execOpen} onClose={()=>setExecOpen(false)} p={p} go={go}/>
  </div>;
}

// ---------- TAB: Clínico ----------
function TabClinico({p}) {
  const hba1c = [{m:'oct/24',v:9.4},{m:'ene/25',v:9.0},{m:'abr/25',v:8.7},{m:'jul/25',v:8.8},{m:'oct/25',v:8.9},{m:'abr/26',v:p.hba1c}];
  return <div className="space-y-4">
    <div className="grid grid-cols-3 gap-4">
      <Section title="Evolución HbA1c" sub="Últimos 18 meses · objetivo 7.0%" className="col-span-2">
        <HbA1cChart data={hba1c} objetivo={p.hba1cObj}/>
      </Section>
      <Section title="Glucemia">
        <div className="space-y-2">
          <GlucRow l="Ayunas" v="164" u="mg/dL" tone="danger"/>
          <GlucRow l="Promedio" v="186" u="mg/dL" tone="warn"/>
          <GlucRow l="Postprandial" v="228" u="mg/dL" tone="danger"/>
        </div>
      </Section>
    </div>
    <div className="grid grid-cols-2 gap-4">
      <Section title="Parámetros físicos">
        <div className="grid grid-cols-3 gap-2 text-[12px]">
          <KV l="Peso" v="84.2 kg"/>
          <KV l="Altura" v="162 cm"/>
          <KV l="IMC" v="32.1"/>
          <KV l="TA" v="148/92"/>
          <KV l="Perím. abd." v="108 cm"/>
          <KV l="FC reposo" v="78"/>
        </div>
      </Section>
      <Section title="Comorbilidades">
        <div className="flex flex-wrap gap-1.5">
          <Badge tone="warn" size="sm">HTA</Badge>
          <Badge tone="warn" size="sm">Obesidad grado I</Badge>
          <Badge tone="sun" size="sm">Dislipidemia</Badge>
          <Badge tone="danger" size="sm">Nefropatía diabética G2</Badge>
        </div>
      </Section>
    </div>
    <Section title="Medicación activa" sub="5 fármacos · 1 con gap">
      <table className="w-full text-[12px]">
        <thead><tr className="text-[10px] font-mono uppercase tracking-wider text-ink-400 border-b border-slate-100">
          <th className="text-left py-2 font-semibold">Fármaco</th><th className="text-left font-semibold">Dosis</th><th className="text-left font-semibold">Frecuencia</th><th className="text-left font-semibold">Inicio</th><th className="text-right font-semibold">Estado</th>
        </tr></thead>
        <tbody>
          {[
            {m:'Metformina',d:'850 mg',f:'2×/día',i:'12/03/2016',s:'ok'},
            {m:'Empagliflozina',d:'25 mg',f:'1×/día',i:'08/09/2023',s:'ok'},
            {m:'Dulaglutida',d:'1.5 mg',f:'1×/semana',i:'15/01/2025',s:'danger'},
            {m:'Losartán',d:'50 mg',f:'1×/día',i:'20/06/2018',s:'ok'},
            {m:'Atorvastatina',d:'20 mg',f:'1×/noche',i:'20/06/2018',s:'ok'},
          ].map(m => <tr key={m.m} className="border-b border-slate-100 last:border-0">
            <td className="py-2 font-semibold text-ink-800">{m.m}</td>
            <td className="font-mono text-[11.5px] text-ink-700">{m.d}</td>
            <td className="text-ink-600">{m.f}</td>
            <td className="font-mono text-[11px] text-ink-500">{m.i}</td>
            <td className="text-right">{m.s==='ok'?<Badge tone="ok" size="sm">Al día</Badge>:<Badge tone="danger" size="sm" dot>Gap 22d</Badge>}</td>
          </tr>)}
        </tbody>
      </table>
    </Section>
  </div>;
}
function GlucRow({l,v,u,tone}) {
  const fg = tone==='danger'?'text-[#B93535]':tone==='warn'?'text-[#D28513]':'text-ink-800';
  return <div className="flex items-baseline justify-between py-1.5 border-b border-slate-100 last:border-0">
    <span className="text-[11.5px] text-ink-500">{l}</span>
    <span className={'font-mono font-bold text-[15px] tabular-nums '+fg}>{v} <span className="text-[10px] font-normal text-ink-400">{u}</span></span>
  </div>;
}

// ---------- TAB: Adherencia ----------
function TabAdherencia({p}) {
  const sem = Array.from({length:12},(_,i)=>({
    n:i+1,
    s: i<6?'ok': i<9?'gap': i===11?'pend':'gap'
  }));
  const motivos = [
    {l:'Efecto adverso GI', v:38, t:'danger'},
    {l:'Barrera logística', v:28, t:'sun'},
    {l:'Costo/cobertura', v:14, t:'warn'},
    {l:'Olvido', v:10, t:'helios'},
    {l:'Mejoría percibida', v:6, t:'teal2'},
    {l:'Otro', v:4, t:'slate'},
  ];
  const historial = [
    {f:'12:10',c:'WhatsApp',r:'Respondió · "me marea, lo dejé hace 3 semanas"',t:'ok'},
    {f:'21/04',c:'WhatsApp',r:'Sin respuesta',t:'danger'},
    {f:'22/04',c:'SMS',r:'Sin respuesta',t:'danger'},
    {f:'23/04',c:'Llamada',r:'No atendió',t:'warn'},
    {f:'24/04',c:'WhatsApp',r:'Respondió con efectos adversos',t:'ok'},
  ];
  return <div className="space-y-4">
    <div className="grid grid-cols-3 gap-4">
      <div className="col-span-1 bg-[#E04B4B]/5 ring-1 ring-[#E04B4B]/15 rounded-2xl p-5">
        <div className="text-[10.5px] font-mono uppercase tracking-wider text-[#B93535] font-semibold">Score de adherencia</div>
        <div className="font-display font-extrabold text-[56px] text-[#B93535] tabular-nums leading-none mt-1">{p.adh}%</div>
        <div className="text-[12px] text-ink-700 mt-2 font-semibold">Adherencia crítica</div>
        <div className="text-[11px] text-ink-500 mt-0.5">WF-ADH activado · 3 intentos registrados</div>
        <div className="mt-3 pt-3 border-t border-[#E04B4B]/15">
          <ProgressBar value={p.adh} tone="danger"/>
          <div className="flex justify-between text-[10px] font-mono text-ink-400 mt-1"><span>0%</span><span>Target ≥85%</span></div>
        </div>
      </div>
      <Section title="Línea de tiempo de dispensas" sub="12 semanas · Dulaglutida GLP-1" className="col-span-2">
        <div className="flex gap-1 mt-2">
          {sem.map(s => <div key={s.n} className="flex-1">
            <div className={'h-10 rounded-md '+(
              s.s==='ok'?'bg-[#2EA571]':s.s==='gap'?'bg-[#E04B4B]/70':'bg-slate-200 striped'
            )}/>
            <div className="text-[9px] font-mono text-ink-400 text-center mt-1">S{s.n}</div>
          </div>)}
        </div>
        <div className="flex gap-4 text-[11px] text-ink-500 mt-3">
          <span className="flex items-center gap-1.5"><span className="w-2.5 h-2.5 rounded-sm bg-[#2EA571]"/>Retirado</span>
          <span className="flex items-center gap-1.5"><span className="w-2.5 h-2.5 rounded-sm bg-[#E04B4B]/70"/>Gap</span>
          <span className="flex items-center gap-1.5"><span className="w-2.5 h-2.5 rounded-sm bg-slate-200 striped"/>Pendiente</span>
        </div>
      </Section>
    </div>
    <div className="grid grid-cols-2 gap-4">
      <Section title="Motivos detectados por IA" sub="Distribución acumulada · últimos 12 meses">
        <div className="space-y-2 mt-2">
          {motivos.map(m => <div key={m.l} className="flex items-center gap-3">
            <span className="text-[12px] text-ink-700 w-40 shrink-0">{m.l}</span>
            <div className="flex-1"><ProgressBar value={m.v} max={40} tone={m.t==='slate'?'helios':m.t}/></div>
            <span className="font-mono text-[11.5px] font-semibold text-ink-800 tabular-nums w-10 text-right">{m.v}%</span>
          </div>)}
        </div>
      </Section>
      <Section title="Historial de contactos" sub="Últimos intentos automáticos y humanos">
        <table className="w-full text-[11.5px]">
          <thead><tr className="text-[10px] font-mono uppercase text-ink-400 border-b border-slate-100"><th className="text-left py-1.5">Fecha</th><th className="text-left">Canal</th><th className="text-left">Resultado</th></tr></thead>
          <tbody>
          {historial.map((h,i)=><tr key={i} className="border-b border-slate-100 last:border-0">
            <td className="py-1.5 font-mono text-[10.5px] text-ink-500">{h.f}</td>
            <td><Badge tone="slate" size="sm">{h.c}</Badge></td>
            <td className={'text-[11.5px] '+(h.t==='danger'?'text-[#B93535]':h.t==='warn'?'text-[#D28513]':'text-ink-700')}>{h.r}</td>
          </tr>)}
          </tbody>
        </table>
      </Section>
    </div>
  </div>;
}

// ---------- TAB: Journey ----------
function TabJourney({p}) {
  const hitos = [
    {f:'12/03/2016',l:'Alta',d:'Ingreso al programa. DM2 + HTA.',dur:'—',ag:'sistema',done:true},
    {f:'12/03/2016',l:'Receta vigente',d:'Primera receta emitida por Dr. Hidalgo.',dur:'0 d',ag:'humano',done:true},
    {f:'08/04/2026',l:'Dispensa',d:'Retiro en Farmacity Caballito · 3 productos.',dur:'27 d',ag:'humano',done:true},
    {f:'21/04/2026',l:'Gap detectado',d:'Dulaglutida sin retirar hace 22 días.',dur:'13 d',ag:'sistema',done:true,highlight:true},
    {f:'21/04/2026',l:'WF-ADH iniciado',d:'Workflow automático arrancó a las 08:00.',dur:'0 d',ag:'sistema',done:true},
    {f:'21-25/04',  l:'Recontacto ×3',d:'WhatsApp → SMS → Llamada · respondió al 4to intento.',dur:'4 d',ag:'sistema',done:true},
    {f:'25/04/2026',l:'Escalado a humano',d:'Motivo clasificado como efecto adverso · derivado a Dra. Alemán.',dur:'0 d',ag:'sistema',done:true},
    {f:'26/04/2026',l:'En seguimiento',d:'Seguimiento clínico activo · reevaluación en 7 días.',dur:'actual',ag:'humano',done:false,active:true},
  ];
  return <div className="grid grid-cols-3 gap-4">
    <Section title="Timeline del caso" sub="Cada hito con fecha, duración y quién lo ejecutó" className="col-span-2">
      <div className="relative pl-8">
        <div className="absolute left-[14px] top-2 bottom-2 w-px bg-slate-200"/>
        {hitos.map((h,i) => <div key={i} className="relative mb-4 last:mb-0">
          <div className={'absolute -left-[22px] top-0 w-4 h-4 rounded-full ring-2 ring-white '+(h.active?'bg-[#E04B4B] animate-pulse':h.highlight?'bg-[#EEA028]':h.done?'bg-[#2EA571]':'bg-slate-300')}/>
          <div className="flex items-baseline gap-2 flex-wrap">
            <span className="font-mono text-[11px] font-semibold text-ink-700">{h.f}</span>
            <span className="text-[13px] font-semibold text-ink-800 font-display">{h.l}</span>
            <Badge tone={h.ag==='sistema'?'helios':'teal2'} size="sm">{h.ag==='sistema'?'Sistema':'Humano'}</Badge>
            {h.active && <Badge tone="danger" size="sm" dot>En curso</Badge>}
            <span className="text-[10.5px] font-mono text-ink-400 ml-auto">{h.dur}</span>
          </div>
          <p className="text-[11.5px] text-ink-500 mt-0.5">{h.d}</p>
        </div>)}
      </div>
    </Section>
    <Section title="Workflow activo · WF-ADH" sub="Estado en vivo">
      <div className="space-y-2">
        {[
          {l:'Trigger: gap detectado',done:true},
          {l:'Consulta HIS + CRM',done:true},
          {l:'Clasificador de riesgo IA',done:true},
          {l:'Envío WhatsApp personalizado',done:true},
          {l:'Fallback SMS + Llamada',done:true},
          {l:'Clasificación de motivo IA',done:true},
          {l:'Escalamiento a adherencia',done:true,active:true},
          {l:'Seguimiento clínico',done:false},
          {l:'Resolución o derivación',done:false},
        ].map((s,i)=><div key={i} className="flex items-center gap-2">
          <div className={'w-5 h-5 rounded-full flex items-center justify-center shrink-0 '+(s.done?'bg-[#2EA571]/15 text-[#1E8057]':s.active?'bg-[#E04B4B]/15 text-[#B93535]':'bg-slate-100 text-slate-400')}>
            {s.done?<Icon.check c="w-3 h-3"/>:s.active?<span className="w-1.5 h-1.5 rounded-full bg-[#E04B4B] animate-pulse"/>:<span className="w-1 h-1 rounded-full bg-slate-400"/>}
          </div>
          <span className={'text-[11.5px] '+(s.done?'text-ink-700':s.active?'text-[#B93535] font-semibold':'text-ink-400')}>{s.l}</span>
        </div>)}
      </div>
    </Section>
  </div>;
}

// ---------- TAB: Doc ----------
function TabDoc({p}) {
  const checklist = [
    {l:'Receta médica vigente',s:'ok'},
    {l:'Autorización OSDE',s:'ok'},
    {l:'DNI copia',s:'ok'},
    {l:'Consentimiento informado',s:'pend'},
    {l:'Remito firmado',s:'fail'},
  ];
  const done = checklist.filter(c=>c.s==='ok').length;
  return <div className="grid grid-cols-3 gap-4">
    <Section title="Checklist de documentación" sub={done+' de '+checklist.length+' completos · 60%'} className="col-span-1">
      <div className="space-y-2">
        {checklist.map((c,i) => <div key={i} className="flex items-center gap-2.5 py-1.5 border-b border-slate-100 last:border-0">
          <div className={'w-5 h-5 rounded-md flex items-center justify-center shrink-0 '+(c.s==='ok'?'bg-[#2EA571]/15 text-[#1E8057]':c.s==='pend'?'bg-[#EEA028]/15 text-[#D28513]':'bg-[#E04B4B]/15 text-[#B93535]')}>
            {c.s==='ok'?<Icon.check c="w-3 h-3"/>:c.s==='pend'?<Icon.clock c="w-3 h-3"/>:<ExtraIcons.x c="w-3 h-3"/>}
          </div>
          <span className={'text-[12px] flex-1 '+(c.s==='ok'?'text-ink-700':c.s==='pend'?'text-ink-700':'text-ink-700 font-semibold')}>{c.l}</span>
          {c.s!=='ok' && <button className="text-[11px] text-helios-700 hover:underline">Subir</button>}
        </div>)}
      </div>
    </Section>
    <Section title="Archivos adjuntos" sub="4 archivos · 2.3 MB" className="col-span-1">
      {[
        {n:'receta_R-2026-04281.pdf',t:'Receta',f:'05/04/2026'},
        {n:'autorizacion_OSDE_310.pdf',t:'Autorización',f:'05/04/2026'},
        {n:'DNI_MFernandez.jpg',t:'Identidad',f:'12/03/2016'},
        {n:'HbA1c_abr2026.pdf',t:'Laboratorio',f:'02/04/2026'},
      ].map(a => <div key={a.n} className="flex items-center gap-2.5 py-2 border-b border-slate-100 last:border-0">
        <div className="w-7 h-7 rounded-lg bg-helios-50 text-helios-700 flex items-center justify-center shrink-0"><Icon.doc c="w-3.5 h-3.5"/></div>
        <div className="min-w-0 flex-1">
          <div className="text-[11.5px] font-semibold text-ink-800 truncate font-mono">{a.n}</div>
          <div className="text-[10px] text-ink-400">{a.t} · {a.f}</div>
        </div>
        <button className="p-1.5 text-ink-500 hover:text-ink-800"><ExtraIcons.dl c="w-3.5 h-3.5"/></button>
      </div>)}
    </Section>
    <Section title="Validaciones automáticas" sub="WF-DOC · ejecutado hace 2h" className="col-span-1">
      {[
        {l:'Precio Dulaglutida vs padrón OSDE',s:'ok',v:'$18.400 · dentro del rango'},
        {l:'Bonificación 40% aplicada correctamente',s:'ok',v:'Match'},
        {l:'Cantidad coincide con receta',s:'ok',v:'4 unidades'},
        {l:'Autorización vigente',s:'ok',v:'Vence 20/05/2026'},
        {l:'Firma profesional válida',s:'ok',v:'M.P. 48291'},
      ].map((v,i)=><div key={i} className="flex items-start gap-2 py-1.5 border-b border-slate-100 last:border-0">
        <Icon.check c="w-3.5 h-3.5 text-[#1E8057] mt-0.5 shrink-0"/>
        <div className="min-w-0">
          <div className="text-[11.5px] text-ink-800 font-medium">{v.l}</div>
          <div className="text-[10.5px] font-mono text-ink-400">{v.v}</div>
        </div>
      </div>)}
    </Section>
  </div>;
}

// ---------- TAB: Fact ----------
function TabFact({p}) {
  return <div className="grid grid-cols-3 gap-4">
    <Section title="Estado en el pipeline" className="col-span-2">
      <div className="flex items-center gap-2 mb-4">
        {['Alta','Dispensa','Doc. completa','Legajo armado','Facturado'].map((s,i)=>{
          const at = i<=1;
          return <React.Fragment key={s}>
            <div className={'flex-1 rounded-lg px-2 py-2 text-center text-[11px] font-semibold '+(at?'bg-helios-50 text-helios-700 ring-1 ring-helios-200':'bg-slate-50 text-ink-400')}>{s}</div>
            {i<4 && <Icon.chevR c={'w-3 h-3 shrink-0 '+(at?'text-helios-400':'text-ink-300')}/>}
          </React.Fragment>;
        })}
      </div>
      <div className="grid grid-cols-2 gap-4">
        <KV l="Etapa actual" v="Dispensa registrada · pendiente doc."/>
        <KV l="Valor pendiente" v={<span className="font-mono font-bold text-[15px] text-ink-800">$284.900</span>}/>
        <KV l="Financiador · plan" v={p.fin+' · '+p.plan}/>
        <KV l="Período facturación" v="Abril 2026"/>
      </div>
    </Section>
    <Section title="Reglas económicas aplicadas">
      <div className="space-y-1.5 text-[11.5px]">
        <div className="flex justify-between py-1 border-b border-slate-100"><span className="text-ink-500">Dulaglutida 1.5mg × 4</span><span className="font-mono">$73.600</span></div>
        <div className="flex justify-between py-1 border-b border-slate-100"><span className="text-ink-500">Metformina 850mg × 2</span><span className="font-mono">$8.400</span></div>
        <div className="flex justify-between py-1 border-b border-slate-100"><span className="text-ink-500">Empagliflozina 25mg</span><span className="font-mono">$22.500</span></div>
        <div className="flex justify-between py-1 border-b border-slate-100"><span className="text-ink-500">Subtotal</span><span className="font-mono">$104.500</span></div>
        <div className="flex justify-between py-1 border-b border-slate-100"><span className="text-ink-500">Bonif. OSDE 310 (40%)</span><span className="font-mono text-[#B93535]">-$41.800</span></div>
        <div className="flex justify-between py-1.5 font-bold text-ink-800"><span>Facturable</span><span className="font-mono">$62.700</span></div>
      </div>
    </Section>
    <Section title="Historial de facturaciones" className="col-span-3">
      <table className="w-full text-[12px]">
        <thead><tr className="text-[10px] font-mono uppercase tracking-wider text-ink-400 border-b border-slate-100">
          <th className="text-left py-2">Período</th><th className="text-left">Monto</th><th className="text-left">Estado</th><th className="text-left">Fecha</th><th className="text-left">Nº factura</th>
        </tr></thead>
        <tbody>
          {[
            {p:'Marzo 2026',m:'$58.200',e:'Aprobado',f:'05/04/2026',n:'FA-0003-00028341'},
            {p:'Febrero 2026',m:'$54.800',e:'Aprobado',f:'08/03/2026',n:'FA-0003-00027998'},
            {p:'Enero 2026',m:'$56.100',e:'Aprobado',f:'06/02/2026',n:'FA-0003-00027650'},
            {p:'Diciembre 2025',m:'$52.300',e:'Aprobado',f:'09/01/2026',n:'FA-0003-00027310'},
          ].map(r=><tr key={r.n} className="border-b border-slate-100 last:border-0">
            <td className="py-2 font-semibold">{r.p}</td>
            <td className="font-mono">{r.m}</td>
            <td><Badge tone="ok" size="sm">{r.e}</Badge></td>
            <td className="font-mono text-[11px] text-ink-500">{r.f}</td>
            <td className="font-mono text-[11px] text-ink-500">{r.n}</td>
          </tr>)}
        </tbody>
      </table>
    </Section>
  </div>;
}

// ---------- TAB: Actividad ----------
function TabActividad({p, filtro, setFiltro}) {
  const eventos = [
    {t:'hoy 12:10',tipo:'Auto',ag:'WhatsApp API',desc:'Respuesta recibida: "me marea, lo dejé hace 3 semanas"'},
    {t:'hoy 12:10',tipo:'Auto',ag:'WF-ADH · IA',desc:'Motivo clasificado: efecto adverso GI (confianza 92%)'},
    {t:'hoy 12:10',tipo:'Auto',ag:'WF-ADH',desc:'Caso escalado a adherencia + alerta Dra. Alemán'},
    {t:'hoy 11:44',tipo:'Auto',ag:'WF-ADH',desc:'WhatsApp enviado · plantilla ADH-GLP1-01'},
    {t:'hoy 11:43',tipo:'Auto',ag:'WF-ADH · IA',desc:'Score 78 · Segmento: efecto adverso probable'},
    {t:'hoy 11:42',tipo:'Auto',ag:'WF-ADH',desc:'Gap detectado: 22 días sin retirar Dulaglutida'},
    {t:'ayer 16:05',tipo:'Humano',ag:'Dra. Alemán',desc:'Revisó alerta clínica · dejó nota'},
    {t:'ayer 14:30',tipo:'Humano',ag:'Camila Díaz',desc:'Intento de llamada — no atendió'},
    {t:'23/04 10:22',tipo:'Auto',ag:'WF-ADH',desc:'SMS enviado · sin respuesta en 24h'},
    {t:'22/04 09:00',tipo:'Auto',ag:'WF-ADH',desc:'Recordatorio WhatsApp #2'},
    {t:'21/04 08:00',tipo:'Auto',ag:'WF-ADH',desc:'Workflow iniciado por cron diario'},
    {t:'08/04 17:32',tipo:'Humano',ag:'Farmacity Caballito',desc:'Dispensa R-2026-04281 confirmada'},
    {t:'05/04 10:15',tipo:'Humano',ag:'Dr. Hidalgo',desc:'Emite receta R-2026-04281'},
    {t:'02/04 14:00',tipo:'Auto',ag:'Lab clínico',desc:'HbA1c 8.6% cargado en HIS'},
    {t:'28/03 09:00',tipo:'Humano',ag:'Lic. Ferrer',desc:'Consulta nutricional · plan ajustado'},
  ];
  const vis = filtro==='sistema'?eventos.filter(e=>e.tipo==='Auto'):filtro==='humano'?eventos.filter(e=>e.tipo==='Humano'):eventos;
  return <div>
    <div className="flex gap-1 mb-3">
      {[{k:'todos',l:'Todos'},{k:'sistema',l:'Solo sistema'},{k:'humano',l:'Solo humanos'}].map(f => <button key={f.k} onClick={()=>setFiltro(f.k)}
        className={'px-2.5 py-1 text-[11.5px] rounded-lg font-medium '+(filtro===f.k?'bg-helios-50 text-helios-700':'text-ink-500 hover:bg-slate-50')}>{f.l}</button>)}
    </div>
    <div className="space-y-0">
      {vis.map((e,i)=><div key={i} className="flex gap-3 py-2.5 border-b border-slate-100 last:border-0">
        <div className="w-24 shrink-0 text-[10.5px] font-mono text-ink-400 pt-0.5">{e.t}</div>
        <Badge tone={e.tipo==='Auto'?'helios':'teal2'} size="sm">{e.tipo}</Badge>
        <span className="text-[11.5px] font-semibold text-ink-700 w-36 shrink-0 truncate">{e.ag}</span>
        <div className="flex-1 text-[12px] text-ink-700 leading-snug">{e.desc}</div>
      </div>)}
    </div>
  </div>;
}

// ---------- Shared helpers ----------
function Section({title, sub, children, className=''}) {
  return <div className={className}>
    <div className="mb-2.5">
      <h3 className="text-[13px] font-display font-semibold text-ink-800">{title}</h3>
      {sub && <p className="text-[11px] text-ink-400 mt-0.5">{sub}</p>}
    </div>
    <div className="bg-slate-50/40 rounded-xl p-3 border border-slate-100">{children}</div>
  </div>;
}
function KV({l, v}) {
  return <div className="text-[12px]">
    <div className="text-[10px] font-mono uppercase tracking-wider text-ink-400">{l}</div>
    <div className="mt-0.5 text-ink-800">{v}</div>
  </div>;
}
function AlertRow({tone, tit, meta}) {
  return <div className="flex gap-2.5 p-2.5 bg-white rounded-lg border border-slate-100">
    <div className={'w-6 h-6 rounded-md flex items-center justify-center shrink-0 '+(
      tone==='danger'?'bg-[#E04B4B]/10 text-[#B93535]':tone==='warn'?'bg-[#EEA028]/10 text-[#D28513]':'bg-[#F5B84D]/10 text-[#D28513]'
    )}><Icon.alert c="w-3.5 h-3.5"/></div>
    <div className="min-w-0">
      <div className="text-[12px] font-semibold text-ink-800">{tit}</div>
      <div className="text-[10.5px] text-ink-400 mt-0.5">{meta}</div>
    </div>
  </div>;
}

// ---------- Modales ----------
function RegistrarDispensaModal({open, onClose, p, toast}) {
  return <Modal open={open} onClose={onClose} title="Registrar dispensa"
    subtitle={p.n+' · '+p.id}
    footer={<>
      <Button variant="outline" size="sm" onClick={onClose}>Cancelar</Button>
      <Button variant="primary" size="sm" onClick={()=>{toast('Dispensa registrada · remito generado','ok'); onClose();}}>Confirmar y generar remito</Button>
    </>}>
    <div className="space-y-3">
      <Field label="Fecha y hora"><Input type="datetime-local" defaultValue="2026-04-23T15:00"/></Field>
      <Field label="Medicamentos dispensados">
        <div className="space-y-1.5">
          {['Metformina 850mg × 60','Empagliflozina 25mg × 30','Dulaglutida 1.5mg × 4'].map(m => <label key={m} className="flex items-center gap-2 p-2 bg-slate-50 rounded-lg">
            <input type="checkbox" defaultChecked className="rounded"/><span className="text-[12px] flex-1">{m}</span>
          </label>)}
        </div>
      </Field>
      <div className="grid grid-cols-2 gap-3">
        <Field label="Quién retiró"><Select><option>Paciente</option><option>Familiar</option><option>Tutor</option></Select></Field>
        <Field label="Nombre si no es paciente"><Input placeholder="—"/></Field>
      </div>
      <Field label="Observaciones"><Textarea placeholder="Notas opcionales"/></Field>
    </div>
  </Modal>;
}
function ContactarModal({open, onClose, p, toast}) {
  const [clinico, setClinico] = useState(false);
  return <Modal open={open} onClose={onClose} title="Registrar contacto"
    subtitle={p.n+' · '+p.id}
    footer={<>
      <Button variant="outline" size="sm" onClick={onClose}>Cancelar</Button>
      <Button variant="primary" size="sm" onClick={()=>{toast('Contacto registrado','ok'); onClose();}}>Guardar</Button>
    </>}>
    <div className="space-y-3">
      <div className="grid grid-cols-2 gap-3">
        <Field label="Canal"><Select><option>WhatsApp</option><option>SMS</option><option>Llamada</option></Select></Field>
        <Field label="Resultado"><Select onChange={e=>setClinico(e.target.value.includes('clínico'))}><option>Respondió positivo</option><option>Respondió negativo</option><option>Sin respuesta</option><option>Número incorrecto</option></Select></Field>
      </div>
      <Field label="Motivo detectado"><Select onChange={e=>setClinico(e.target.value==='Efecto adverso' || e.target.value==='Complicación clínica')}>
        <option>Efecto adverso</option><option>Barrera logística</option><option>Costo/cobertura</option><option>Olvido</option><option>Mejoría percibida</option><option>Complicación clínica</option><option>Otro</option>
      </Select></Field>
      <Field label="Notas"><Textarea placeholder="Detalles de la conversación"/></Field>
      <Field label="Próxima acción"><Input placeholder="Ej: reagendar dispensa para el 28/04"/></Field>
      {clinico && <label className="flex items-center gap-2 p-2.5 rounded-lg bg-[#E04B4B]/5 ring-1 ring-[#E04B4B]/15">
        <input type="checkbox" required className="rounded"/>
        <span className="text-[11.5px] text-[#B93535] font-medium">Notificar al equipo médico (obligatorio para motivo clínico)</span>
      </label>}
    </div>
  </Modal>;
}

window.CasoPage = CasoPage;

// ---------- Workflow exec button + modal ----------
function PlayExecButton({onClick}) {
  const [hover, setHover] = useState(false);
  return <span className="relative inline-flex">
    <button
      onClick={onClick}
      onMouseEnter={()=>setHover(true)}
      onMouseLeave={()=>setHover(false)}
      className="w-[22px] h-[22px] inline-flex items-center justify-center rounded-full bg-helios-500 text-white hover:bg-helios-600 active:scale-95 transition shadow-sm ring-1 ring-helios-600/20"
      aria-label="Ver ejecución del workflow"
    >
      <Icon.play c="w-3 h-3"/>
    </button>
    {hover && <span className="absolute left-1/2 -translate-x-1/2 -top-7 px-2 py-1 rounded-md bg-ink-900 text-white text-[10.5px] font-medium whitespace-nowrap shadow-md z-10 pointer-events-none">
      Ver ejecución
      <span className="absolute left-1/2 -translate-x-1/2 top-full w-0 h-0 border-l-[4px] border-r-[4px] border-t-[4px] border-l-transparent border-r-transparent border-t-ink-900"/>
    </span>}
  </span>;
}

// Compact live execution diagram for the running workflow
function WorkflowExecModal({open, onClose, p, go}) {
  // Steps of WF-ADH (Adherencia) — concrete execution trace for this case
  const steps = [
    {id:'trg', lbl:'Trigger · Gap >20d',       state:'done',   t:'−3d 14:20', note:'Detectado por monitor · intento 1 abierto'},
    {id:'ev',  lbl:'Evaluar riesgo + canal',   state:'done',   t:'−3d 14:20', note:'Riesgo alto → WhatsApp prioridad 1'},
    {id:'wa',  lbl:'WhatsApp recordatorio',    state:'done',   t:'−3d 14:21', note:'Entregado · leído −3d 18:04'},
    {id:'w1',  lbl:'Esperar respuesta 48h',    state:'done',   t:'−1d 14:21', note:'Sin respuesta → escala a intento 2'},
    {id:'sms', lbl:'SMS + llamada operador',   state:'running',t:'hoy 09:10', note:'Llamada en cola · operador: M. Ramírez'},
    {id:'w2',  lbl:'Esperar 24h',              state:'pending',t:'—',         note:'Si no responde → derivar a médico tratante'},
    {id:'esc', lbl:'Escalar a médico',         state:'pending',t:'—',         note:'Crea tarea clínica + alerta en bandeja'},
  ];
  const done = steps.filter(s=>s.state==='done').length;
  const running = steps.findIndex(s=>s.state==='running');
  return <Modal open={open} onClose={onClose}
    title="Ejecución · WF-ADH"
    subtitle={<span>Adherencia — {p.n} · {p.id} <span className="text-ink-400">·</span> intento <span className="font-mono font-semibold text-ink-700">2/3</span></span>}
    width="w-[680px]"
    footer={<>
      <Button variant="outline" size="sm" onClick={onClose}>Cerrar</Button>
      <Button variant="outline" size="sm"><svg viewBox="0 0 24 24" className="w-3.5 h-3.5" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round"><rect x="6" y="4" width="4" height="16" rx="1"/><rect x="14" y="4" width="4" height="16" rx="1"/></svg>Pausar intento</Button>
      <Button variant="primary" size="sm" onClick={()=>{ onClose(); go && go('workflow', 'WF-ADH'); }}><Icon.eye c="w-3.5 h-3.5"/>Abrir en Workflows</Button>
    </>}>
    <div className="space-y-4">
      {/* Header stats */}
      <div className="grid grid-cols-4 gap-2">
        <ExecStat l="Estado" v={<span className="inline-flex items-center gap-1.5"><span className="w-1.5 h-1.5 rounded-full bg-helios-500 animate-pulse"/><span className="text-[11.5px] font-semibold text-helios-700">Corriendo</span></span>}/>
        <ExecStat l="Progreso" v={<span className="font-mono text-[12px] font-semibold text-ink-800">{done}/{steps.length}</span>}/>
        <ExecStat l="Iniciado" v={<span className="font-mono text-[11px] text-ink-700">hace 3d</span>}/>
        <ExecStat l="SLA" v={<span className="font-mono text-[11px] text-ink-700">48h · 12h rest.</span>}/>
      </div>

      {/* Vertical step list */}
      <div className="rounded-xl ring-1 ring-slate-200 bg-white overflow-hidden">
        <div className="px-3 py-2 border-b border-slate-100 flex items-center justify-between">
          <div className="text-[11px] font-semibold text-ink-700 uppercase tracking-wide">Trazado de ejecución</div>
          <div className="text-[10.5px] text-ink-500">Live · actualizado hace 4s</div>
        </div>
        <div className="p-3">
          {steps.map((s, i) => <ExecStep key={s.id} s={s} last={i===steps.length-1} isRunning={i===running}/>)}
        </div>
      </div>

      {/* Context */}
      <div className="grid grid-cols-2 gap-2 text-[11.5px]">
        <div className="rounded-lg bg-slate-50 ring-1 ring-slate-200/60 p-2.5">
          <div className="text-[10px] uppercase tracking-wide text-ink-500 font-semibold mb-1">Disparador</div>
          <div className="text-ink-800">Gap Dulaglutida &gt; 20 días</div>
          <div className="text-ink-500 text-[11px] mt-0.5">Última dispensa 02/04 · esperada 22/04</div>
        </div>
        <div className="rounded-lg bg-slate-50 ring-1 ring-slate-200/60 p-2.5">
          <div className="text-[10px] uppercase tracking-wide text-ink-500 font-semibold mb-1">Política aplicada</div>
          <div className="text-ink-800">Adherencia · Riesgo alto</div>
          <div className="text-ink-500 text-[11px] mt-0.5">3 intentos · escala a médico si falla</div>
        </div>
      </div>
    </div>
  </Modal>;
}

function ExecStat({l, v}) {
  return <div className="rounded-lg bg-slate-50 ring-1 ring-slate-200/60 px-2.5 py-1.5">
    <div className="text-[9.5px] uppercase tracking-wide text-ink-500 font-semibold">{l}</div>
    <div className="mt-0.5">{v}</div>
  </div>;
}

function ExecStep({s, last, isRunning}) {
  const tone = s.state==='done' ? 'ok' : s.state==='running' ? 'run' : 'pending';
  const dot = {
    ok:      {bg:'bg-[#2F8F6B]', ring:'ring-[#2F8F6B]/20', ic:<svg viewBox="0 0 24 24" className="w-3 h-3 text-white" fill="none" stroke="currentColor" strokeWidth="3" strokeLinecap="round" strokeLinejoin="round"><polyline points="20 6 9 17 4 12"/></svg>},
    run:     {bg:'bg-helios-500', ring:'ring-helios-500/25', ic:<span className="w-1.5 h-1.5 rounded-full bg-white animate-pulse"/>},
    pending: {bg:'bg-white ring-1 ring-slate-300', ring:'', ic:<span className="w-1 h-1 rounded-full bg-slate-300"/>},
  }[tone];
  return <div className="flex gap-3 relative">
    <div className="flex flex-col items-center" style={{width:20}}>
      <span className={`w-5 h-5 rounded-full flex items-center justify-center ${dot.bg} ${dot.ring ? 'ring-2 '+dot.ring : ''} ${isRunning?'shadow-[0_0_0_4px_rgba(240,155,85,0.15)]':''}`}>{dot.ic}</span>
      {!last && <span className={`w-px flex-1 mt-0.5 mb-0.5 ${s.state==='done'?'bg-[#2F8F6B]/40':'bg-slate-200'}`} style={{minHeight:22}}/>}
    </div>
    <div className={`flex-1 pb-3 ${last?'pb-0':''}`}>
      <div className="flex items-center gap-2">
        <span className={`text-[12.5px] font-semibold ${s.state==='pending'?'text-ink-400':'text-ink-800'}`}>{s.lbl}</span>
        {s.state==='running' && <Badge tone="helios" size="sm" dot>en curso</Badge>}
        <span className="ml-auto font-mono text-[10.5px] text-ink-500">{s.t}</span>
      </div>
      <div className={`text-[11px] mt-0.5 ${s.state==='pending'?'text-ink-400':'text-ink-500'}`}>{s.note}</div>
    </div>
  </div>;
}
