/* global React, Icon, HablaiPill */
const { useState: useLandState, useEffect: useLandEffect, useRef: useLandRef } = React;

/**
 * Hablai Landing: editorial, cálido, serif grande.
 * Secciones: Nav, Hero (con demo integrado), Before/After, Diferenciadores,
 * Pill-in-the-wild, Precios, Footer.
 *
 * Principios:
 *  - Nada de eyebrows "POR QUÉ HABLAI NO OTRA APP" arriba de cada sección.
 *    La página habla por sí sola, como la app. Titulares serif directos.
 *  - Cero mención a competidores por nombre.
 *  - "Apretai y hablai" es el permiso chileno. Hablai: hablar en voseo.
 *    El copy lo usa como pequeño guiño sin explicarlo.
 */
function HablaiLanding() {
  return (
    <div className="landing">
      <LandingNav />
      <LandingHero />
      <LandingBeforeAfter />
      <LandingDifferentiators />
      <LandingPillShowcase />
      <LandingPricing />
      <LandingFooter />
    </div>
  );
}

function LandingNav() {
  const isDark = typeof document !== "undefined" &&
    document.documentElement.getAttribute("data-theme") === "dark";
  const wordmark = isDark
    ? "assets/brand/hablai-wordmark-dark.png"
    : "assets/brand/hablai-wordmark-light.png";
  return (
    <nav className="lnav">
      <div className="lnav-inner">
        <div className="lnav-brand">
          <img src={wordmark} alt="Hablai" style={{ height: 26, width: "auto" }} />
        </div>
        <div className="lnav-links">
          <a>Producto</a>
          <a>Privacidad</a>
          <a>Precios</a>
          <a>Blog</a>
        </div>
        <div className="lnav-right">
          <a className="btn-download" href="/downloads"><Icon name="apple" size={14} /> Descargar</a>
        </div>
      </div>
    </nav>
  );
}

/* ── Hero ─────────────────────────────────── */
function LandingHero() {
  return (
    <section className="lhero">
      <h1 className="lhero-title serif">
        Dictar en crudo es fácil.<br/>
        <em>Dictar limpio</em> es el truco.
      </h1>
      <p className="lhero-lead">
        Mantienes una tecla, hablas, sueltas. Un modelo corriendo en tu
        propio Mac transcribe con puntuación y pega el texto donde estés
        escribiendo. Tu voz nunca sale de tu computador.
      </p>
      <div className="lhero-cta">
        <a className="btn-download btn-download--lg" href="/downloads"><Icon name="apple" size={18} /> Descargar para Mac</a>
        <span className="lhero-cta-meta">
          14 días gratis · <strong>$15/mes</strong> · corre 100% local en tu Mac
        </span>
      </div>
      <LandingDemo />
      <LandingMarquee />
    </section>
  );
}

/* ── Interactive demo ─────────────────────────
 * Auto-loop. Arranca solo al entrar al viewport, se reinicia cada vez que
 * completa el polish. User feedback 2026-04-21: "tiene que autoreproducirse
 * de manera inmediata, como un gif que se repite".
 *
 * Ciclo completo ~8s:
 *   0.0s  listening empieza, palabras aparecen ~140ms cada una
 *   ~4s   llega a polishing
 *   ~5s   texto pulido se va dibujando (22ms/char)
 *   ~7s   done, se queda 2.5s mostrando el resultado
 *   ~9.5s reset → arranca de nuevo
 */
