// Extra sections: Manifesto, SpeedBench (interactive race), Privacy
const { useState: useStateR, useEffect: useEffectR, useRef: useRefR } = React;

// ———————————————————————————————————————————————————————————
// Manifesto — four vows
// ———————————————————————————————————————————————————————————
function Manifesto() {
  const vows = [
    { kanji: "壱", label: "One", title: "Silent", body: "Hold fn. Release. No windows, no clicks, no fuss. It was never there." },
    { kanji: "弐", label: "Two", title: "Swift", body: "You speak far faster than you type. The ninja simply stops wasting that." },
    { kanji: "参", label: "Three", title: "Precise", body: "Fillers removed, punctuation fixed, your words kept. A cleanup, never a rewrite." },
    { kanji: "肆", label: "Four", title: "Yours", body: "Your own API key, or fully local models. Your voice answers to you." },
  ];
  return (
    <section className="section manifesto">
      <div className="section-head">
        <div className="section-eyebrow">The code</div>
        <h2 className="section-title">Four vows of the Ninja.</h2>
        <p className="section-sub">Every design decision traces back to one of these.</p>
      </div>
      <div className="manifesto-grid">
        {vows.map((v, i) => (
          <div key={i} className="code-card">
            <div className="code-num" aria-hidden>{v.kanji}</div>
            <div className="code-title">{v.title}</div>
            <p className="code-body">{v.body}</p>
            <div className="code-index">{v.label} · 第{v.label === "One" ? "一" : v.label === "Two" ? "二" : v.label === "Three" ? "三" : "四"}条</div>
          </div>
        ))}
      </div>
    </section>
  );
}

