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

/* ---------- hooks ---------- */
function useScrolled(threshold = 40) {
  const [s, setS] = useState(false);
  useEffect(() => {
    const on = () => setS(window.scrollY > threshold);
    on();
    window.addEventListener("scroll", on, { passive: true });
    return () => window.removeEventListener("scroll", on);
  }, [threshold]);
  return s;
}

function useReveal() {
  useEffect(() => {
    const els = document.querySelectorAll(".reveal:not(.in)");
    if (!("IntersectionObserver" in window)) {
      els.forEach((e) => e.classList.add("in"));
      return;
    }
    const io = new IntersectionObserver(
      (entries) => {
        entries.forEach((en) => {
          if (en.isIntersecting) {
            en.target.classList.add("in");
            io.unobserve(en.target);
          }
        });
      },
      { threshold: 0.16, rootMargin: "0px 0px -8% 0px" }
    );
    els.forEach((e) => io.observe(e));
    return () => io.disconnect();
  });
}

// parallax: translateY a ref based on scroll, gated by motion
function useParallax(ref, factor, motion) {
  useEffect(() => {
    if (!motion) {
      if (ref.current) ref.current.style.transform = "";
      return;
    }
    let raf = 0;
    const apply = () => {
      raf = 0;
      if (ref.current) ref.current.style.transform = `translate3d(0, ${window.scrollY * factor}px, 0)`;
    };
    const on = () => { if (!raf) raf = requestAnimationFrame(apply); };
    apply();
    window.addEventListener("scroll", on, { passive: true });
    return () => { window.removeEventListener("scroll", on); cancelAnimationFrame(raf); };
  }, [ref, factor, motion]);
}

/* ---------- background ---------- */
function Particles({ motion }) {
  const items = React.useMemo(
    () =>
      Array.from({ length: 26 }, (_, i) => ({
        id: i,
        left: Math.random() * 100,
        size: 1 + Math.random() * 2.5,
        dur: 14 + Math.random() * 26,
        delay: -Math.random() * 30,
      })),
    []
  );
  if (!motion) return null;
  return (
    <div className="particles" aria-hidden="true">
      {items.map((p) => (
        <span
          key={p.id}
          className="particle"
          style={{
            left: p.left + "%",
            bottom: "-10px",
            width: p.size + "px",
            height: p.size + "px",
            animationDuration: p.dur + "s",
            animationDelay: p.delay + "s",
          }}
        />
      ))}
    </div>
  );
}

/* ---------- nav ---------- */
function Nav() {
  const scrolled = useScrolled();
  const D = window.JCROS;
  return (
    <nav className={"nav" + (scrolled ? " scrolled" : "")}>
      <div className="nav-inner">
        <a className="wordmark" href="#top" aria-label="jcros.ai home">
          jcros<span className="dot">.</span><span className="ai">ai</span>
        </a>
        <div className="nav-links">
          {D.nav.map((n) => (
            <a key={n.href} className="nav-link" href={n.href}>{n.label}</a>
          ))}
        </div>
        <div className="nav-cta">
          <a className="nav-link" href="#play" style={{ display: "none" }}>x</a>
          <a className="btn btn-primary" href="#signup">
            Join the drop <span className="arrow">→</span>
          </a>
        </div>
      </div>
    </nav>
  );
}

/* ---------- hero (3 directions) ---------- */
function Hero({ direction, motion, title }) {
  const D = window.JCROS.hero;
  const imgRef = useRef(null);
  useParallax(imgRef, direction === "deep" ? 0.12 : 0.22, motion);

  // summit hero is a slow-motion video loop; other directions keep the still art
  const useVideo = direction === "summit";
  useEffect(() => {
    const el = imgRef.current;
    if (!useVideo || !el || el.tagName !== "VIDEO") return;
    const apply = () => {
      el.playbackRate = 0.3; // 120fps source → ~36fps perceived: slower + smoother
      if (motion) { const p = el.play(); if (p) p.catch(() => {}); }
      else el.pause();
    };
    apply();
    el.addEventListener("loadedmetadata", apply);
    return () => el.removeEventListener("loadedmetadata", apply);
  }, [useVideo, motion]);

  const words = title || D.title;
  const Title = (
    <h1 className="hero-title h-display">
      {words[0]} <span className="glow">{words[1]}</span>{" "}{words[2]}
    </h1>
  );

  const Actions = (
    <div className="hero-actions">
      <a className="btn btn-primary" href="#games">Explore the worlds <span className="arrow">→</span></a>
      <a className="btn btn-ghost" href="#engine">How it works</a>
    </div>
  );

  const img =
    direction === "peak" ? "assets/peak-moon.png" : "assets/explorer-ridge.png";

  return (
    <header className={"hero " + direction} id="top">
      <div className="hero-media">
        {useVideo ? (
          <video
            ref={imgRef}
            className="hero-img hero-video"
            src="assets/hero-loop.mp4"
            poster="assets/hero-poster.jpg"
            autoPlay
            loop
            muted
            playsInline
            aria-hidden="true"
          />
        ) : (
          <img ref={imgRef} className="hero-img" src={img} alt="" aria-hidden="true" />
        )}
        <div className="hero-scrim" />
      </div>

      {direction === "deep" && <div className="hero-orb" aria-hidden="true" />}

      <div className="hud hud-tl"><span className="tick" /> SYS://JCROS · WORLDGEN ONLINE</div>
      <div className="hud hud-br">SEED 0x{(direction === "peak" ? "A11A" : direction === "deep" ? "FFFF" : "7C3A")} · ∞</div>

      <div className="hero-content shell">
        <div className="hero-eyebrow"><span className="eyebrow">{D.eyebrow}</span></div>
        {Title}
        <p className="hero-sub">{D.sub}</p>
        {Actions}
      </div>

      {direction === "peak" && (
        <div className="hero-feature">
          <div className="game-genre" style={{ color: "var(--accent)" }}>NOW IN ALPHA</div>
          <div style={{ fontFamily: "var(--font-display)", fontWeight: 700, fontSize: 22, marginTop: 8 }}>The Crossing</div>
          <p style={{ color: "var(--muted)", fontSize: 13, marginTop: 8 }}>An infinite novel you play. One story, endless paths.</p>
        </div>
      )}

      <div className="scroll-cue"><span>scroll</span><span className="bar" /></div>
    </header>
  );
}