function LandingDemo() {
  const [state, setState] = useLandState("idle");
  const [transcript, setTranscript] = useLandState("");
  const [polished, setPolished] = useLandState("");
  const offline = true;
  const [paused, setPaused] = useLandState(false);
  const [inView, setInView] = useLandState(false);
  const timers = useLandRef([]);
  const containerRef = useLandRef(null);

  const DEMO_RAW = "eh hola mira te quería pasar el link del pr de hablai es github punto com slash hablai slash app y bueno si puedes revisarlo hoy mejor ehm gracias";
  const DEMO_POLISHED = "Hola, te paso el link del PR de Hablai: github.com/hablai/app. Si puedes revisarlo hoy, mejor. Gracias.";

  const cleanup = () => { timers.current.forEach(clearTimeout); timers.current = []; };

  const start = () => {
    cleanup();
    setState("listening"); setTranscript(""); setPolished("");
    const words = DEMO_RAW.split(" ");
    words.forEach((w, i) => {
      timers.current.push(setTimeout(() => {
        setTranscript(prev => prev + (prev ? " " : "") + w);
      }, 140 * (i + 1)));
    });
    timers.current.push(setTimeout(() => setState("polishing"), 140 * words.length + 400));
    timers.current.push(setTimeout(() => {
      let i = 0;
      const id = setInterval(() => {
        i++;
        setPolished(DEMO_POLISHED.slice(0, i));
        if (i >= DEMO_POLISHED.length) { clearInterval(id); setState("done"); }
      }, 22);
    }, 140 * words.length + 1300));
  };

  const reset = () => { cleanup(); setState("idle"); setTranscript(""); setPolished(""); };

  // IntersectionObserver: solo corre el loop cuando el demo está en viewport.
  // Ahorra CPU + evita empezar el loop "por detrás" antes que el user lo vea.
  useLandEffect(() => {
    if (typeof IntersectionObserver === "undefined") { setInView(true); return; }
    const el = containerRef.current;
    if (!el) return;
    const obs = new IntersectionObserver(
      (entries) => entries.forEach(e => setInView(e.isIntersecting)),
      { threshold: 0.2 }
    );
    obs.observe(el);
    return () => obs.disconnect();
  }, []);

  // Loop controller: arranca al estar en viewport + no pausado, y al llegar
  // a "done" espera 2.5s mostrando el resultado y reinicia.
  useLandEffect(() => {
    if (paused || !inView) { cleanup(); return; }
    if (state === "idle") {
      const t = setTimeout(start, 450);
      return () => clearTimeout(t);
    }
    if (state === "done") {
      const t = setTimeout(() => { reset(); }, 2500);
      return () => clearTimeout(t);
    }
  }, [state, paused, inView]);

  useLandEffect(() => () => cleanup(), []);

  const togglePause = () => {
    if (paused) { setPaused(false); reset(); }
    else { setPaused(true); cleanup(); }
  };

  return (
    <div className="ldemo" ref={containerRef}>
      <div className="ldemo-frame">
        <div className="ldemo-topbar">
          <span className="caps">
            {paused ? "Pausado" : "Demo en vivo"}
            {!paused && inView && <span className="ldemo-live-dot" aria-hidden="true" />}
          </span>
          <div className="ldemo-modeswitch">
            <span className="ldemo-mode ldemo-mode--active">
              <Icon name="cpu" size={11} /> 100% local
            </span>
          </div>
        </div>

        <div className="ldemo-body">
          <div className="ldemo-col">
            <div className="caps ldemo-col-label">
              <span className="dotcol dotcol--raw" /> Lo que dijiste
            </div>
            <div className="ldemo-raw">
              {transcript || <span className="ldemo-placeholder">Así se transcribe un audio real…</span>}
              {state === "listening" && <span className="blink-cursor">▏</span>}
            </div>
          </div>

          <div className="ldemo-divider">
            <div className="ldemo-divider-line" />
            <div className="ldemo-divider-arrow"><Icon name="arrow-right" size={14} /></div>
            <div className="ldemo-divider-line" />
          </div>

          <div className="ldemo-col">
            <div className="caps ldemo-col-label">
              <span className="dotcol dotcol--polished" /> Lo que Hablai pega
            </div>
            <div className="ldemo-polished serif">
              {polished || <span className="ldemo-placeholder">…puntuado, limpio y con formato.</span>}
              {state === "polishing" && <span className="blink-cursor">▏</span>}
            </div>
          </div>
        </div>

        <div className="ldemo-footer">
          <div className="ldemo-pill-wrap">
            <HablaiPill state={paused ? "idle" : state} offline={offline} />
          </div>
          <div className="ldemo-actions">
            <button className="btn-ghost" onClick={togglePause} aria-label={paused ? "Reanudar demo" : "Pausar demo"}>
              {paused ? <><Icon name="mic" size={13} /> Reanudar</> : "Pausar"}
            </button>
            {state === "done" && (
              <button className="btn-ghost">
                <Icon name="copy" size={12} /> Copiar resultado
              </button>
            )}
          </div>
        </div>
      </div>

      <div className="ldemo-caption">
        Demo loopeando. En la app real es tu voz, tu micrófono, tu modelo.
      </div>
    </div>
  );
}

/* ── Marquee social proof ─────────────────── */
function LandingMarquee() {
  const logos = ["Anthropic", "Linear", "Framer", "Vercel", "Stripe", "Supabase", "Cursor", "Raycast"];
  return (
    <div className="lmarquee">
      <div className="lmarquee-track">
        {logos.concat(logos).map((l, i) => (
          <span key={i} className="serif lmarquee-item">{l}</span>
        ))}
      </div>
    </div>
  );
}

