/* global React */
const { useState, useEffect, useRef } = React;

// ============= TERMINAL TYPE EFFECT =========================================
function TerminalType({ code }) {
  // code like "FN-2025" → render as "FN_2025" with FN_20 white, 25 orange
  const text = (code || "").replace("-", "_");
  const splitAt = Math.max(0, text.length - 2);
  const [n, setN] = useState(0);
  useEffect(() => {
    setN(0);
    let i = 0;
    const id = setInterval(() => {
      i++;
      setN(i);
      if (i >= text.length) clearInterval(id);
    }, 140);
    return () => clearInterval(id);
  }, [text]);
  const head = text.slice(0, Math.min(n, splitAt));
  const tail = n > splitAt ? text.slice(splitAt, n) : "";
  return (
    <span className="term-type">
      <span className="term-head">{head}</span>
      <span className="term-tail accent">{tail}</span>
      <span className="term-caret" aria-hidden="true"></span>
    </span>
  );
}

// ============= GALLERY DATA =================================================
// Each year is a self-contained archive: a "feature" video, a strip of reels,
// and a curated mosaic of photos. Replace `src` values with real media when
// it lands; the placeholder branches render automatically when src is null.
// The mosaic `span` keys map to .gv-tile.s-* classes in gallery-styles.css.

const GALLERY_DATA = {
  "2025": {
    code: "FN-2025",
    eyebrow: "ARCHIVE · YEAR 02",
    title: ["YEAR", "TWO."],
    sub: "Fight Night 2025 · 8 teams · 12 bots · 14 bouts · Dogpatch Labs, Dublin.",
    meta: ["DATE 15.11.2025", "TEAMS 08", "BOUTS 14", "ATTEND 240"],
    feature: {
      src: null, // drop a video URL or local path here
      poster: "assets/photo-arena-wide.png",
      title: "FN-2025 · The Recap",
      runtime: "06:42",
      caption: "Six minutes inside the arena — qualifiers, finals, the smoke.",
      tag: "OFFICIAL CUT"
    },
    reels: [
      { id: "FN25-R-01", label: "Final · KO at 0:48", dur: "0:48", src: null, poster: null },
      { id: "FN25-R-02", label: "Chainsaw spec demo", dur: "1:12", src: null, poster: null },
      { id: "FN25-R-03", label: "Pit walk-thru", dur: "0:36", src: null, poster: null },
      { id: "FN25-R-04", label: "Crowd · semis", dur: "0:22", src: null, poster: null },
      { id: "FN25-R-05", label: "Tech check · BLUE-EYE", dur: "0:54", src: null, poster: null },
      { id: "FN25-R-06", label: "Trophy · winners", dur: "0:31", src: null, poster: null }
    ],
    photos: [
      { src: "assets/photo-arena-wide.png",     id: "FN25-001", label: "Bout 04 · Arena Centre",     span: "s-hero" },
      { src: "assets/photo-bot-eyes.png",       id: "FN25-002", label: "BLUE-EYE · Inspection",      span: "s-tall" },
      { src: "assets/photo-chainsaw.png",       id: "FN25-003", label: "Weapon Spec · Chainsaw",     span: "s-sq"   },
      { src: "assets/photo-controller.png",     id: "FN25-004", label: "Pilot Box · Bout 07",        span: "s-sm"   },
      { src: "assets/photo-bot-blue.png",       id: "FN25-005", label: "Drive Train · Pre-bout",     span: "s-sm"   },
      { src: "assets/photo-arena-overview.png", id: "FN25-006", label: "Arena Overview · 16:00",     span: "s-wide" },
      { src: "assets/photo-team.png",           id: "FN25-007", label: "Team Floor · Demo Day",      span: "s-sq"   },
      { src: "assets/photo-smoke.png",          id: "FN25-008", label: "Bout 09 · Smoke",            span: "s-sm"   },
      { src: "assets/photo-controller-2.png",   id: "FN25-009", label: "Pilot · Hands",              span: "s-stub" },
      { src: "assets/photo-ducks.png",          id: "FN25-010", label: "Off-shift · Ducks",          span: "s-stub" },
      // additional placeholder slots for new uploads
      { src: null, id: "FN25-011", label: "(empty slot)", span: "s-stub" },
      { src: null, id: "FN25-012", label: "(empty slot)", span: "s-stub" }
    ]
  },
  "2024": {
    code: "FN-2024",
    eyebrow: "ARCHIVE · YEAR 01",
    title: ["YEAR", "ONE."],
    sub: "Fight Night 2024 · the inaugural night · 5 teams · proof of concept.",
    meta: ["DATE 20.10.2024", "TEAMS 05", "BOUTS 09", "ATTEND 140"],
    feature: {
      src: null,
      poster: null,
      title: "FN-2024 · How It Started",
      runtime: "04:18",
      caption: "Year one. Smaller crowd, smaller bots, same noise.",
      tag: "ORIGIN CUT"
    },
    reels: [
      { id: "FN24-R-01", label: "First match · ever", dur: "1:02", src: null, poster: null },
      { id: "FN24-R-02", label: "Build day · garage", dur: "0:44", src: null, poster: null },
      { id: "FN24-R-03", label: "Final · winners' lap", dur: "0:38", src: null, poster: null },
      { id: "FN24-R-04", label: "Sparks · b-roll", dur: "0:18", src: null, poster: null },
      { id: "FN24-R-05", label: "Audience reaction", dur: "0:24", src: null, poster: null },
      { id: "FN24-R-06", label: "Closing remarks", dur: "0:51", src: null, poster: null }
    ],
    photos: [
      { src: null, id: "FN24-001", label: "Inaugural arena · wide",     span: "s-hero" },
      { src: null, id: "FN24-002", label: "Team Origin · pit crew",     span: "s-tall" },
      { src: null, id: "FN24-003", label: "First weapon · drum",        span: "s-sq"   },
      { src: null, id: "FN24-004", label: "Crowd · opening",            span: "s-sm"   },
      { src: null, id: "FN24-005", label: "Bot inspection",             span: "s-sm"   },
      { src: null, id: "FN24-006", label: "Bout 03 · winning hit",      span: "s-wide" },
      { src: null, id: "FN24-007", label: "Pilot box · year one",       span: "s-sq"   },
      { src: null, id: "FN24-008", label: "Trophy reveal",              span: "s-sm"   },
      { src: null, id: "FN24-009", label: "Off-shift · build",          span: "s-stub" },
      { src: null, id: "FN24-010", label: "Sponsor wall · year one",    span: "s-stub" },
      { src: null, id: "FN24-011", label: "(empty slot)",                span: "s-stub" },
      { src: null, id: "FN24-012", label: "(empty slot)",                span: "s-stub" }
    ]
  }
};