/* ---------- mission ---------- */
function Mission() {
  const M = window.JCROS.mission;
  return (
    <section className="section mission" id="studio">
      <div className="shell">
        <div className="reveal" style={{ marginBottom: 32 }}>
          <span className="eyebrow center">{M.eyebrow}</span>
        </div>
        <p className="big reveal">
          {M.line[0]}<br />
          {M.line[1]}<em>{M.line[2]}</em>{M.line[3]}
        </p>
        <div className="stats reveal">
          {M.stats.map((s, i) => (
            <div className="stat" key={i}>
              <div className="n">{s.n}<span className="u">{s.u}</span></div>
              <div className="l">{s.l}</div>
            </div>
          ))}
        </div>
      </div>
    </section>
  );
}

/* ---------- games ---------- */
function GameCard({ g }) {
  return (
    <article className="game-card reveal" style={{ "--g": g.g }}>
      <div className="game-art">
        <div className="haze-blob" />
        <div className="glyph">{g.glyph}</div>
        <div className="scanline" />
        <div className="game-status"><span className="pip" />{g.status}</div>
        <div className="keyart-tag">key art · {g.key}.webp</div>
      </div>
      <div className="game-body">
        <div className="game-genre">{g.genre}</div>
        <h3 className="game-name">{g.name}</h3>
        <p className="game-desc">{g.desc}</p>
        <div className="game-tags">{g.tags.map((t) => <span key={t}>{t}</span>)}</div>
      </div>
    </article>
  );
}

function Games() {
  const D = window.JCROS;
  return (
    <section className="section" id="games">
      <div className="shell">
        <div className="section-head reveal">
          <span className="eyebrow">THE WORLDS</span>
          <h2 className="section-title h-display">Four worlds.<br /><span className="glow">Infinite</span> ways to play.</h2>
          <p className="section-lead">Each title is its own living system — generated, persistent, and built to never run dry. Pick a world and step in.</p>
        </div>
        <div className="games-grid">
          {D.games.map((g) => <GameCard key={g.key} g={g} />)}
        </div>
      </div>
    </section>
  );
}

/* ---------- tech / engine ---------- */
function Tech() {
  const D = window.JCROS;
  return (
    <section className="section tech" id="engine">
      <div className="shell">
        <div className="section-head center reveal">
          <span className="eyebrow center">AI-NATIVE BY DESIGN</span>
          <h2 className="section-title h-display">The same engine powers <span className="glow">every world</span></h2>
          <p className="section-lead">AI isn't a feature we bolted on. It's the foundation everything is built from — the reason our worlds have no edges.</p>
        </div>
        <div className="pillars">
          {D.pillars.map((p) => (
            <div className="pillar reveal" key={p.idx}>
              <div className="rune" aria-hidden="true" />
              <div className="idx">{p.idx}</div>
              <h3>{p.h}</h3>
              <p>{p.p}</p>
            </div>
          ))}
        </div>
      </div>
    </section>
  );
}

