// VOICE DEMO — "Sounds like" A/B player.
// Two side-by-side voice samples to make the quality difference visceral:
// the 2024-era IVR-style agent (left) vs. an Iris-style 2026 agent (right).
//
// Implementation note: real audio files aren't checked in yet. We use the
// browser's SpeechSynthesis API as a STAND-IN: the "old" voice is synthesised
// with a slow rate + monotone pitch + a robotic voice if available; the
// "new" voice uses a natural female voice at conversational rate. Replace
// `playClip()` with <audio> tags pointing at real recordings when ready.

function VoiceDemo() {
  return (
    <section className="section" id="voice">
      <div className="shell">
        <SectionHead
          num="§ 06"
          label="VOICE QUALITY · A/B"
          title="Sounds like. Sounds nothing like."
          kicker="The fastest way to know if a voice agent is good: hear it next to a bad one. Press play on both. You'll know in twelve seconds."
        />

        <div style={{
          display: "grid",
          gridTemplateColumns: "1fr 1fr",
          gap: 1,
          background: "var(--ink)",
          border: "1px solid var(--ink)",
          marginBottom: 56,
        }} className="ab-grid">

          <SamplePanel
            kind="old"
            label="A typical 2024 voice agent"
            descriptor="IVR-trained · scripted turns · robotic prosody"
            badPoints={[
              "Reads from a tree — can't handle the unexpected",
              "Latency: 1.8s before each reply",
              "Same answer every time, regardless of context",
              "Customers hang up at ~38%",
            ]}
            line="Please. Press. One. For. Renewals. Press. Two. To. Speak. With. A. Representative."
            ttsConfig={{ rate: 0.68, pitch: 0.85, prefer: ["Microsoft David", "Albert", "Fred", "Daniel"], filter: "robot" }}
            color="var(--ink-mute)"
            duration="0:21"
          />

          <SamplePanel
            kind="new"
            label="Iris — voice agent we ship"
            descriptor="Realtime · context-aware · sub-600ms"
            goodPoints={[
              "Listens, interrupts naturally, recovers from confusion",
              "Latency: ~540ms — feels like a real call",
              "Pulls live Salesforce context per turn",
              "Books to your calendar in-line, no transfer",
            ]}
            line="Hi Marcus — saw you opened the renewal four times. Want me to walk through what changed on the pricing tiers?"
            ttsConfig={{ rate: 1.05, pitch: 1.0, prefer: ["Samantha", "Karen", "Google UK English Female", "Microsoft Aria"] }}
            color="var(--persimmon)"
            duration="0:14"
          />

        </div>

        {/* Technical detail below */}
        <div style={{
          display: "grid",
          gridTemplateColumns: "1.2fr 1fr",
          gap: "clamp(32px, 5vw, 80px)",
          alignItems: "start",
        }} className="voice-detail">
          <div>
            <p className="eyebrow" style={{ marginBottom: 16 }}>UNDER THE HOOD</p>
            <h3 className="serif" style={{ margin: 0, fontSize: "clamp(28px, 3vw, 44px)", lineHeight: 1.05, letterSpacing: "-0.025em", textWrap: "balance" }}>
              The difference isn't the voice. It's the stack underneath.
            </h3>
            <p className="body" style={{ marginTop: 20, maxWidth: "55ch", color: "var(--ink-soft)" }}>
              A pretty voice on top of a 2024 architecture still sounds like 2024.
              We rebuild the whole loop — routing, memory, eval — so the agent has room
              to actually think before it speaks.
            </p>
          </div>

          <div style={{ display: "grid", gap: 12 }}>
            {[
              ["01", "Routing",  "Cloudflare Voice Agents + Twilio — WebRTC for the web, PSTN for the phone. SIP if you bring your own."],
              ["02", "Brain",    "Claude on AWS Bedrock for nuance, Workers AI Llama as automatic free fallback. OpenAI / Anthropic direct also supported if you prefer."],
              ["03", "Memory",   "Salesforce is the source of truth. Agents read the right records and write the right ones back. Cloudflare Vectorize for RAG."],
              ["04", "Voice",    "Workers AI (Deepgram Aura) for STT + TTS — no API keys. ElevenLabs or Cartesia when a specific voice is required."],
              ["05", "Eval",     "Every call scored on outcome, sentiment, drift, and cost."],
            ].map(([n, k, v]) => (
              <div key={n} style={{
                display: "grid",
                gridTemplateColumns: "32px 100px 1fr",
                gap: 16,
                padding: "16px 0",
                borderBottom: "1px solid var(--rule)",
                alignItems: "start",
              }}>
                <span className="mono" style={{ fontSize: 11, color: "var(--ink-mute)", letterSpacing: "0.06em" }}>{n}</span>
                <span className="mono" style={{ fontSize: 12, color: "var(--ink)", letterSpacing: "0.08em", textTransform: "uppercase" }}>{k}</span>
                <span className="body-sm" style={{ color: "var(--ink-soft)" }}>{v}</span>
              </div>
            ))}
          </div>
        </div>
      </div>

      <style>{`
        @media (max-width: 980px) {
          .ab-grid { grid-template-columns: 1fr !important; }
          .voice-detail { grid-template-columns: 1fr !important; }
        }
      `}</style>
    </section>
  );
}