/* ── Before / After ─────────────────────────
 * Sin sobretítulos. El contraste habla solo.
 */
function LandingBeforeAfter() {
  const examples = [
    {
      label: "Email rápido",
      raw: "hola samir eh quería confirmar la reunión del jueves a las tres y también ver si podemos mover el stand-up del lunes",
      polished: "Hola Samir, quería confirmar la reunión del jueves a las 3:00. ¿Podemos mover el stand-up del lunes?",
    },
    {
      label: "Notas de código",
      raw: "ok entonces el bug está en el componente pill jsx línea noventa y dos cuando el estado cambia a polishing el timer no se limpia",
      polished: "El bug está en `Pill.jsx` línea 92: cuando el estado cambia a `polishing`, el timer no se limpia.",
    },
    {
      label: "Lista de tareas",
      raw: "a ver necesito comprar café pasar por la tintorería y acordarme de pagar la luz antes del quince",
      polished: "• Comprar café\n• Pasar por la tintorería\n• Pagar la luz antes del 15",
    },
  ];
  const [active, setActive] = useLandState(0);
  return (
    <section className="lba">
      <div className="lba-head">
        <h2 className="serif lba-title">
          El truco no es transcribir.<br/>
          Es <em>quedar bien</em> cuando lo pega.
        </h2>
        <p className="lba-sub">
          Todo lo que dictas pasa por un LLM que aprende tu estilo, tu diccionario
          y el contexto de la app donde estás escribiendo.
        </p>
      </div>

      <div className="lba-tabs">
        {examples.map((e, i) => (
          <button
            key={i}
            className={`lba-tab ${active === i ? "lba-tab--active" : ""}`}
            onClick={() => setActive(i)}
          >
            {e.label}
          </button>
        ))}
      </div>

      <div className="lba-compare">
        <div className="lba-col lba-col--raw">
          <div className="caps lba-col-label">Lo que dijiste</div>
          <div className="lba-text">{examples[active].raw}</div>
        </div>
        <div className="lba-arrow">
          <svg viewBox="0 0 40 40" width="40" height="40" fill="none" stroke="currentColor" strokeWidth="1.2">
            <path d="M8 20h24M24 12l8 8-8 8" strokeLinecap="round" />
          </svg>
        </div>
        <div className="lba-col lba-col--polished">
          <div className="caps lba-col-label">Lo que Hablai escribe</div>
          <div className="lba-text serif" style={{ whiteSpace: "pre-line" }}>{examples[active].polished}</div>
        </div>
      </div>
    </section>
  );
}

/* ── Differentiators ──────────────────────────
 * Sin sobretítulo. Sin comparaciones con nombres.
 * Solo lo que Hablai hace, directo.
 */
function LandingDifferentiators() {
  const features = [
    {
      icon: "shield",
      title: "Tu voz no sale del Mac.",
      body: "Transcripción 100% local con Parakeet y Whisper. Tu cuenta solo valida la suscripción: el audio jamás sale de tu Mac.",
      meta: "0 datos salen",
      accent: true,
    },
    {
      icon: "zap",
      title: "Más rápido que releer lo que dijiste.",
      body: "Modelos afinados para Apple Silicon con Metal. 5 segundos de audio se transcriben en menos de 200 ms una vez cargado el modelo.",
      meta: "31x tiempo real",
    },
    {
      icon: "layers",
      title: "El pulido es opcional, y lo eliges tú.",
      body: "Sin configurar nada, Hablai dicta igual. Si quieres pulido con LLM: Ollama local, Apple Intelligence, o tu propia key de Anthropic, OpenAI o Groq.",
      meta: "7 proveedores",
    },
    {
      icon: "book",
      title: "Aprende tu jerga.",
      body: "Nombres, marcas, acrónimos técnicos. Lo dices dos veces y Hablai lo guarda. El LLM respeta la ortografía que tú elegiste.",
      meta: "Ilimitadas",
    },
    {
      icon: "sliders",
      title: "Tres estilos de corrección.",
      body: "Ligero, Medio o Alto: tú decides cuánto corrige el pulido, desde puntuación mínima hasta texto listo para enviar.",
      meta: "3 estilos",
    },
    {
      icon: "lock",
      title: "Un precio, no diez.",
      body: "$15 al mes con 14 días de prueba. Minutos ilimitados porque el cómputo lo pone tu Mac, no un servidor que cobra por segundo.",
      meta: "$15 / mes",
      accent: true,
    },
  ];
  return (
    <section className="ldiff">
      <div className="ldiff-head">
        <h2 className="serif ldiff-title">
          Las otras apps transcriben.<br/>
          <em>Hablai</em> te hace quedar bien.
        </h2>
      </div>
      <div className="ldiff-grid">
        {features.map((f, i) => (
          <div key={i} className={`ldiff-card ${f.accent ? "ldiff-card--accent" : ""}`}>
            <div className="ldiff-icon"><Icon name={f.icon} size={18} /></div>
            <h3 className="serif ldiff-card-title" dangerouslySetInnerHTML={{ __html: f.title }} />
            <p className="ldiff-card-body">{f.body}</p>
            <div className="ldiff-meta">{f.meta}</div>
          </div>
        ))}
      </div>

      <LandingComparison />
    </section>
  );
}