// ============= GALLERY HUB ==================================================
function GalleryPage() {
  return (
    <div className="gv-page" data-screen-label="Gallery">
      <header className="gv-hero">
        <div className="gv-hero-eyebrow"><span className="pip"></span>▸ ARCHIVE · TWO YEARS ON RECORD</div>
        <h1>PROOF<br /><span className="accent">ON RECORD.</span></h1>
        <p className="gv-hero-sub">
          Two Fight Nights, two folders. Photos from the floor, video from the
          pit. Pick a year.
        </p>
        <div className="gv-hero-meta">
          <span><span className="dot"></span>FN-2024 · 05 TEAMS</span>
          <span><span className="dot"></span>FN-2025 · 08 TEAMS</span>
          <span><span className="dot"></span>FN-2026 · TBA</span>
        </div>
      </header>

      <section className="gv-eras">
        <a className="gv-era" href="#/gallery/2025" data-screen-label="Era · FN-2025">
          <div className="gv-era-cover" style={{backgroundImage: "url(assets/photo-arena-wide.png)"}}></div>
          <div className="gv-era-overlay"></div>
          <div className="gv-era-meta">
            <span className="id">FN-2025</span>
            <span>YEAR 02 · LATEST</span>
          </div>
          <div className="gv-era-body">
            <h2 className="gv-era-year"><span className="em">2025</span></h2>
            <div className="gv-era-tag">The Year Two Cut</div>
            <div className="gv-era-stats">
              <span>TEAMS <span className="v">08</span></span>
              <span>BOUTS <span className="v">14</span></span>
              <span>ATTEND <span className="v">240</span></span>
            </div>
            <span className="gv-era-cta">OPEN ARCHIVE →</span>
          </div>
        </a>

        <a className="gv-era amber" href="#/gallery/2024" data-screen-label="Era · FN-2024">
          <div className="gv-era-cover placeholder"></div>
          <div className="gv-era-overlay"></div>
          <div className="gv-era-meta">
            <span className="id">FN-2024</span>
            <span>YEAR 01 · ORIGIN</span>
          </div>
          <div className="gv-era-body">
            <h2 className="gv-era-year"><span className="em">2024</span></h2>
            <div className="gv-era-tag">How It Started</div>
            <div className="gv-era-stats">
              <span>TEAMS <span className="v">05</span></span>
              <span>BOUTS <span className="v">09</span></span>
              <span>ATTEND <span className="v">140</span></span>
            </div>
            <span className="gv-era-cta">OPEN ARCHIVE →</span>
          </div>
        </a>
      </section>
    </div>
  );
}