/* ---------- get involved (join + invest) ---------- */
function Involve() {
  const D = window.JCROS;
  const inv = D.invest;
  const deckMail =
    "mailto:" + inv.cta.email + "?subject=" + encodeURIComponent("Investor enquiry — jcros.ai");
  const jobsMail =
    "mailto:" + D.careersEmail + "?subject=" + encodeURIComponent("Open application — jcros.ai");
  return (
    <section className="section" id="involved">
      <div className="shell">
        <div className="section-head center reveal">
          <span className="eyebrow center">GET INVOLVED</span>
          <h2 className="section-title h-display">Two ways to <span className="glow">build</span> with us.</h2>
          <p className="section-lead">Help make these worlds — or help fund them. There's a place for you either way.</p>
        </div>

        <div className="involve-grid">
          {/* ── Join the studio ── */}
          <div className="involve-card reveal">
            <span className="eyebrow">JOIN THE STUDIO</span>
            <h3>Build games that <span className="glow">never end</span>.</h3>
            <p>A small crew of engineers, designers and researchers obsessed with emergence. Come make worlds nobody — not even us — has fully seen.</p>
            <div className="roles">
              {D.roles.map((r) => (
                <a className="role" href="#signup" key={r.t}>
                  <div>
                    <div className="r-title">{r.t}</div>
                    <div className="r-meta">{r.m}</div>
                  </div>
                  <span className="r-go">→</span>
                </a>
              ))}
            </div>
            <div className="hero-actions">
              <a className="btn btn-primary" href={jobsMail}>Open application <span className="arrow">→</span></a>
            </div>
            <p className="note">{D.careersEmail}</p>
          </div>

          {/* ── Raise / investors (quieter, secondary) ── */}
          <div className="involve-card involve-muted reveal">
            <span className="eyebrow">{inv.eyebrow}</span>
            <h3>{inv.title[0]} <span className="glow">{inv.title[1]}</span> {inv.title[2]}</h3>
            <p>{inv.body}</p>
            <div className="roles">
              {inv.highlights.map((h) => (
                <div className="role role-static" key={h.t}>
                  <div>
                    <div className="r-title">{h.t}</div>
                    <div className="r-meta">{h.m}</div>
                  </div>
                  <span className="r-go">∞</span>
                </div>
              ))}
            </div>
            <div className="hero-actions">
              <a className="btn btn-ghost" href={deckMail}>{inv.cta.label} <span className="arrow">→</span></a>
            </div>
            <p className="note">{inv.cta.email}</p>
          </div>
        </div>
      </div>
    </section>
  );
}

/* ---------- signup ---------- */
function Signup() {
  const [done, setDone] = useState(false);
  const submit = useCallback((e) => { e.preventDefault(); setDone(true); }, []);
  return (
    <section className="section" id="signup">
      <div className="shell">
        <div className="signup-inner reveal">
          <span className="eyebrow center">EARLY ACCESS</span>
          <h2 className="section-title h-display" style={{ marginTop: 18 }}>Get the next world first.</h2>
          <p className="section-lead" style={{ marginInline: "auto" }}>Drop your signal address. We'll send playtest invites, devlogs and the occasional transmission from worlds still under construction.</p>
          {done ? (
            <p className="ok">▸ TRANSMISSION RECEIVED — welcome to the expedition.</p>
          ) : (
            <form onSubmit={submit}>
              <input type="email" required placeholder="you@signal.net" aria-label="Email address" />
              <button className="btn btn-primary" type="submit">Request access <span className="arrow">→</span></button>
            </form>
          )}
          <p className="note">No spam. Only signal. Unsubscribe anytime.</p>
        </div>
      </div>
    </section>
  );
}

/* ---------- footer ---------- */
function Footer() {
  return (
    <footer className="footer" id="contact">
      <div className="shell">
        <div className="footer-grid">
          <div>
            <div className="mark">jcros<span className="ai">.ai</span></div>
            <p className="blurb">An AI-native game studio building worlds with infinite potential. We set the rules; the worlds do the rest.</p>
          </div>
          <div>
            <h4>Worlds</h4>
            <ul>
              <li><a href="#games">Era</a></li>
              <li><a href="#games">The Crossing</a></li>
              <li><a href="#games">AGI</a></li>
              <li><a href="#games">Mr Viking</a></li>
            </ul>
          </div>
          <div>
            <h4>Studio</h4>
            <ul>
              <li><a href="#studio">About</a></li>
              <li><a href="#engine">The Engine</a></li>
              <li><a href="#involved">Careers</a></li>
              <li><a href="#involved">Investors</a></li>
              <li><a href="#signup">Press</a></li>
            </ul>
          </div>
          <div>
            <h4>Signal</h4>
            <ul>
              <li><a href="#signup">Discord</a></li>
              <li><a href="#signup">X / Twitter</a></li>
              <li><a href="#signup">YouTube</a></li>
              <li><a href="#contact">hello@jcros.ai</a></li>
            </ul>
          </div>
        </div>
        <div className="footer-base">
          <span>© 2026 jcros.ai — all worlds reserved</span>
          <span>MADE WITH ∞ POSSIBILITY</span>
        </div>
      </div>
    </footer>
  );
}

Object.assign(window, {
  Nav, Hero, Mission, Games, Tech, Involve, Signup, Footer, Particles, useReveal,
});