/* ── Genérica: Hablai vs otras apps vs dictado del sistema ──
 * No nombramos competidores. "Otras apps de dictado" es suficiente.
 */
function LandingComparison() {
  const rows = [
    { f: "Modo 100% local (offline)", hablai: "Siempre", others: "A veces", native: "Limitado" },
    { f: "Post-procesado con LLM", hablai: "4+ proveedores", others: "Fijo o ninguno", native: "No" },
    { f: "Diccionario personal", hablai: "Ilimitado", others: "A veces", native: "Básico" },
    { f: "Estilos de corrección", hablai: "3 niveles", others: "A veces", native: "No" },
    { f: "Dictado sin internet", hablai: "Sí (hasta 3 días seguidos)", others: "Raro", native: "No" },
    { f: "Código abierto (base)", hablai: "Sí", others: "Raro", native: "No" },
    { f: "Telemetría por default", hablai: "Off", others: "On", native: "On" },
  ];
  return (
    <div className="lcompare">
      <div className="lcompare-head">
        <div />
        <div className="lcompare-h lcompare-h--us">
          <span className="serif">Hablai</span>
        </div>
        <div className="lcompare-h">Otras apps</div>
        <div className="lcompare-h">Dictado del sistema</div>
      </div>
      {rows.map((r, i) => (
        <div key={i} className="lcompare-row">
          <div className="lcompare-f">{r.f}</div>
          <div className="lcompare-v lcompare-v--us"><strong>{r.hablai}</strong></div>
          <div className="lcompare-v">{r.others}</div>
          <div className="lcompare-v">{r.native}</div>
        </div>
      ))}
    </div>
  );
}

/* ── Pill showcase: 4 estados, ciclo suave ───
 * Reemplaza el "Así se ve" sobrecargado. Aquí solo vive el pill,
 * cycling: idle → listening → polishing → done → idle.
 * Sin eyebrow, sin pompa. El pill es la evidencia.
 */
function LandingPillShowcase() {
  const CYCLE = ["idle", "listening", "polishing", "done"];
  const LABELS = {
    idle: { n: "1", t: "Dormida", s: "Vive en la barra de menú. Un punto." },
    listening: { n: "2", t: "Escuchando", s: "Apretaste. La onda responde a tu voz." },
    polishing: { n: "3", t: "Puliendo", s: "El LLM arregla, tu cursor espera." },
    done: { n: "4", t: "Listo", s: "Texto pegado en la app activa." },
  };
  const [idx, setIdx] = useLandState(0);
  const cur = CYCLE[idx];

  useLandEffect(() => {
    const dur = cur === "idle" ? 1400 : cur === "listening" ? 2200 : cur === "polishing" ? 1400 : 1800;
    const t = setTimeout(() => setIdx((i) => (i + 1) % CYCLE.length), dur);
    return () => clearTimeout(t);
  }, [idx, cur]);

  return (
    <section className="lshot">
      <div className="lshot-head">
        <h2 className="serif lshot-title">
          Una app pequeña.<br/>Un gesto <em>silencioso</em>.
        </h2>
        <p className="lshot-sub">
          Apretai. Hablai. Listo. Eso es todo lo que ves.
        </p>
      </div>

      <div className="lpills">
        <div className="lpills-center">
          <HablaiPill state={cur} offline />
        </div>
        <div className="lpills-steps">
          {CYCLE.map((s, i) => {
            const L = LABELS[s];
            const active = i === idx;
            const past = i < idx;
            return (
              <div key={s} className={`lpstep ${active ? "lpstep--active" : ""} ${past ? "lpstep--past" : ""}`}>
                <div className="lpstep-num mono">{L.n}</div>
                <div className="lpstep-body">
                  <div className="serif lpstep-t">{L.t}</div>
                  <div className="lpstep-s">{L.s}</div>
                </div>
              </div>
            );
          })}
        </div>
      </div>
    </section>
  );
}