// ============= GALLERY YEAR PAGE ============================================
function GalleryYearPage({ year }) {
  const data = GALLERY_DATA[year] || GALLERY_DATA["2025"];
  const [lb, setLb] = useState(null); // index into data.photos

  useEffect(() => {
    if (lb === null) return;
    const onKey = (e) => {
      const n = data.photos.length;
      if (e.key === "Escape") setLb(null);
      else if (e.key === "ArrowRight") setLb((i) => (i + 1) % n);
      else if (e.key === "ArrowLeft") setLb((i) => (i - 1 + n) % n);
    };
    window.addEventListener("keydown", onKey);
    return () => window.removeEventListener("keydown", onKey);
  }, [lb, data]);

  const f = data.feature;

  return (
    <div className="gv-page" data-screen-label={`Gallery · ${data.code}`}>
      <header className="gv-hero gv-hero-split">
        <div className="gv-hero-left">
          <div className="gv-hero-eyebrow"><span className="pip"></span>▸ {data.eyebrow}</div>
          <h1 className="gv-hero-term">
            <TerminalType code={data.code} />
          </h1>
          <p className="gv-hero-sub">{data.sub}</p>
        </div>
        <div className="gv-hero-meta gv-hero-meta-stack">
          {data.meta.map((m, i) => <span key={i}><span className="dot"></span>{m}</span>)}
        </div>
      </header>

      <div className="gv-year">

        {/* ── Featured video ─────────────────────────────────────── */}
        <section className="gv-feature">
          <div className="gv-feature-tag">
            <span><span className="em">▸ FEATURE</span> · {f.tag}</span>
            <span className="amber">● {data.code}</span>
          </div>
          <div className="gv-video">
            {f.src ? (
              <video
                src={f.src}
                poster={f.poster || undefined}
                controls
                playsInline
                preload="metadata"
              />
            ) : (
              <div className="placeholder-fill" style={f.poster ? {
                background: `linear-gradient(rgba(0,0,0,0.55), rgba(0,0,0,0.55)), url(${f.poster}) center/cover`
              } : undefined}>
                <div className="play-icon"></div>
                <span className="label">▸ VIDEO PENDING · {f.title}</span>
                <span className="ts">{f.runtime}</span>
              </div>
            )}
          </div>
          <div className="gv-feature-cap">
            <span className="ttl">{f.title}</span>
            <span>{f.caption} · {f.runtime}</span>
          </div>
        </section>

        {/* ── Reels strip ────────────────────────────────────────── */}
        <section className="gv-reels">
          <div className="gv-reels-head">
            <span><span className="em">▸ REELS</span> · CLIPS &amp; CUTS</span>
            <span>{String(data.reels.length).padStart(2,'0')} ITEMS</span>
          </div>
          <div className="gv-reels-grid">
            {data.reels.map((r, i) => (
              <div key={i} className="gv-reel">
                {r.src ? (
                  <video src={r.src} poster={r.poster || undefined} muted playsInline preload="metadata" />
                ) : r.poster ? (
                  <img src={r.poster} alt={r.label} loading="lazy" />
                ) : (
                  <div className="reel-cover">
                    <div className="play"></div>
                  </div>
                )}
                <div className="reel-meta">
                  <span className="dur">{r.dur}</span>
                  <span className="id">{r.id}</span>
                  <span>{r.label}</span>
                </div>
              </div>
            ))}
          </div>
        </section>

        {/* ── Photo mosaic ───────────────────────────────────────── */}
        <section className="gv-photos">
          <div className="gv-photos-head">
            <span><span className="em">▸ PHOTOS</span> · CURATED</span>
            <span className="amber">{String(data.photos.length).padStart(3,'0')} FRAMES ON RECORD</span>
          </div>
          <div className="gv-mosaic">
            {data.photos.map((p, i) => (
              <button key={i} className={`gv-tile ${p.span}`} onClick={() => p.src && setLb(i)}>
                {p.src ? (
                  <img src={p.src} alt={p.label} loading="lazy" />
                ) : (
                  <div className="placeholder-fill">▸ FRAME PENDING</div>
                )}
                <span className="tile-id">{p.id}</span>
                <span className="tile-label">{p.label}</span>
              </button>
            ))}
          </div>
          <div className="gv-mosaic-foot">
            ▸ END OF {data.code} · MORE FRAMES TO LAND
          </div>
        </section>
      </div>

      {lb !== null && data.photos[lb] && data.photos[lb].src && (
        <div className="gv-lb" onClick={() => setLb(null)}>
          <div className="gv-lb-frame" onClick={(e) => e.stopPropagation()}>
            <div className="gv-lb-head">
              <span><span className="em">FRAME</span> · {data.photos[lb].id}</span>
              <span>{String(lb + 1).padStart(3,'0')} / {String(data.photos.length).padStart(3,'0')}</span>
            </div>
            <div className="gv-lb-body">
              <img src={data.photos[lb].src} alt={data.photos[lb].label} />
            </div>
            <div className="gv-lb-foot">
              <span>{data.photos[lb].label}</span>
              <div className="gv-lb-nav">
                <button onClick={() => setLb((i) => (i - 1 + data.photos.length) % data.photos.length)}>←</button>
                <button onClick={() => setLb((i) => (i + 1) % data.photos.length)}>→</button>
                <button className="gv-lb-close" onClick={() => setLb(null)}>[ ESC ] CLOSE</button>
              </div>
            </div>
          </div>
        </div>
      )}
    </div>
  );
}