// ———————————————————————————————————————————————————————————
// Privacy — on-device vs cloud toggle
// ———————————————————————————————————————————————————————————
function Privacy() {
  const [mode, setMode] = useStateR("cloud");
  const onDevice = mode === "device";
  return (
    <section className="section privacy">
      <div className="section-head">
        <div className="section-eyebrow">Privacy</div>
        <h2 className="section-title">Your voice answers <span className="privacy-title-alt">to you.</span></h2>
        <p className="section-sub">By default, dictation runs through your own Groq API key. Your key, your account, your data relationship. Prefer total silence? Flip on local mode and nothing ever leaves your Mac.</p>
      </div>
      <div className="privacy-grid">
        <ul className="privacy-list">
          <li><span className="privacy-check">✓</span>Your own API key. No middleman server collecting your audio</li>
          <li><span className="privacy-check">✓</span>Local mode: Whisper and a local LLM run fully on-device, fully offline</li>
          <li><span className="privacy-check">✓</span>Privacy Mode: skip AI cleanup entirely, raw transcript only</li>
          <li><span className="privacy-check">✓</span>Audio is never stored by the app</li>
          <li><span className="privacy-check">✓</span>No analytics, no tracking, no phoning home</li>
        </ul>
        <div className="privacy-viz">
          <div className="privacy-toggle">
            <span className="privacy-toggle-label">Mode</span>
            <div className="privacy-toggle-btns">
              <button className={!onDevice ? "active" : ""} onClick={() => setMode("cloud")}>your key (default)</button>
              <button className={onDevice ? "active" : ""} onClick={() => setMode("device")}>local mode</button>
            </div>
          </div>
          <svg className="privacy-svg" viewBox="0 0 400 200" aria-hidden>
            {/* Mac */}
            <g className={`priv-node ${onDevice ? "priv-center" : "priv-left"}`}>
              <rect x="40" y="60" width="120" height="80" rx="8" fill="var(--paper-2)" stroke="var(--ink)" strokeWidth="2.5"/>
              <rect x="52" y="72" width="96" height="56" rx="3" fill="var(--paper)" stroke="var(--ink)" strokeWidth="1.8"/>
              <rect x="85" y="140" width="30" height="5" fill="var(--paper-2)" stroke="var(--ink)" strokeWidth="1.8"/>
              <rect x="70" y="145" width="60" height="4" rx="2" fill="var(--paper-2)" stroke="var(--ink)" strokeWidth="1.8"/>
              {/* Padlock inside mac when on-device */}
              {onDevice && (
                <g className="priv-lock">
                  <rect x="85" y="90" width="30" height="24" rx="3" fill="var(--accent)" stroke="var(--ink)" strokeWidth="2"/>
                  <path d="M93 90 v-6 a7 7 0 0 1 14 0 v6" fill="none" stroke="var(--ink)" strokeWidth="2" strokeLinecap="round"/>
                  <circle cx="100" cy="102" r="2.5" fill="var(--ink)"/>
                </g>
              )}
              {/* sound waves when dictating on-device */}
              {onDevice && (
                <g className="priv-waves">
                  <path d="M65 100 q0 -6 0 -12" stroke="var(--accent-ink)" strokeWidth="1.5" fill="none" strokeLinecap="round"/>
                  <path d="M60 100 q0 -10 0 -20" stroke="var(--accent-ink)" strokeWidth="1.5" fill="none" strokeLinecap="round" opacity="0.6"/>
                  <path d="M135 100 q0 -6 0 -12" stroke="var(--accent-ink)" strokeWidth="1.5" fill="none" strokeLinecap="round"/>
                  <path d="M140 100 q0 -10 0 -20" stroke="var(--accent-ink)" strokeWidth="1.5" fill="none" strokeLinecap="round" opacity="0.6"/>
                </g>
              )}
            </g>
            <text x="100" y="180" fontFamily="ui-monospace, monospace" fontSize="11" fill="var(--ink-70)" textAnchor="middle" className="priv-label priv-left-label" style={{opacity: onDevice ? 0 : 1}}>your mac</text>
            <text x="200" y="180" fontFamily="ui-monospace, monospace" fontSize="11" fill="var(--ink-70)" textAnchor="middle" className="priv-label priv-center-label" style={{opacity: onDevice ? 1 : 0}}>your mac · everything stays here</text>

            {/* Connection line + server when cloud mode */}
            {!onDevice && (
              <g className="priv-cloud-group">
                <path d="M160 100 L240 100" stroke="var(--ink)" strokeWidth="2.5" strokeDasharray="7 5" className="privacy-flow" strokeLinecap="round"/>
                <g className="priv-packet">
                  <circle r="4" fill="var(--accent-2)" stroke="var(--ink)" strokeWidth="1.5"/>
                </g>
                {/* Server */}
                <g>
                  <rect x="240" y="60" width="120" height="80" rx="8" fill="var(--paper-2)" stroke="var(--ink)" strokeWidth="2.5"/>
                  <rect x="252" y="72" width="96" height="16" rx="2" fill="var(--paper)" stroke="var(--ink)" strokeWidth="1.5"/>
                  <circle cx="260" cy="80" r="2" fill="var(--accent-2)"/>
                  <rect x="268" y="78" width="76" height="4" fill="var(--ink-30)"/>
                  <rect x="252" y="92" width="96" height="16" rx="2" fill="var(--paper)" stroke="var(--ink)" strokeWidth="1.5"/>
                  <circle cx="260" cy="100" r="2" fill="var(--accent-2)"/>
                  <rect x="268" y="98" width="76" height="4" fill="var(--ink-30)"/>
                  <rect x="252" y="112" width="96" height="16" rx="2" fill="var(--paper)" stroke="var(--ink)" strokeWidth="1.5"/>
                  <circle cx="260" cy="120" r="2" fill="var(--accent-2)"/>
                  <rect x="268" y="118" width="76" height="4" fill="var(--ink-30)"/>
                </g>
                <text x="300" y="180" fontFamily="ui-monospace, monospace" fontSize="11" fill="var(--ink-70)" textAnchor="middle">groq · your key, your account</text>
              </g>
            )}
          </svg>
          <div className="privacy-status">
            <span className={`privacy-dot ${onDevice ? "" : "offline"}`} />
            {onDevice ? "local mode · fully offline · no network" : "your key · nothing stored · switch anytime"}
          </div>
        </div>
      </div>
    </section>
  );
}

