// ROARK v4 — Mini-demos del Ecosistema (Buca 2026-06-28)
// Visuales que DEMUESTRAN el producto dentro del eco__panel en vez de solo
// describirlo. Se montan al cambiar de tab (eco__panel usa key={active}, así
// que el useEffect corre fresco en cada selección). Self-contained: sin GSAP,
// requestAnimationFrame puro y respeto a prefers-reduced-motion.

(function () {
  const { useState, useEffect, useRef } = React;

  const REDUCED = typeof window !== 'undefined' && window.matchMedia &&
    window.matchMedia('(prefers-reduced-motion: reduce)').matches;

  // PERF: solo monta/anima el demo cuando la sección del ecosistema está a la
  // vista. Off-screen no renderiza nada (el usuario no lo ve) → cero costo idle
  // de las animaciones infinitas (waveform, pulsos, spinner) en el resto del page.
  function useInView(margin) {
    const ref = useRef(null);
    const [inView, setInView] = useState(false);
    useEffect(() => {
      const el = ref.current;
      if (!el || !('IntersectionObserver' in window)) { setInView(true); return; }
      const io = new IntersectionObserver((entries) => {
        setInView(entries[0].isIntersecting);
      }, { rootMargin: margin || '160px' });
      io.observe(el);
      return () => io.disconnect();
    }, []);
    return [ref, inView];
  }

  // Count-up de 0 → target con ease-out. Devuelve el valor mostrado.
  function useCountUp(target, opts) {
    opts = opts || {};
    const dur = opts.dur || 1100;
    const decimals = opts.decimals || 0;
    const [val, setVal] = useState(REDUCED ? target : 0);
    useEffect(() => {
      if (REDUCED) { setVal(target); return; }
      let raf, start = null;
      const tick = (t) => {
        if (start === null) start = t;
        const p = Math.min(1, (t - start) / dur);
        const eased = 1 - Math.pow(1 - p, 3); // easeOutCubic
        setVal(target * eased);
        if (p < 1) raf = requestAnimationFrame(tick);
        else setVal(target);
      };
      raf = requestAnimationFrame(tick);
      return () => cancelAnimationFrame(raf);
    }, [target]);
    return decimals ? val.toFixed(decimals) : Math.round(val).toLocaleString('es-MX');
  }

  function Ticker({ value, prefix, suffix, decimals, dur }) {
    const shown = useCountUp(value, { decimals: decimals, dur: dur });
    return <span>{prefix || ''}{shown}{suffix || ''}</span>;
  }

  // ---------- E·01 DASHBOARD: KPIs + sparkline que se dibuja ----------
  function DashboardDemo() {
    const pathRef = useRef(null);
    useEffect(() => {
      const el = pathRef.current;
      if (!el) return;
      const len = el.getTotalLength();
      el.style.strokeDasharray = len;
      if (REDUCED) { el.style.strokeDashoffset = 0; return; }
      el.style.strokeDashoffset = len;
      let raf, start = null;
      const dur = 1400;
      const tick = (t) => {
        if (start === null) start = t;
        const p = Math.min(1, (t - start) / dur);
        const eased = 1 - Math.pow(1 - p, 3);
        el.style.strokeDashoffset = len * (1 - eased);
        if (p < 1) raf = requestAnimationFrame(tick);
      };
      raf = requestAnimationFrame(tick);
      return () => cancelAnimationFrame(raf);
    }, []);

    // 7 puntos normalizados (0–100 → coords del viewBox 240x70)
    const pts = [62, 48, 55, 34, 40, 22, 12];
    const d = pts.map((y, i) => `${i === 0 ? 'M' : 'L'} ${i * 38 + 6} ${y}`).join(' ');

    return (
      <div className="eco-demo eco-demo--dash" aria-hidden="true">
        <div className="ed-kpis">
          <div className="ed-kpi">
            <span className="ed-kpi__k">Casos activos</span>
            <span className="ed-kpi__v"><Ticker value={1284} /></span>
            <span className="ed-kpi__d ed-up">▲ 12%</span>
          </div>
          <div className="ed-kpi">
            <span className="ed-kpi__k">Horas ahorradas</span>
            <span className="ed-kpi__v"><Ticker value={326} suffix=" h" /></span>
            <span className="ed-kpi__d ed-up">▲ 8%</span>
          </div>
          <div className="ed-kpi">
            <span className="ed-kpi__k">Respuesta prom.</span>
            <span className="ed-kpi__v"><Ticker value={1.4} decimals={1} suffix=" min" dur={900} /></span>
            <span className="ed-kpi__d ed-down">▼ 34%</span>
          </div>
        </div>
        <div className="ed-chart">
          <div className="ed-chart__head">
            <span>Carga operativa · 7 días</span>
            <span className="ed-live"><i />EN VIVO</span>
          </div>
          <svg viewBox="0 0 240 70" preserveAspectRatio="none">
            <path ref={pathRef} className="ed-spark" d={d} fill="none" />
          </svg>
        </div>
      </div>
    );
  }

  // ---------- E·02 WHATSAPP: chat con typing → respuesta ----------
  function WhatsappDemo() {
    const [stage, setStage] = useState(REDUCED ? 3 : 0);
    useEffect(() => {
      if (REDUCED) return;
      const t1 = setTimeout(() => setStage(1), 350);   // burbuja entrante
      const t2 = setTimeout(() => setStage(2), 1100);  // typing
      const t3 = setTimeout(() => setStage(3), 2200);  // respuesta agente
      return () => { clearTimeout(t1); clearTimeout(t2); clearTimeout(t3); };
    }, []);
    return (
      <div className="eco-demo eco-demo--wa" aria-hidden="true">
        <div className="ed-wa__head"><i className="ed-wa__dot" />Agente · WhatsApp</div>
        <div className="ed-wa__body">
          {stage >= 1 && (
            <div className="ed-bubble ed-bubble--in">¿Tienen espacio mañana en la mañana?</div>
          )}
          {stage === 2 && (
            <div className="ed-bubble ed-bubble--typing"><i /><i /><i /></div>
          )}
          {stage >= 3 && (
            <div className="ed-bubble ed-bubble--out">Sí — te aparto mañana 10:30. ¿Te lo confirmo? ✅</div>
          )}
        </div>
      </div>
    );
  }

  // ---------- E·03 LLAMADAS: waveform + timer ----------
  function CallDemo() {
    const [secs, setSecs] = useState(REDUCED ? 12 : 0);
    useEffect(() => {
      if (REDUCED) return;
      const id = setInterval(() => setSecs((s) => (s >= 12 ? 12 : s + 1)), 240);
      return () => clearInterval(id);
    }, []);
    const mm = String(Math.floor(secs / 60)).padStart(2, '0');
    const ss = String(secs % 60).padStart(2, '0');
    const bars = [0.4, 0.7, 1, 0.55, 0.85, 0.3, 0.65, 0.95, 0.5, 0.75, 0.35, 0.8, 0.6, 0.9, 0.45];
    return (
      <div className="eco-demo eco-demo--call" aria-hidden="true">
        <div className="ed-call__head">
          <span className="ed-call__live"><i />LLAMADA ACTIVA</span>
          <span className="ed-call__timer">{mm}:{ss}</span>
        </div>
        <div className={"ed-wave" + (REDUCED ? " is-static" : "")}>
          {bars.map((h, i) => (
            <span key={i} style={{ '--h': h, '--i': i }} />
          ))}
        </div>
        <div className="ed-call__cap">Entiende, agenda y registra en tu sistema.</div>
      </div>
    );
  }

  // ---------- E·04 INTEGRACIONES: log de sincronización en vivo ----------
  function IntegrationsDemo() {
    const TOOLS = [
      { n: 'CRM · HubSpot', d: 280 },
      { n: 'Facturación · CFDI', d: 760 },
      { n: 'Google Calendar', d: 1240 },
      { n: 'WhatsApp Business', d: 1720 }
    ];
    const [done, setDone] = useState(REDUCED ? TOOLS.length : 0);
    useEffect(() => {
      if (REDUCED) return;
      const ts = TOOLS.map((t, i) => setTimeout(() => setDone((d) => Math.max(d, i + 1)), t.d));
      return () => ts.forEach(clearTimeout);
    }, []);
    return (
      <div className="eco-demo eco-demo--int" aria-hidden="true">
        <div className="ed-int__head"><i className="ed-sync" />SINCRONIZANDO TU STACK</div>
        <div className="ed-int__rows">
          {TOOLS.map((t, i) => (
            <div className={"ed-int__row" + (i < done ? " is-done" : "")} key={t.n}
                 style={{ animationDelay: (i * 0.12) + 's' }}>
              <span className="ed-int__name">{t.n}</span>
              <span className="ed-int__status">
                {i < done
                  ? <span className="ed-int__ok">✓ sincronizado</span>
                  : <span className="ed-int__wait"><i /><i /><i /></span>}
              </span>
            </div>
          ))}
        </div>
        <div className="ed-int__foot">Enlazado a lo que ya usas. Sin capturar dos veces.</div>
      </div>
    );
  }

  // ---------- E·05 UN SOLO CEREBRO: feed unificado multicanal ----------
  function BrainDemo() {
    const FEED = [
      { tag: 'WA', cls: 'wa', txt: 'Cliente preguntó por disponibilidad', d: 300 },
      { tag: 'TEL', cls: 'tel', txt: 'Llamada agendó cita · mañana 10:30', d: 900 },
      { tag: 'MAIL', cls: 'mail', txt: 'Cotización enviada y registrada', d: 1500 }
    ];
    const [n, setN] = useState(REDUCED ? FEED.length : 0);
    useEffect(() => {
      if (REDUCED) return;
      const ts = FEED.map((f, i) => setTimeout(() => setN((c) => Math.max(c, i + 1)), f.d));
      return () => ts.forEach(clearTimeout);
    }, []);
    return (
      <div className="eco-demo eco-demo--brain" aria-hidden="true">
        <div className="ed-brain__head"><i className="ed-sync" />UN SOLO TIMELINE · 3 CANALES</div>
        <div className="ed-brain__feed">
          {FEED.slice(0, n).map((f, i) => (
            <div className="ed-brain__row" key={f.tag} style={{ animationDelay: (i * 0.05) + 's' }}>
              <span className={"ed-tag ed-tag--" + f.cls}>{f.tag}</span>
              <span className="ed-brain__txt">{f.txt}</span>
            </div>
          ))}
        </div>
        <div className="ed-brain__foot">
          <span className="ed-brain__merge">↳</span> Todo aterriza en el mismo lugar. Cero sistemas que no se hablan.
        </div>
      </div>
    );
  }

  // ---------- E·06 A TU MEDIDA: blueprint que se dibuja solo ----------
  function BlueprintDemo() {
    const NODES = [
      { x: 18, y: 30, t: 'TU OPERACIÓN', d: 0 },
      { x: 130, y: 30, t: 'AGENTE', d: 0.5 },
      { x: 242, y: 14, t: 'DASHBOARD', d: 1.0 },
      { x: 242, y: 78, t: 'TU EQUIPO', d: 1.0 }
    ];
    const LINES = [
      { d: 'M 78 38 L 130 38', delay: 0.35 },
      { d: 'M 188 38 L 242 24', delay: 0.85 },
      { d: 'M 188 42 L 242 86', delay: 0.85 }
    ];
    return (
      <div className="eco-demo eco-demo--bp" aria-hidden="true">
        <div className="ed-bp__head"><i className="ed-sync" />MAPEANDO TU OPERACIÓN · ÚNICO</div>
        <svg className="ed-bp__svg" viewBox="0 0 300 110" preserveAspectRatio="xMidYMid meet">
          {LINES.map((l, i) => (
            <path key={i} className="ed-bp__line" d={l.d} pathLength="1" fill="none"
                  style={{ animationDelay: REDUCED ? '0s' : l.delay + 's' }} />
          ))}
          {NODES.map((nd, i) => (
            <g key={i} className="ed-bp__node" style={{ animationDelay: REDUCED ? '0s' : nd.d + 's' }}>
              <rect x={nd.x} y={nd.y} width="70" height="18" rx="3" />
              <text x={nd.x + 35} y={nd.y + 12} textAnchor="middle">{nd.t}</text>
            </g>
          ))}
        </svg>
        <div className="ed-bp__foot">Mapeamos cómo trabajas antes de construir. No hay dos iguales.</div>
      </div>
    );
  }

  function EcoDemo({ which }) {
    const [ref, inView] = useInView('200px');
    let inner = null;
    if (inView) {
      if (which === 0) inner = <DashboardDemo />;
      else if (which === 1) inner = <WhatsappDemo />;
      else if (which === 2) inner = <CallDemo />;
      else if (which === 3) inner = <IntegrationsDemo />;
      else if (which === 4) inner = <BrainDemo />;
      else if (which === 5) inner = <BlueprintDemo />;
    }
    // El wrapper reserva alto para que no salte el layout al montar el demo.
    return <div className="eco-demo-mount" ref={ref}>{inner}</div>;
  }

  Object.assign(window, { EcoDemo });
})();