// ── Single sample panel with a big play button + waveform animation
function SamplePanel({ kind, label, descriptor, badPoints, goodPoints, line, ttsConfig, color, duration }) {
  const [playing, setPlaying] = useState(false);
  const [progress, setProgress] = useState(0);
  const utterRef = useRef(null);
  const progressRef = useRef(null);

  // Cancel on unmount
  useEffect(() => () => stop(), []);

  function stop() {
    try { window.speechSynthesis.cancel(); } catch (_) {}
    if (progressRef.current) clearInterval(progressRef.current);
    setPlaying(false);
    setProgress(0);
  }

  function play() {
    if (playing) { stop(); return; }
    // Cancel any other panel that's playing first
    try { window.speechSynthesis.cancel(); } catch (_) {}

    const u = new SpeechSynthesisUtterance(line);
    const voices = window.speechSynthesis.getVoices();
    const v = ttsConfig.prefer.map(name => voices.find(x => x.name && x.name.includes(name))).find(Boolean)
            || voices.find(x => /en[-_]/i.test(x.lang));
    if (v) u.voice = v;
    u.rate = ttsConfig.rate;
    u.pitch = ttsConfig.pitch;
    u.volume = 1.0;

    // Estimate duration (rough words/min)
    const wordCount = line.split(/\s+/).length;
    const wpm = ttsConfig.rate * 160;
    const estMs = (wordCount / wpm) * 60000;
    let elapsed = 0;
    progressRef.current = setInterval(() => {
      elapsed += 80;
      setProgress(Math.min(1, elapsed / estMs));
    }, 80);

    u.onend = () => stop();
    u.onerror = () => stop();
    utterRef.current = u;
    setPlaying(true);
    setProgress(0);
    window.speechSynthesis.speak(u);
  }

  const isNew = kind === "new";
  const points = isNew ? goodPoints : badPoints;

  return (
    <article style={{
      background: isNew ? "var(--paper)" : "var(--paper-2)",
      padding: 32,
      display: "flex",
      flexDirection: "column",
      gap: 22,
      minHeight: 480,
      position: "relative",
    }}>
      {/* Header */}
      <header style={{ display: "flex", justifyContent: "space-between", alignItems: "flex-start", gap: 12 }}>
        <div>
          <span className="mono" style={{ fontSize: 10, color, letterSpacing: "0.16em", textTransform: "uppercase", fontWeight: 700 }}>
            {isNew ? "↑ THE NEW BAR" : "↓ THE OLD WAY"}
          </span>
          <h3 className="serif" style={{ margin: "8px 0 0 0", fontSize: "clamp(22px, 2.4vw, 30px)", lineHeight: 1.1, letterSpacing: "-0.02em", color: "var(--ink)" }}>
            {label}
          </h3>
          <p className="mono" style={{ margin: "8px 0 0 0", fontSize: 11, color: "var(--ink-soft)", letterSpacing: "0.08em", textTransform: "uppercase" }}>
            {descriptor}
          </p>
        </div>
        <span className="mono" style={{ fontSize: 11, color: "var(--ink-mute)", letterSpacing: "0.06em" }}>
          {duration}
        </span>
      </header>

      {/* Play surface */}
      <div style={{
        background: isNew ? "var(--ink)" : "color-mix(in oklab, var(--ink) 12%, var(--paper-2))",
        color: isNew ? "var(--bone)" : "var(--ink)",
        padding: "26px 24px",
        display: "flex",
        alignItems: "center",
        gap: 18,
        position: "relative",
        overflow: "hidden",
      }}>
        <button
          type="button"
          onClick={play}
          aria-label={playing ? "Stop" : "Play sample"}
          style={{
            width: 56,
            height: 56,
            borderRadius: "50%",
            border: "none",
            background: color,
            color: isNew ? "var(--ink)" : "var(--bone)",
            cursor: "pointer",
            display: "inline-grid",
            placeItems: "center",
            flexShrink: 0,
            transition: "transform 0.15s",
            boxShadow: playing ? `0 0 0 6px color-mix(in oklab, ${color} 30%, transparent)` : "none",
          }}
          onMouseEnter={e => e.currentTarget.style.transform = "scale(1.06)"}
          onMouseLeave={e => e.currentTarget.style.transform = "scale(1)"}
        >
          {playing ? (
            <svg width="20" height="20" viewBox="0 0 24 24" fill="currentColor"><rect x="6" y="5" width="4" height="14"/><rect x="14" y="5" width="4" height="14"/></svg>
          ) : (
            <svg width="20" height="20" viewBox="0 0 24 24" fill="currentColor"><polygon points="6,4 20,12 6,20"/></svg>
          )}
        </button>

        <div style={{ flex: 1, minWidth: 0 }}>
          <PlayWave active={playing} color={isNew ? "var(--persimmon)" : "var(--ink-mute)"} bg={isNew ? "color-mix(in oklab, var(--bone) 25%, transparent)" : "color-mix(in oklab, var(--ink) 25%, transparent)"} />
          <div style={{ marginTop: 12, height: 2, background: isNew ? "color-mix(in oklab, var(--bone) 18%, transparent)" : "color-mix(in oklab, var(--ink) 18%, transparent)", position: "relative" }}>
            <div style={{ position: "absolute", inset: 0, width: (progress * 100) + "%", background: color, transition: "width 0.08s linear" }}></div>
          </div>
          <p style={{ margin: "12px 0 0 0", fontSize: 13, lineHeight: 1.4, fontStyle: "normal", color: isNew ? "color-mix(in oklab, var(--bone) 85%, transparent)" : "var(--ink-soft)", fontFamily: "var(--font-display)" }}>
            "{line}"
          </p>
        </div>
      </div>

      {/* Points */}
      <ul style={{ margin: 0, padding: 0, listStyle: "none", display: "grid", gap: 10 }}>
        {points.map((p, i) => (
          <li key={i} style={{ display: "flex", gap: 10, fontSize: 13, lineHeight: 1.45 }}>
            <span style={{ color, flexShrink: 0, fontFamily: "var(--font-mono)" }}>{isNew ? "+" : "—"}</span>
            <span style={{ color: "var(--ink-2)" }}>{p}</span>
          </li>
        ))}
      </ul>
    </article>
  );
}

// Reactive waveform that animates when audio plays
function PlayWave({ active, color, bg }) {
  const bars = 28;
  return (
    <div style={{ display: "flex", alignItems: "center", gap: 2, height: 28 }}>
      {Array.from({ length: bars }).map((_, i) => (
        <span
          key={i}
          style={{
            display: "block",
            flex: 1,
            background: active ? color : bg,
            height: active ? `${15 + Math.sin(i * 0.7) * 35 + Math.random() * 50}%` : "20%",
            animation: active ? `pwave 0.9s ease-in-out ${i * 0.04}s infinite` : "none",
            transition: "height 0.3s",
          }}
        />
      ))}
      <style>{`
        @keyframes pwave {
          0%, 100% { transform: scaleY(0.4); }
          50% { transform: scaleY(1); }
        }
      `}</style>
    </div>
  );
}

Object.assign(window, { VoiceDemo });