// ============= REGISTER INTEREST FORM =============
function RegisterInterestForm({ compact }) {
  const [first, setFirst] = useState("");
  const [email, setEmail] = useState("");
  const [build, setBuild] = useState("");
  const [state, setState] = useState("idle"); // idle | submitting | done | error

  const submit = async (e) => {
    e.preventDefault();
    if (!email || !first) return;
    setState("submitting");
    try {
      await window.__pwSubmitForm({
        name: first,
        email,
        build_idea: build || "(none provided)",
        source: "register-interest-form",
        page: typeof window !== "undefined" ? window.location.hash || "/" : "",
      }, "FN-2026 · Register Interest (full form)");
      setState("done");
    } catch (err) {
      setState("error");
    }
  };

  if (state === "done") {
    return (
      <div className={`ri-form ri-done ${compact ? "compact" : ""}`}>
        <div className="ri-form-head">
          <span>INTAKE.SH · CONFIRMED</span>
          <span className="amber">● 200 OK</span>
        </div>
        <div className="ri-done-body">
          <p>[ OK ] interest registered · check your inbox</p>
          <p>we'll mail you when applications open.</p>
          <p className="dim">// {first.toUpperCase()} · {email}</p>
        </div>
      </div>);

  }

  return (
    <form
      className={`ri-form ${compact ? "compact" : ""}`}
      onSubmit={submit}
      data-action="register-interest">
      
      <div className="ri-form-head">
        <span>INTAKE.SH · REGISTER INTEREST</span>
        <span className={state === "submitting" ? "amber" : "ok"}>
          {state === "submitting" ? "● TRANSMITTING" : "● READY"}
        </span>
      </div>

      <label className="ri-row">
        <span className="ri-prompt">Name ></span>
        <input
          className="ri-input"
          autoComplete="given-name"
          value={first}
          onChange={(e) => setFirst(e.target.value)}
          placeholder="ELIZA"
          required />
        
      </label>

      <label className="ri-row">
        <span className="ri-prompt">Email ></span>
        <input
          className="ri-input"
          autoComplete="email"
          type="email"
          value={email}
          onChange={(e) => setEmail(e.target.value)}
          placeholder="you@domain.ie"
          required />
        
      </label>

      <label className="ri-row">
        <span className="ri-prompt">Build ></span>
        <input
          className="ri-input"
          value={build}
          onChange={(e) => setBuild(e.target.value)}
          placeholder="(optional) one line — what would you build?"
          maxLength={120} />
        
      </label>

      <div className="ri-actions">
        <button type="submit" className="btn btn-primary" disabled={state === "submitting"}>
          {state === "submitting" ? "TRANSMITTING…" : "SUBMIT →"}
        </button>
        <span className="ri-fineprint">No spam. We'll mail you when applications open.</span>
      </div>
      {state === "error" && (
        <div className="ri-error" role="alert">
          [ ERR ] couldn't transmit — try again, or email hello@patchrobowars.ie.
        </div>
      )}
    </form>);

}

