/* Animated Process Map — shows how we automate a real flow */

const FLOWS = {
  facturas: {
    name: 'Facturación proveedores',
    nodes: [
      { id: 'in',    x: 40,  y: 160, w: 130, h: 70, label: 'Email / PDF', meta: 'input', type: 'io' },
      { id: 'ocr',   x: 220, y: 60,  w: 140, h: 70, label: 'OCR + Extract', meta: 'agente IA', type: 'ia' },
      { id: 'val',   x: 220, y: 260, w: 140, h: 70, label: 'Validación', meta: 'reglas + IA', type: 'ia' },
      { id: 'erp',   x: 410, y: 160, w: 140, h: 70, label: 'ERP · Sage', meta: 'sync', type: 'sys' },
      { id: 'aprob', x: 600, y: 60,  w: 130, h: 70, label: 'Aprobación', meta: 'slack bot', type: 'ia' },
      { id: 'pay',   x: 600, y: 260, w: 130, h: 70, label: 'Pago SEPA', meta: 'BBVA API', type: 'sys' },
      { id: 'arc',   x: 780, y: 160, w: 130, h: 70, label: 'Archivo', meta: 'S3 + índice', type: 'io' },
    ],
    edges: [
      { from: 'in',   to: 'ocr' },
      { from: 'in',   to: 'val' },
      { from: 'ocr',  to: 'erp' },
      { from: 'val',  to: 'erp' },
      { from: 'erp',  to: 'aprob' },
      { from: 'erp',  to: 'pay' },
      { from: 'aprob', to: 'arc' },
      { from: 'pay',  to: 'arc' },
    ],
    detail: {
      before: { title: 'Antes', time: '4h / factura', volume: '180 facturas/mes', cost: '86h/mes' },
      after:  { title: 'Después', time: '38s / factura', volume: '180+ sin aumentar headcount', cost: '1.9h/mes supervisión' }
    }
  },
  soporte: {
    name: 'Soporte L1',
    nodes: [
      { id: 'web',   x: 40,  y: 60,  w: 130, h: 70, label: 'Web chat', meta: 'input', type: 'io' },
      { id: 'mail',  x: 40,  y: 160, w: 130, h: 70, label: 'Email', meta: 'input', type: 'io' },
      { id: 'wha',   x: 40,  y: 260, w: 130, h: 70, label: 'WhatsApp', meta: 'input', type: 'io' },
      { id: 'tri',   x: 220, y: 160, w: 140, h: 70, label: 'Triaje IA', meta: 'clasifica', type: 'ia' },
      { id: 'rag',   x: 410, y: 60,  w: 140, h: 70, label: 'Agente RAG', meta: 'KB propietaria', type: 'ia' },
      { id: 'crm',   x: 410, y: 260, w: 140, h: 70, label: 'CRM · HubSpot', meta: 'ticket', type: 'sys' },
      { id: 'esc',   x: 600, y: 160, w: 140, h: 70, label: 'Escalado L2', meta: 'humano', type: 'sys' },
      { id: 'out',   x: 790, y: 160, w: 130, h: 70, label: 'Respuesta', meta: 'multi-canal', type: 'io' },
    ],
    edges: [
      { from: 'web',  to: 'tri' },
      { from: 'mail', to: 'tri' },
      { from: 'wha',  to: 'tri' },
      { from: 'tri',  to: 'rag' },
      { from: 'tri',  to: 'crm' },
      { from: 'rag',  to: 'out' },
      { from: 'rag',  to: 'esc' },
      { from: 'crm',  to: 'esc' },
      { from: 'esc',  to: 'out' },
    ],
    detail: {
      before: { title: 'Antes', time: '18min / ticket', volume: '420 tickets/mes', cost: '4 FTE' },
      after:  { title: 'Después', time: '1.4min · auto 72%', volume: '420 tickets/mes', cost: '1 FTE + supervisión' }
    }
  },
  onboarding: {
    name: 'Onboarding cliente',
    nodes: [
      { id: 'sig',   x: 40,  y: 160, w: 130, h: 70, label: 'Firma contrato', meta: 'DocuSign', type: 'io' },
      { id: 'spl',   x: 220, y: 160, w: 140, h: 70, label: 'Orquestador', meta: 'event bus', type: 'ia' },
      { id: 'crm',   x: 410, y: 40,  w: 130, h: 70, label: 'CRM setup', meta: 'HubSpot', type: 'sys' },
      { id: 'erp',   x: 410, y: 135, w: 130, h: 70, label: 'ERP cuenta', meta: 'crear', type: 'sys' },
      { id: 'acc',   x: 410, y: 230, w: 130, h: 70, label: 'Accesos', meta: 'Okta SSO', type: 'sys' },
      { id: 'wel',   x: 410, y: 325, w: 130, h: 70, label: 'Welcome pack', meta: 'IA personalizado', type: 'ia' },
      { id: 'not',   x: 600, y: 160, w: 140, h: 70, label: 'Notificación', meta: 'equipo + cliente', type: 'sys' },
      { id: 'kic',   x: 790, y: 160, w: 130, h: 70, label: 'Kickoff', meta: 'agenda auto', type: 'io' },
    ],
    edges: [
      { from: 'sig', to: 'spl' },
      { from: 'spl', to: 'crm' },
      { from: 'spl', to: 'erp' },
      { from: 'spl', to: 'acc' },
      { from: 'spl', to: 'wel' },
      { from: 'crm', to: 'not' },
      { from: 'erp', to: 'not' },
      { from: 'acc', to: 'not' },
      { from: 'wel', to: 'not' },
      { from: 'not', to: 'kic' },
    ],
    detail: {
      before: { title: 'Antes', time: '3–5 días', volume: '—', cost: '6h humanas/cliente' },
      after:  { title: 'Después', time: '12 min', volume: 'sin límite', cost: '15min supervisión' }
    }
  }
};

