/* Retro CRT-TV preloader.
   Three states:
     OFF      → TV bezel with glowing PLAY button. User clicks to start.
     POWER_ON → quick power-on flash, brief static, channel flip
     STORY    → typewriter narration over scanlines, then fade-out reveals page.
   Persists in sessionStorage so it only plays once per visit. */

const { useState, useEffect, useRef } = React;

const STORY_LINES = [
  "// FILE 014 — YOKOHAMA, 19:42",
  "",
  "Tonight, the harbor is louder than usual.",
  "Bandages on the wrist. Cigarette in the rain.",
  "",
  "Somewhere between agency and port mafia,",
  "a port engineer signs another commit.",
  "",
  "His ability is called \"shipping it.\"",
  "It nullifies any system that meets him.",
  "",
  "// PRESS ANY KEY TO CONTINUE..."
];

function Preloader() {
  const [phase, setPhase] = useState("off"); // off | on | story | done
  const [storyIdx, setStoryIdx] = useState(0);
  const [storyChar, setStoryChar] = useState(0);
  const audioRef = useRef(null);
  const knobRef = useRef(null);

  // Skip preloader entirely if already shown this session
  useEffect(() => {
    try {
      if (sessionStorage.getItem("preloader-seen") === "1") {
        setPhase("done");
        document.body.classList.remove("preloader-active");
      } else {
        document.body.classList.add("preloader-active");
      }
    } catch (e) {
      document.body.classList.add("preloader-active");
    }
    // Mark mounted so the inline FOUC shield can hide
    document.body.classList.add("preloader-mounted");
  }, []);

  // Esc / any key skips
  useEffect(() => {
    if (phase === "off") {
      const onKey = (e) => {
        if (e.key === "Enter" || e.key === " ") { e.preventDefault(); start(); }
      };
      window.addEventListener("keydown", onKey);
      return () => window.removeEventListener("keydown", onKey);
    }
    if (phase === "done") return;
    const onKey = (e) => {
      if (e.key === "Escape" || phase === "story") finish();
    };
    window.addEventListener("keydown", onKey);
    return () => window.removeEventListener("keydown", onKey);
  }, [phase]);

  // Power-on sequence
  useEffect(() => {
    if (phase !== "on") return;
    const t1 = setTimeout(() => setPhase("story"), 1400);
    return () => clearTimeout(t1);
  }, [phase]);

  // Typewriter for story
  useEffect(() => {
    if (phase !== "story") return;
    if (storyIdx >= STORY_LINES.length) {
      const t = setTimeout(finish, 1800);
      return () => clearTimeout(t);
    }
    const line = STORY_LINES[storyIdx];
    if (storyChar < line.length) {
      const speed = line.startsWith("//") ? 22 : (line === "" ? 0 : 32);
      const t = setTimeout(() => setStoryChar(c => c + 1), speed + Math.random() * 18);
      return () => clearTimeout(t);
    } else {
      const pause = line === "" ? 120 : (line.startsWith("//") ? 600 : 380);
      const t = setTimeout(() => {
        setStoryIdx(i => i + 1);
        setStoryChar(0);
      }, pause);
      return () => clearTimeout(t);
    }
  }, [phase, storyIdx, storyChar]);

  function start() {
    setPhase("on");
    // tiny click sound via WebAudio (no asset needed)
    try {
      const ctx = new (window.AudioContext || window.webkitAudioContext)();
      const o = ctx.createOscillator();
      const g = ctx.createGain();
      o.type = "square";
      o.frequency.value = 80;
      g.gain.value = 0.08;
      o.connect(g); g.connect(ctx.destination);
      o.start();
      o.frequency.exponentialRampToValueAtTime(2400, ctx.currentTime + 0.15);
      g.gain.exponentialRampToValueAtTime(0.0001, ctx.currentTime + 0.4);
      o.stop(ctx.currentTime + 0.4);
    } catch (e) {}
    // knob spin
    if (knobRef.current) knobRef.current.classList.add("spin");
  }

  function finish() {
    setPhase("done");
    try { sessionStorage.setItem("preloader-seen", "1"); } catch (e) {}
    setTimeout(() => {
      document.body.classList.remove("preloader-active");
    }, 700);
  }

  function skip(e) {
    e.stopPropagation();
    finish();
  }

  if (phase === "done") return null;

  return (
    <div className={"preloader phase-" + phase}>
      <div className="pre-room">
        {/* wallpaper grain + vignette done in CSS */}
        <div className="pre-tv-set">
          <div className="pre-tv-bezel">
            {/* top brand strip */}
            <div className="pre-brand">
              <span className="pre-brand-name">YOKOHAMA / 太宰 — 014</span>
              <span className="pre-brand-led"></span>
            </div>

            {/* the screen */}
            <div className="pre-screen-wrap">
              <div className="pre-screen">
                <div className="pre-curve"></div>
                <div className="pre-scanlines"></div>
                <div className="pre-noise"></div>
                <div className="pre-vignette"></div>

                {phase === "off" && (
                  <button className="pre-off" onClick={start} aria-label="Begin transmission">
                    {/* SMPTE-style film leader countdown card */}
                    <div className="pre-off-grid"></div>
                    <div className="pre-off-crosshair">
                      <span className="ch-h"></span>
                      <span className="ch-v"></span>
                      <span className="ch-tl"></span><span className="ch-tr"></span>
                      <span className="ch-bl"></span><span className="ch-br"></span>
                    </div>

                    {/* corner ticks */}
                    <div className="pre-off-corner tl">SMPTE · 太宰<br/><span>YOKOHAMA-14</span></div>
                    <div className="pre-off-corner tr">REEL 014<br/><span>1909 — 1948</span></div>
                    <div className="pre-off-corner bl">ASPECT 4:3<br/><span>NTSC · MONO</span></div>
                    <div className="pre-off-corner br">ARCHIVE<br/><span>NO LONGER HUMAN</span></div>

                    {/* center: countdown numeral + sigil */}
                    <div className="pre-off-center">
                      <div className="pre-off-numeral">
                        <span className="num">14</span>
                        <span className="ring r1"></span>
                        <span className="ring r2"></span>
                        <span className="ring r3"></span>
                      </div>
                      <div className="pre-off-jp">太宰治<span className="ko">— ファイル ＃０１４ —</span></div>
                    </div>

                    {/* bottom standby plate */}
                    <div className="pre-off-plate">
                      <span className="plate-led"></span>
                      <span className="plate-text">PRESS PLAY TO BEGIN TRANSMISSION</span>
                      <span className="plate-key">▸ ENTER</span>
                    </div>

                    {/* faint "STANDBY" diagonal stamp */}
                    <div className="pre-off-stamp">STAND BY</div>
                  </button>
                )}

                {phase === "on" && (
                  <div className="pre-on">
                    <div className="pre-flash"></div>
                    <div className="pre-static"></div>
                    <div className="pre-hline"></div>
                  </div>
                )}

                {phase === "story" && (
                  <div className="pre-story">
                    <div className="pre-story-head">
                      <span className="pre-rec">●REC</span>
                      <span className="pre-tape">SP · 00:14:32</span>
                      <span className="pre-tape right">CH 14</span>
                    </div>
                    <div className="pre-story-body">
                      {STORY_LINES.slice(0, storyIdx + 1).map((line, i) => {
                        const text = i === storyIdx ? line.slice(0, storyChar) : line;
                        const isMeta = line.startsWith("//");
                        return (
                          <div key={i} className={"pre-line" + (isMeta ? " meta" : "") + (line === "" ? " blank" : "")}>
                            {text}
                            {i === storyIdx && storyChar < line.length && <span className="pre-caret">▍</span>}
                          </div>
                        );
                      })}
                    </div>
                  </div>
                )}
              </div>
            </div>

            {/* control panel under the screen */}
            <div className="pre-controls">
              <div className="pre-knob-group">
                <div className="pre-knob" ref={knobRef}>
                  <span className="pre-knob-tick"></span>
                </div>
                <span className="pre-knob-label">CH</span>
              </div>
              <div className="pre-vu">
                <div className="pre-vu-bars">
                  {Array.from({length: 14}).map((_, i) => (
                    <span key={i} style={{animationDelay: (i * 60) + "ms"}}></span>
                  ))}
                </div>
                <span className="pre-vu-label">VU</span>
              </div>
              <div className="pre-knob-group">
                <div className="pre-knob small">
                  <span className="pre-knob-tick"></span>
                </div>
                <span className="pre-knob-label">VOL</span>
              </div>
            </div>
          </div>

          {/* TV legs */}
          <div className="pre-legs">
            <span></span><span></span>
          </div>
        </div>

        {/* skip button */}
        {phase !== "off" && (
          <button className="pre-skip" onClick={skip}>SKIP INTRO →</button>
        )}

        {/* footer marquee-y caption */}
        <div className="pre-caption">
          <span>NO LONGER HUMAN · 走れメロス · 太宰治 · ARCHIVE 14</span>
          <span>NO LONGER HUMAN · 走れメロス · 太宰治 · ARCHIVE 14</span>
        </div>
      </div>
    </div>
  );
}

/* Mount immediately — own React root, separate from main app */
(function mountPreloader() {
  const host = document.createElement("div");
  host.id = "preloader-root";
  document.body.appendChild(host);
  ReactDOM.createRoot(host).render(<Preloader />);
})();