// ———————————————————————————————————————————————————————————
// SpeedBench — interactive race
// ———————————————————————————————————————————————————————————

// A rotating pool of funny sentences. One is picked per race.
const RACE_SENTENCES = [
  "I type like a raccoon wearing mittens while the ninja sips matcha and laughs politely.",
  "My fingers are powered by panic and leftover pizza; the ninja is powered by generational discipline.",
  "By the time I find the comma key, the ninja has already replied to three emails and adopted a cat.",
  "Look at me, typing confidently, being absolutely humiliated by a tiny cartoon with a headband.",
  "The ninja finished this sentence, made tea, and filed your taxes while you were still looking for the Q.",
];

const NINJA_SECONDS = 3.6; // ninja finishes in 3.6s — feels fast but fair
const MAX_SECONDS = 30;    // hard cap for user race

function SpeedBench() {
  // phase: idle | countdown | racing | done
  const [phase, setPhase] = useStateR("idle");
  const [count, setCount] = useStateR(3);
  const [typed, setTyped] = useStateR("");
  const [elapsed, setElapsed] = useStateR(0); // seconds
  const [finalTime, setFinalTime] = useStateR(null);
  const [sentence, setSentence] = useStateR(RACE_SENTENCES[0]);
  const [pasteBust, setPasteBust] = useStateR(false); // show gotcha overlay
  const [dq, setDq] = useStateR(false); // disqualified for pasting
  const inputRef = useRefR(null);
  const startRef = useRefR(0);
  const rafRef = useRefR(0);

  const RACE_WORDS = sentence.trim().split(/\s+/).length;

  // Countdown
  useEffectR(() => {
    if (phase !== "countdown") return;
    if (count === 0) {
      setPhase("racing");
      startRef.current = performance.now();
      setTimeout(() => inputRef.current?.focus(), 30);
      return;
    }
    const id = setTimeout(() => setCount(c => c - 1), 700);
    return () => clearTimeout(id);
  }, [phase, count]);

  // Elapsed timer during race
  useEffectR(() => {
    if (phase !== "racing") return;
    const tick = () => {
      const e = (performance.now() - startRef.current) / 1000;
      setElapsed(e);
      if (e >= MAX_SECONDS) {
        finish(e, typed);
        return;
      }
      rafRef.current = requestAnimationFrame(tick);
    };
    rafRef.current = requestAnimationFrame(tick);
    return () => cancelAnimationFrame(rafRef.current);
  }, [phase, typed]);

  const finish = (t, value) => {
    cancelAnimationFrame(rafRef.current);
    setFinalTime(t);
    setPhase("done");
  };

  const onType = (e) => {
    const v = e.target.value;
    setTyped(v);
    if (v.trim() === sentence) {
      const t = (performance.now() - startRef.current) / 1000;
      finish(t, v);
    }
  };

  const onPaste = (e) => {
    e.preventDefault();
    setPasteBust(true);
    setDq(true);
    setTimeout(() => setPasteBust(false), 2400);
    // end the race immediately as DQ
    const t = (performance.now() - startRef.current) / 1000;
    finish(t, typed);
  };

  const start = () => {
    setTyped("");
    setElapsed(0);
    setFinalTime(null);
    setDq(false);
    setPasteBust(false);
    // pick a fresh random sentence each race
    setSentence(RACE_SENTENCES[Math.floor(Math.random() * RACE_SENTENCES.length)]);
    setCount(3);
    setPhase("countdown");
  };

  const reset = () => {
    setPhase("idle");
    setTyped("");
    setElapsed(0);
    setFinalTime(null);
    setDq(false);
    setPasteBust(false);
  };

  // Per-character correctness for visual feedback during typing
  const charStates = sentence.split("").map((ch, i) => {
    if (i >= typed.length) return "pending";
    return typed[i] === ch ? "ok" : "bad";
  });

  // Stats
  const userTime = finalTime ?? elapsed;
  const userWpm = userTime > 0 ? Math.round((RACE_WORDS / userTime) * 60) : 0;
  const correctChars = typed.split("").filter((c, i) => c === sentence[i]).length;
  const accuracy = typed.length > 0 ? Math.round((correctChars / typed.length) * 100) : 100;
  const finishedCorrectly = typed.trim() === sentence && !dq;

  const ninjaWpm = Math.round((RACE_WORDS / NINJA_SECONDS) * 60); // ~233 wpm
  const ninjaProgress = phase === "racing"
    ? Math.min(1, elapsed / NINJA_SECONDS)
    : phase === "done"
      ? 1
      : 0;
  const userProgress = phase === "racing" || phase === "done"
    ? Math.min(1, typed.length / sentence.length)
    : 0;

  const ninjaFinished = ninjaProgress >= 1;

  return (
    <section className="section speedbench" id="race">
      <div className="section-head">
        <div className="section-eyebrow">Speed challenge</div>
        <h2 className="section-title">Think you're fast? Race the ninja.</h2>
        <p className="section-sub">A small game with a rigged premise: speaking is just faster than typing. The ninja says the sentence below in about <strong>{NINJA_SECONDS}s</strong>. Your job is to type it. Good luck. You'll need it.</p>
      </div>

      <div className="race-stats" aria-label="typing versus speaking speed">
        <div className="race-stat">
          <div className="race-stat-num">45<span>wpm</span></div>
          <div className="race-stat-label">you, typing</div>
        </div>
        <div className="race-stat race-stat-accent">
          <div className="race-stat-num">200+<span>wpm</span></div>
          <div className="race-stat-label">you, speaking</div>
        </div>
        <div className="race-stat race-stat-verdict">
          <div className="race-stat-num">4×</div>
          <div className="race-stat-label">faster · zero typos</div>
        </div>
      </div>

      <div className="race-arena">
        {/* countdown overlay */}
        {phase === "countdown" && (
          <div className="race-countdown">
            <div className="race-countdown-num">{count === 0 ? "GO!" : count}</div>
            <div className="race-countdown-sub">get ready…</div>
          </div>
        )}

        {/* paste bust overlay */}
        {pasteBust && (
          <div className="race-paste-bust">
            <div className="paste-bust-card">
              <div className="paste-bust-emoji">🥷</div>
              <div className="paste-bust-title">Don't. You. Dare.</div>
              <div className="paste-bust-sub">The ninja saw that. Disqualified 😤</div>
            </div>
          </div>
        )}

        <div className="race-lanes">
          {/* NINJA LANE */}
          <div className={`race-lane ninja-lane ${ninjaFinished && phase !== "idle" ? "lane-winner" : ""}`}>
            <div className="race-lane-head">
              <div className="race-lane-name">
                <svg width="22" height="22" viewBox="0 0 60 60" className={phase === "racing" && !ninjaFinished ? "shuriken-spin" : ""} aria-hidden>
                  <g fill="var(--accent)" stroke="var(--ink)" strokeWidth="2" strokeLinejoin="round">
                    <path d="M30 4 L36 24 L56 30 L36 36 L30 56 L24 36 L4 30 L24 24 Z" />
                  </g>
                  <circle cx="30" cy="30" r="4" fill="var(--paper)" stroke="var(--ink)" strokeWidth="2" />
                </svg>
                Ninja Typer
              </div>
              <div className="race-lane-meta">{ninjaWpm} wpm · 100%</div>
            </div>

            <div className="race-track">
              <div className="race-track-fill smooth-fill" style={{ transform: `scaleX(${ninjaProgress})` }} />
              {/* sparkle trail */}
              {phase === "racing" && !ninjaFinished && (
                <div className="ninja-sparks" style={{ transform: `translateX(calc(${ninjaProgress * 100}cqw - 100%))` }}>
                  <span className="spark s1">✦</span>
                  <span className="spark s2">✧</span>
                  <span className="spark s3">✦</span>
                  <span className="spark s4">·</span>
                </div>
              )}
              <div className="race-track-runner smooth-runner" style={{ left: `${ninjaProgress * 100}%` }}>
                <svg width="38" height="38" viewBox="0 0 60 60" className={`ninja-star ${phase === "racing" && !ninjaFinished ? "ninja-star-spin" : ""}`} aria-hidden>
                  {/* Outer 8-point star */}
                  <g stroke="var(--ink)" strokeWidth="2" strokeLinejoin="round">
                    <path d="M30 2 L34 22 L52 10 L40 28 L58 30 L40 32 L52 50 L34 38 L30 58 L26 38 L8 50 L20 32 L2 30 L20 28 L8 10 L26 22 Z" fill="var(--accent)" />
                  </g>
                  {/* Inner rotating disk */}
                  <circle cx="30" cy="30" r="7" fill="var(--paper)" stroke="var(--ink)" strokeWidth="2" />
                  <circle cx="30" cy="30" r="2.5" fill="var(--ink)" />
                </svg>
              </div>
            </div>

            <div className="race-lane-status">
              {phase === "idle" && <span className="race-muted">waiting to race…</span>}
              {phase === "countdown" && <span className="race-muted">ready</span>}
              {phase === "racing" && !ninjaFinished && <span>dictating…</span>}
              {ninjaFinished && phase !== "idle" && (
                <span className="race-done">✓ done in {NINJA_SECONDS}s</span>
              )}
            </div>
          </div>

          {/* USER LANE */}
          <div className={`race-lane user-lane ${phase === "done" && finishedCorrectly && userTime < NINJA_SECONDS ? "lane-winner" : ""}`}>
            <div className="race-lane-head">
              <div className="race-lane-name">
                <svg width="22" height="22" viewBox="0 0 28 28" aria-hidden>
                  <rect x="3" y="8" width="22" height="14" rx="2" fill="var(--paper)" stroke="var(--ink)" strokeWidth="1.5" />
                  <rect x="6" y="11" width="3" height="3" rx="0.5" fill="var(--ink)" />
                  <rect x="11" y="11" width="3" height="3" rx="0.5" fill="var(--ink)" />
                  <rect x="16" y="11" width="3" height="3" rx="0.5" fill="var(--ink)" />
                  <rect x="21" y="11" width="3" height="3" rx="0.5" fill="var(--ink)" />
                  <rect x="6" y="16" width="16" height="3" rx="0.5" fill="var(--ink)" />
                </svg>
                You
              </div>
              <div className="race-lane-meta">
                {phase === "racing" || phase === "done"
                  ? `${userWpm} wpm · ${accuracy}%`
                  : "avg person: 45 wpm"}
              </div>
            </div>

            <div className="race-track">
              <div className="race-track-fill user-fill smooth-fill" style={{ transform: `scaleX(${userProgress})` }} />
              <div className="race-track-runner smooth-runner" style={{ left: `${userProgress * 100}%` }}>
                <svg width="30" height="30" viewBox="0 0 28 28" className="kbd-runner" aria-hidden>
                  <rect x="3" y="8" width="22" height="14" rx="2" fill="var(--paper)" stroke="var(--ink)" strokeWidth="1.5" />
                  <rect x="6" y="11" width="3" height="3" rx="0.5" fill="var(--ink)" />
                  <rect x="11" y="11" width="3" height="3" rx="0.5" fill="var(--ink)" />
                  <rect x="16" y="11" width="3" height="3" rx="0.5" fill="var(--ink)" />
                  <rect x="21" y="11" width="3" height="3" rx="0.5" fill="var(--ink)" />
                  <rect x="6" y="16" width="16" height="3" rx="0.5" fill="var(--ink)" />
                </svg>
              </div>
            </div>

            <div className="race-lane-status">
              {phase === "idle" && <span className="race-muted">click Go to start</span>}
              {phase === "countdown" && <span className="race-muted">fingers at the ready…</span>}
              {phase === "racing" && <span className="race-live">⏱ {elapsed.toFixed(1)}s</span>}
              {phase === "done" && finishedCorrectly && <span className="race-done">✓ finished in {userTime.toFixed(1)}s</span>}
              {phase === "done" && dq && <span className="race-muted">disqualified · {userTime.toFixed(1)}s</span>}
              {phase === "done" && !finishedCorrectly && !dq && <span className="race-muted">gave up at {userTime.toFixed(1)}s</span>}
            </div>
          </div>
        </div>

        {/* Sentence display with per-char highlighting */}
        <div className="race-prompt">
          <div className="race-prompt-label">Type this sentence · no pasting, ninja's watching 👁️</div>
          <div className="race-prompt-text">
            {sentence.split("").map((ch, i) => (
              <span key={i} className={`race-char race-char-${charStates[i]}`}>{ch}</span>
            ))}
          </div>

          <input
            ref={inputRef}
            type="text"
            className="race-input"
            value={typed}
            onChange={onType}
            onPaste={onPaste}
            disabled={phase !== "racing"}
            placeholder={phase === "racing" ? "start typing…" : "press Go to race"}
            autoComplete="off"
            spellCheck="false"
          />
        </div>

        {/* Scoreboard — visible when done */}
        {phase === "done" && (
          <div className="race-scoreboard">
            <div className={`score-card ${ninjaFinished && (userTime > NINJA_SECONDS || dq) ? "score-winner" : ""}`}>
              <div className="score-badge">🥷 Ninja</div>
              <div className="score-time">{NINJA_SECONDS}s</div>
              <div className="score-wpm">{ninjaWpm} wpm</div>
              <div className="score-acc">100% accuracy</div>
            </div>
            <div className="score-vs">vs.</div>
            <div className={`score-card ${userTime < NINJA_SECONDS && finishedCorrectly ? "score-winner" : ""}`}>
              <div className="score-badge">⌨️ You</div>
              <div className="score-time">{dq ? "DQ" : `${userTime.toFixed(1)}s`}</div>
              <div className="score-wpm">{dq ? "—" : `${userWpm} wpm`}</div>
              <div className="score-acc">{dq ? "caught pasting 👀" : `${accuracy}% accuracy`}</div>
            </div>

            <div className="race-verdict">
              {dq && (
                <>Caught you. The ninja doesn't paste, it <em>speaks</em>. Run it back, honestly this time.</>
              )}
              {!dq && finishedCorrectly && userTime < NINJA_SECONDS && (
                <>🎉 You beat the ninja by <strong>{(NINJA_SECONDS - userTime).toFixed(1)}s</strong>. Are you… also a ninja?</>
              )}
              {!dq && finishedCorrectly && userTime >= NINJA_SECONDS && (
                <>The ninja won by <strong>{(userTime - NINJA_SECONDS).toFixed(1)}s</strong>. That's <strong>{(userTime / NINJA_SECONDS).toFixed(1)}×</strong> faster, hands-free, zero typos, and emotionally unavailable.</>
              )}
              {!dq && !finishedCorrectly && (
                <>The ninja already finished, {NINJA_SECONDS}s flat, and started meditating. Rematch?</>
              )}
            </div>
          </div>
        )}

        {/* Controls */}
        <div className="race-controls">
          {phase === "idle" && (
            <button className="btn btn-primary btn-large" onClick={start}>
              Go. Race the ninja.
              <svg width="14" height="14" viewBox="0 0 14 14" fill="none" aria-hidden>
                <path d="M3 7h8M7 3l4 4-4 4" stroke="currentColor" strokeWidth="1.8" strokeLinecap="round" strokeLinejoin="round"/>
              </svg>
            </button>
          )}
          {phase === "countdown" && (
            <button className="btn btn-ghost btn-large" onClick={reset}>cancel</button>
          )}
          {phase === "racing" && (
            <button className="btn btn-ghost btn-large" onClick={() => finish(elapsed, typed)}>give up</button>
          )}
          {phase === "done" && (
            <>
              <button className="btn btn-primary btn-large" onClick={start}>rematch</button>
              <button className="btn btn-ghost btn-large" onClick={reset}>reset</button>
            </>
          )}
        </div>
      </div>
    </section>
  );
}

Object.assign(window, { Manifesto, Privacy, SpeedBench });