function buildPath(from, to) {
  const fx = from.x + from.w, fy = from.y + from.h / 2;
  const tx = to.x,           ty = to.y + to.h / 2;
  const mx = (fx + tx) / 2;
  return `M ${fx} ${fy} C ${mx} ${fy}, ${mx} ${ty}, ${tx} ${ty}`;
}

function ProcessMap() {
  const [flowKey, setFlowKey] = React.useState('facturas');
  const [active, setActive] = React.useState(null);
  const [tick, setTick] = React.useState(0);
  const flow = FLOWS[flowKey];

  // cycle through nodes automatically
  React.useEffect(() => {
    const i = setInterval(() => setTick(t => t + 1), 1600);
    return () => clearInterval(i);
  }, []);

  React.useEffect(() => {
    if (active) return;
    const n = flow.nodes[tick % flow.nodes.length];
    const el = document.querySelector(`[data-pmnode="${n.id}"]`);
    if (el) {
      el.classList.add('fired');
      setTimeout(() => el.classList.remove('fired'), 1200);
    }
  }, [tick, flow, active]);

  const activeNode = active ? flow.nodes.find(n => n.id === active) : null;
  const activeDetails = {
    in:    { stage: 'INPUT · Captura multi-canal', title: 'Entrada unificada', desc: 'Capturamos cualquier input (email, WhatsApp, API, webhooks, uploads). Todo pasa por un bus de eventos normalizado.' },
    ocr:   { stage: 'IA · Extracción estructurada', title: 'OCR + comprensión', desc: 'Agente multimodal que extrae campos clave, detecta anomalías y normaliza moneda/IVA. Fallback a revisión humana en <1% de casos.' },
    val:   { stage: 'IA · Reglas de negocio', title: 'Validación', desc: 'Reglas deterministas + razonamiento IA para detectar duplicados, facturas alteradas o fuera de contrato marco.' },
    erp:   { stage: 'SYS · Integración nativa', title: 'ERP sync', desc: 'Sincronización idempotente con tu ERP (Sage, SAP, Business Central, Odoo…). Retry con backoff y dead-letter queue.' },
    aprob: { stage: 'IA · Slack bot', title: 'Aprobación conversacional', desc: 'Bot en Slack/Teams que solicita aprobación al responsable correcto según delegación. Escalado automático si no hay respuesta.' },
    pay:   { stage: 'SYS · Banca abierta', title: 'Pago SEPA', desc: 'Integración con tu banco vía PSD2. Generación de remesas, firmas digitales y confirmación de ejecución.' },
    arc:   { stage: 'IO · Archivo indexado', title: 'Archivo', desc: 'Almacenamiento cifrado con índice full-text, retención configurable y auditoría completa para Hacienda.' },
    web: { stage: 'INPUT · Web', title: 'Chat web', desc: 'Widget embebido con contexto de sesión y persistencia.' },
    mail: { stage: 'INPUT · Email', title: 'Email parsing', desc: 'Procesamiento de emails con threading y detección de intención.' },
    wha: { stage: 'INPUT · WhatsApp', title: 'WhatsApp Business', desc: 'API oficial con plantillas y conversación bidireccional.' },
    tri: { stage: 'IA · Router', title: 'Triaje automático', desc: 'Clasificador fine-tuned que enruta por urgencia, categoría y segmento de cliente.' },
    rag: { stage: 'IA · Retrieval', title: 'Agente RAG', desc: 'Base de conocimiento vectorial propietaria. Cita fuentes. Confianza calibrada.' },
    crm: { stage: 'SYS · CRM', title: 'Ticket en HubSpot', desc: 'Crea/actualiza el ticket en tu CRM con todo el contexto.' },
    esc: { stage: 'SYS · Humano', title: 'Escalado L2', desc: 'Handoff suave a agente humano con contexto completo.' },
    out: { stage: 'IO · Multi-canal', title: 'Respuesta', desc: 'Responde por el mismo canal de entrada con tono consistente.' },
    sig: { stage: 'IO · Firma', title: 'Contrato firmado', desc: 'Trigger desde DocuSign/HelloSign vía webhook.' },
    spl: { stage: 'IA · Orquestación', title: 'Event splitter', desc: 'Dispara todos los subsistemas en paralelo.' },
    acc: { stage: 'SYS · Identidad', title: 'Provisioning de accesos', desc: 'SCIM + SSO. Grupos por rol. Baja automática al offboarding.' },
    wel: { stage: 'IA · Personalización', title: 'Welcome pack', desc: 'Documentación personalizada por vertical y tamaño del cliente.' },
    not: { stage: 'SYS · Notificación', title: 'Notificaciones cruzadas', desc: 'Slack interno + email al cliente + calendario.' },
    kic: { stage: 'IO · Kickoff', title: 'Kickoff programado', desc: 'Agenda la reunión inicial con los stakeholders correctos.' },
  }[active];

  return (
    <section className="section" id="mapa">
      <div className="section-inner">
        <span className="section-label reveal"><span className="num">§ 03</span>SISTEMA / PROCESS MAP</span>
        <div className="section-head">
          <h2 className="section-title reveal reveal-delay-1">
            Cómo automatizamos<br/>
            un flujo <em>real.</em>
          </h2>
          <p className="section-lede reveal reveal-delay-2">
            Explora tres flujos que hemos desplegado en producción. Haz clic en cada nodo para ver qué hace exactamente. Los <span style={{color:'var(--accent)'}}>pulsos de luz</span> simulan eventos en tiempo real.
          </p>
        </div>

        <div className="processmap-panel reveal">
          <div className="pm-toolbar">
            <span className="title">Process · {flow.name}</span>
            <div className="controls">
              {Object.entries(FLOWS).map(([k, v]) => (
                <button key={k} className={flowKey === k ? 'active' : ''} onClick={() => { setFlowKey(k); setActive(null); }}>
                  {v.name}
                </button>
              ))}
            </div>
          </div>

          <div className="pm-stage">
            <svg viewBox="0 0 940 400" preserveAspectRatio="xMidYMid meet">
              <defs>
                <marker id="arrow" viewBox="0 0 8 8" refX="7" refY="4" markerWidth="6" markerHeight="6" orient="auto">
                  <path d="M 0 0 L 8 4 L 0 8 z" fill="var(--line-strong)"/>
                </marker>
                <marker id="arrow-active" viewBox="0 0 8 8" refX="7" refY="4" markerWidth="6" markerHeight="6" orient="auto">
                  <path d="M 0 0 L 8 4 L 0 8 z" fill="var(--accent)"/>
                </marker>
              </defs>
              {flow.edges.map((e, i) => {
                const from = flow.nodes.find(n => n.id === e.from);
                const to = flow.nodes.find(n => n.id === e.to);
                const isActive = active && (e.from === active || e.to === active);
                return (
                  <g key={i}>
                    <path d={buildPath(from, to)} className={'pm-edge' + (isActive ? ' active' : '')} markerEnd={isActive ? 'url(#arrow-active)' : 'url(#arrow)'} />
                    <circle r="3" className="pm-packet" style={{ animation: `packet-${i} ${4 + (i%3)}s linear infinite`, offsetPath: `path('${buildPath(from, to)}')`, offsetDistance: '0%' }}>
                      <animateMotion dur={`${5 + (i % 4)}s`} repeatCount="indefinite" path={buildPath(from, to)} />
                    </circle>
                  </g>
                );
              })}
              {flow.nodes.map(n => {
                const isActive = active === n.id;
                return (
                  <g key={n.id} className={'pm-node' + (isActive ? ' active' : '')} data-pmnode={n.id}
                     onClick={() => setActive(active === n.id ? null : n.id)}
                     transform={`translate(${n.x}, ${n.y})`}>
                    <rect width={n.w} height={n.h} rx="1" />
                    <text x="12" y="22" className="label">{n.label}</text>
                    <text x="12" y="42" className="meta">{n.meta}</text>
                    <circle cx={n.w - 14} cy={16} r="3" className="icon"
                            fill={n.type === 'ia' ? 'var(--accent)' : n.type === 'sys' ? 'var(--gold)' : 'var(--ink-3)'} />
                    <text x={n.w - 10} y={n.h - 10} className="meta" textAnchor="end" style={{opacity:0.6}}>{n.type.toUpperCase()}</text>
                  </g>
                );
              })}
            </svg>
          </div>

          <div className="pm-legend">
            <div className="item"><span className="sw ia"></span>AGENTE IA</div>
            <div className="item"><span className="sw ok"></span>EJECUCIÓN EN VIVO</div>
            <div className="item"><span className="sw sys" style={{background:'var(--gold)', boxShadow:'0 0 6px var(--gold)'}}></span>SISTEMA / INTEGRACIÓN</div>
            <div className="item" style={{marginLeft:'auto'}}>{flow.nodes.length} NODOS · {flow.edges.length} ARISTAS</div>
          </div>

          {activeDetails ? (
            <div className="pm-detail">
              <div className="stage">{activeDetails.stage}</div>
              <h4>{activeDetails.title}</h4>
              <p>{activeDetails.desc}</p>
              <div className="stats">
                <div><span className="k">Tipo</span><span className="v">{activeNode?.type?.toUpperCase()}</span></div>
                <div><span className="k">Observable</span><span className="v">Sí · logs + métricas</span></div>
                <div><span className="k">Fallback</span><span className="v">Humano en loop</span></div>
              </div>
            </div>
          ) : (
            <div className="pm-detail">
              <div className="stage">BEFORE / AFTER — {flow.name}</div>
              <div className="stats" style={{marginTop: 8}}>
                <div><span className="k">{flow.detail.before.title}</span><span className="v" style={{color:'var(--signal)'}}>{flow.detail.before.time}</span></div>
                <div><span className="k">{flow.detail.after.title}</span><span className="v">{flow.detail.after.time}</span></div>
                <div><span className="k">Volumen</span><span className="v">{flow.detail.after.volume}</span></div>
                <div><span className="k">Coste humano</span><span className="v">{flow.detail.after.cost}</span></div>
              </div>
              <p style={{marginTop:12, color:'var(--ink-3)', fontSize:13}}>Haz clic en cualquier nodo para ver qué hace exactamente.</p>
            </div>
          )}
        </div>
      </div>
    </section>
  );
}

Object.assign(window, { ProcessMap });