function RegisterInterestInline({ openInterest }) {
  return (
    <div className="ri-inline">
      <div className="section-block-eyebrow">▸ REGISTER INTEREST</div>
      <h2 className="section-block-title">PUT YOURSELF<br /><span className="accent">ON THE LIST.</span></h2>
      <p className="long-prose" style={{ maxWidth: 600 }}>
        Drop your email. When applications open on 01 Jun 2026, you'll be the
        first to know. No spam. No form-stuffing.
      </p>
      <div className="ri-inline-cta">
        <window.HeroNotifyField />
      </div>
    </div>);

}

function RegisterPage() {
  return (
    <div className="page" data-screen-label="Register">
      <header className="page-hero">
        <div className="page-hero-eyebrow">▸ INTAKE PRE-LIST · FN-2026</div>
        <h1 className="page-hero-title">REGISTER<br /><span className="accent">INTEREST.</span></h1>
        <p className="page-hero-sub">
          We'll email you the moment applications go live. That's it.
        </p>
      </header>
      <section className="section-block" style={{ paddingTop: 32 }}>
        <RegisterInterestForm />
      </section>
    </div>);

}

// ============= INTEREST MODAL =============
function InterestModal({ open, onClose }) {
  useEffect(() => {
    if (!open) return;
    const onKey = (e) => {if (e.key === "Escape") onClose();};
    window.addEventListener("keydown", onKey);
    document.body.style.overflow = "hidden";
    return () => {
      window.removeEventListener("keydown", onKey);
      document.body.style.overflow = "";
    };
  }, [open, onClose]);

  if (!open) return null;
  return (
    <div className="ri-modal" onClick={onClose}>
      <div className="ri-modal-frame" onClick={(e) => e.stopPropagation()}>
        <button className="ri-modal-close" onClick={onClose} aria-label="Close">[ ESC ] CLOSE</button>
        <div className="ri-modal-eyebrow">▸ REGISTER INTEREST · FN-2026</div>
        <h2 className="ri-modal-title">PUT YOURSELF ON THE LIST.</h2>
        <p className="ri-modal-blurb">
          Drop your email. We'll mail you the second applications open on 01 Jun 2026.
        </p>
        <window.HeroNotifyField />
      </div>
    </div>);

}

Object.assign(window, {
  GalleryPage,
  GalleryYearPage,
  RegisterPage,
  RegisterInterestForm,
  RegisterInterestInline,
  InterestModal
});