/* ── Pricing ──────────────────────────────── */
function LandingPricing() {
  return (
    <section className="lprice">
      <div className="lprice-head">
        <h2 className="serif lprice-title">Un precio <em>simple</em>.</h2>
        <p className="lprice-sub">
          14 días de prueba. Después $15/mes. Y aunque pagas la suscripción,
          tu voz se procesa 100% en tu Mac: nunca pasa por un servidor.
        </p>
      </div>
      <div className="lprice-grid lprice-grid--single">
        <PriceCard
          tier="Pro"
          price="$15"
          period="por mes"
          pitch="Todo lo que Hablai hace, sin límites."
          features={[
            "Minutos ilimitados (el cómputo lo pone tu Mac)",
            "Transcripción 100% local y privada",
            "Modelos Parakeet y Whisper, eliges en la app",
            "Los tres estilos (Ligero · Medio · Alto)",
            "Diccionario personal y atajos de texto",
            "14 días de prueba, cancelas cuando quieras",
          ]}
          cta="Descargar y probar 14 días"
          href="/downloads"
          featured
        />
      </div>
    </section>
  );
}

function PriceCard({ tier, price, strike, period, pitch, features, cta, href, featured }) {
  return (
    <div className={`pcard ${featured ? "pcard--featured" : ""}`}>
      {featured && <div className="pcard-ribbon">Más popular</div>}
      <div className="pcard-tier caps">{tier}</div>
      <div className="pcard-price-row">
        <span className="pcard-price serif">{price}</span>
        {strike && <span className="pcard-strike">{strike}</span>}
        {period && <span className="pcard-period">{period}</span>}
      </div>
      <p className="pcard-pitch">{pitch}</p>
      <ul className="pcard-features">
        {features.map((f, i) => (
          <li key={i}><Icon name="check" size={12} /> {f}</li>
        ))}
      </ul>
      {href ? (
        <a className={`pcard-cta ${featured ? "pcard-cta--primary" : ""}`} href={href}>{cta}</a>
      ) : (
        <button className={`pcard-cta ${featured ? "pcard-cta--primary" : ""}`}>{cta}</button>
      )}
    </div>
  );
}

/* ── Footer ───────────────────────────────── */
function LandingFooter() {
  return (
    <footer className="lfoot">
      <div className="lfoot-hero">
        <h2 className="serif lfoot-cta-title">
          No pensai. <em>Hablai.</em>
        </h2>
        <a className="btn-download btn-download--lg" href="/downloads"><Icon name="apple" size={18} /> Descargar para Mac</a>
        <span className="lfoot-meta">macOS 13+ (Apple Silicon) · 14 días gratis · tu voz nunca sale de tu Mac</span>
      </div>
      <div className="lfoot-links">
        <div>
          <div className="caps lfoot-col-label">Producto</div>
          <a>Características</a><a>Privacidad</a><a href="/downloads">Descargar</a>
        </div>
        <div>
          <div className="caps lfoot-col-label">Recursos</div>
          <a>Documentación</a><a>Atajos</a><a>LLM providers</a><a>FAQ</a>
        </div>
        <div>
          <div className="caps lfoot-col-label">Compañía</div>
          <a>Blog</a><a>Manifiesto</a><a href="https://github.com/cjpais/Handy" target="_blank" rel="noreferrer">Open source (Handy)</a><a>Contacto</a>
        </div>
        <div>
          <div className="caps lfoot-col-label">Legal</div>
          <a>Términos</a><a>Privacidad</a><a>Licencias</a>
        </div>
      </div>
      <div className="lfoot-bottom">
        <div className="lfoot-brand">
          <img src="assets/brand/hablai-mark-dark.png" alt="" style={{ height: 22, width: "auto", opacity: 0.85 }} />
          <span className="serif">Hablai</span>
          <span className="lfoot-tag">Hecho con cuidado en Santiago.</span>
        </div>
        <div className="lfoot-socials">
          <a>Twitter</a><a>GitHub</a><a>Email</a>
        </div>
      </div>
    </footer>
  );
}

window.HablaiLanding = HablaiLanding;
