/* App orchestration — cinematic Grand Cup Auto cover scene */

const { useState: useState_a, useEffect: useEffect_a } = React;

const TWEAK_DEFAULTS = /*EDITMODE-BEGIN*/{
  "palette": "vi-cover",
  "showLoader": true,
  "grain": 0.07,
  "marketCapAnim": true,
  "showMatchHud": true
}/*EDITMODE-END*/;

/* THE HERO LOGO — Grand Cup Auto cover treatment */
function HeroLogo() {
  return (
    <div className="hero-logo">
      <h1 className="hero-line hero-line-main" style={{margin: 0}}>grand cup auto</h1>
      <div className="hero-vi">VI</div>
    </div>
  );
}

function App() {
  const data = window.GCA_DATA;
  const hasRatWallDeepLink = window.location.hash === "#rat-wall";
  const [stage, setStage] = useState_a(hasRatWallDeepLink ? "ready" : "loading"); // loading -> brief -> ready
  const [briefOpen, setBriefOpen] = useState_a(false);
  const [tweaks, setTweak] = window.useTweaks(TWEAK_DEFAULTS);
  const [installVisible, setInstallVisible] = useState_a(false);
  const [installEvent, setInstallEvent] = useState_a(null);

  /* Live store drives market cap + volume */
  const liveMarket = window.useLive
    ? window.useLive(s => ({ marketCap: s.marketCap, volume24h: s.volume24h, solPrice: s.solPrice }))
    : null;
  const livePrice = liveMarket
    ? { ...data.price, marketCap: liveMarket.marketCap, volume24h: liveMarket.volume24h, solPrice: liveMarket.solPrice }
    : data.price;

  useEffect_a(() => {
    if (!tweaks.showLoader && stage === "loading") setStage("ready");
  }, [tweaks.showLoader, stage]);

  useEffect_a(() => {
    if (stage !== "ready") return undefined;

    const scrollToHashTarget = () => {
      const id = window.location.hash.slice(1);
      if (!id) {
        window.requestAnimationFrame(() => {
          window.scrollTo({ top: 0, behavior: "auto" });
        });
        return;
      }
      const el = document.getElementById(id);
      if (!el) return;
      window.requestAnimationFrame(() => {
        window.scrollTo({ top: Math.max(0, el.offsetTop - 24), behavior: "auto" });
      });
    };

    const t = setTimeout(scrollToHashTarget, 120);
    window.addEventListener("hashchange", scrollToHashTarget);
    return () => {
      clearTimeout(t);
      window.removeEventListener("hashchange", scrollToHashTarget);
    };
  }, [stage]);

  // grain
  useEffect_a(() => {
    document.documentElement.style.setProperty("--grain-opacity", tweaks.grain);
  }, [tweaks.grain]);

  // palette swap
  useEffect_a(() => {
    document.body.dataset.palette = tweaks.palette;
    const root = document.documentElement.style;
    if (tweaks.palette === "vi-cover") {
      root.setProperty("--vc-pink", "#ff3aa3");
      root.setProperty("--vc-cyan", "#46e5e5");
    } else if (tweaks.palette === "neon") {
      root.setProperty("--vc-pink", "#ff1bb5");
      root.setProperty("--vc-cyan", "#00f5ff");
    } else if (tweaks.palette === "v-gold") {
      root.setProperty("--vc-pink", "#f0c040");
      root.setProperty("--vc-cyan", "#ffd23a");
    }
  }, [tweaks.palette]);

  // PWA install prompt
  useEffect_a(() => {
    const handler = (e) => {
      e.preventDefault();
      setInstallEvent(e);
      setInstallVisible(true);
    };
    window.addEventListener("beforeinstallprompt", handler);
    return () => window.removeEventListener("beforeinstallprompt", handler);
  }, []);

  const onLoaded = () => {
    setStage("brief");
    setTimeout(() => setBriefOpen(true), 120);
  };
  const onAccept = () => {
    setBriefOpen(false);
    setTimeout(() => setStage("ready"), 360);
  };
  const onClose = () => {
    setBriefOpen(false);
    setTimeout(() => setStage("ready"), 360);
  };
  const reopenBrief = () => setBriefOpen(true);

  const scrollToPoster = () => {
    const el = document.getElementById("poster-section");
    if (!el) return;
    window.scrollTo({ top: el.offsetTop - 40, behavior: "smooth" });
  };

  const installApp = async () => {
    if (!installEvent) return;
    installEvent.prompt();
    await installEvent.userChoice;
    setInstallVisible(false);
    setInstallEvent(null);
  };

  return (
    <React.Fragment>
      {stage === "loading" && <LoadingScreen onComplete={onLoaded} />}

      <MissionBrief open={briefOpen} onAccept={onAccept} onClose={onClose} />

      <div className={`app ${stage === "ready" || stage === "brief" ? "ready" : ""}`}>
        <HUDBar data={{ price: livePrice }} onWantedClick={scrollToPoster} />

        {/* CINEMATIC HERO */}
        <section className="hero" data-screen-label="01 Hero · Cover">
          <div className="hero-scene" />
          <div className="hero-stars" />
          <div className="hero-art">
            <window.CinematicScene />
          </div>
          {/* Particle rain overlay — additive neon streaks + embers */}
          {typeof window.NeonRain === "function" && <window.NeonRain />}

          {/* Cinema bars */}
          <div className="hero-bars top" />
          <div className="hero-bars bot" />

          {/* Bottom ticker — over the bars, marquee animated */}
          <div className="hero-ticker">
            <div className="hero-ticker-track">
              {[0, 1].map((rep) => (
                <React.Fragment key={rep}>
                  <span className="pip"><span className="d" /> live · brazil 2 – 1 argentina · 67&apos;</span>
                  <span className="pip cyan"><span className="d" /> next · esp vs ger · 04:22:17</span>
                  <span className="pip gold"><span className="d" /> ◎ {livePrice.solPrice.toFixed(2)} sol/usd</span>
                  <span className="pip"><span className="d" /> heat lv. {livePrice.wantedLevel}/5</span>
              <span className="pip cyan"><span className="d" /> grand cup auto / 5 cartels</span>
                </React.Fragment>
              ))}
            </div>
          </div>

          <div className="hero-content">
            <div className="hero-eyebrow">
              <span className="dot" /> LIVE FROM HARD ROCK STADIUM · MIAMI · LEONIDA
            </div>

            <HeroLogo />

            <div className="hero-tag-row">
              <span>GRAND CUP AUTO</span><span className="sep"/>
              <span>5 CARTELS</span><span className="sep"/>
              <span>CARTEL TOKENS</span><span className="sep"/>
              <span>$GCA</span>
            </div>

            <div className="hero-subtag">
              five cartel tokens feed bounty pots while $GCA stays the main burn flywheel.
            </div>

            <div className="hero-cta-row">
              <button className="btn-sunset lg" onClick={scrollToPoster}>Buy $GCA</button>
              <button className="btn-ghost" onClick={reopenBrief}>view mission brief</button>
            </div>
          </div>

          {tweaks.showMatchHud && (
            <div className="hero-match-hud">
              {/* Hologram video accents the match card from behind */}
              <video
                className="match-hologram-video"
                src="assets/vid-match-hologram.mp4"
                autoPlay muted loop playsInline
                aria-hidden="true"
              />
              <MissionLoadingCard />
            </div>
          )}

          {/* Character cutout */}
          <img
            className="hero-character"
            src="assets/char-stockholm.png"
            alt=""
            loading="eager"
          />

          <Minimap />
        </section>

        {typeof window.AdvancedMemeGenerator === "function" && <window.AdvancedMemeGenerator />}

        {/* WORLD IS OURS */}
        <section className="section dark" id="poster-section" data-screen-label="02 The World Is Ours">
          <window.SectionStage
            variant="solo-right"
            shape="chamfer"
            accent="pink"
            num="02"
            eyebrow="cartel economy"
            title={<>the world <span className="ac">is ours.</span></>}
            sub="In Vice City, nobody works for free. Nobody eats unless the Boss eats first."
            cta={{ label: "▸ view the flywheel", onClick: () => { const el = document.querySelector('.world-wrap'); if (el) window.scrollTo({ top: el.offsetTop - 40, behavior: 'smooth' }); } }}
            bg="assets/scene-printing-room.png"
            charRight="assets/char-broker.png"
            charPop={18}
            height={500}
          />
          <PosterGenerator liveMatch={data.liveMatch} />
        </section>

        {/* BOUNTY BOARD */}
        <section className="section darker" data-screen-label="03 Bounty Board">
          <window.SectionStage
            variant="duo"
            shape="slant-r"
            accent="coral"
            num="03"
            eyebrow="pump.fun go relay"
            title={<>bounty <span className="ac">board.</span></>}
            sub="cartel bounties loading into pump.fun go and feeding the main $gca flywheel."
            bg="assets/scene-dossier-wall.png"
            charLeft="assets/char-whale.png"
            charRight="assets/char-superagent.png"
            charPop={16}
            height={500}
          />
          <MostWanted rows={data.leaderboard} />
        </section>

        {/* RAT WALL OF SHAME — sells leaderboard */}
        <window.RatWall />

        {/* PUMP.FUN BOUNTIES — retro broadcast deck */}
        <TurfMap />

        {/* CARTEL BRACKET — cartel crews as Grand Cup cartels */}
        <window.CartelBracket />

        {/* HEIST CONTRACTS */}
        <section className="section midnight" data-screen-label="08 Heist Contracts">
          <window.SectionStage
            variant="solo-left"
            shape="slant-l"
            accent="cyan"
            num="08"
            eyebrow="cartel holder objectives"
            title={<>heist <span className="ac-cyan">contracts.</span></>}
            sub={<>Heist Contracts: <em>Cartel holder objectives</em> 🔥 ⚠️ A bounty that pays out when a community &quot;heist&quot; objective is met within the countdown.</>}
            bg="assets/banner-group-stage.png"
            charLeft="assets/char-referee.png"
            charPop={18}
            height={500}
          />
          <MissionLog missions={data.missions} />
        </section>

        {/* TOKENOMICS — distribution, bonding curve, roadmap, contract */}
        <window.Tokenomics token={data.token} price={livePrice} />

        <JoinCrew />

        <Footer />

        {/* Cinematic flow: scroll reveals + mission progress rail */}
        <window.FlowHost />
      </div>

      {/* Particle / audio layer */}
      {typeof window.CoinBurst === "function" && <window.CoinBurst />}
      {typeof window.SoundtrackController === "function" && <window.SoundtrackController />}
      {typeof window.MuteButton === "function" && <window.MuteButton />}
      {typeof window.TiltGate === "function" && <window.TiltGate />}

      {/* PWA install hint */}
      <div className={`install-hint ${installVisible ? "show" : ""}`}>
        <div className="ic">vc</div>
        <div className="tx">
          <b>install $gca app</b>
          Add to home screen · works offline
        </div>
        <button className="go" onClick={installApp}>install</button>
        <span className="x" onClick={() => setInstallVisible(false)}>×</span>
      </div>

      {/* Tweaks panel */}
      <window.TweaksPanel>
        <window.TweakSection label="Brand palette">
          <window.TweakRadio
            label="Palette"
            value={tweaks.palette}
            onChange={v => setTweak("palette", v)}
            options={[
              { value: "vi-cover", label: "VI cover" },
              { value: "neon",     label: "Neon" },
              { value: "v-gold",   label: "V gold" },
            ]}
          />
        </window.TweakSection>
        <window.TweakSection label="Intro">
          <window.TweakToggle
            label="Loader on refresh"
            value={tweaks.showLoader}
            onChange={v => setTweak("showLoader", v)}
          />
          <window.TweakButton
            label="Replay intro sequence"
            onClick={() => { setStage("loading"); setBriefOpen(false); }}
          />
          <window.TweakButton
            label="Open mission brief"
            onClick={() => setBriefOpen(true)}
          />
        </window.TweakSection>
        <window.TweakSection label="Atmosphere">
          <window.TweakSlider
            label="Film grain"
            value={tweaks.grain}
            min={0} max={0.2} step={0.01}
            onChange={v => setTweak("grain", v)}
          />
          <window.TweakToggle
            label="Animate market cap"
            value={tweaks.marketCapAnim}
            onChange={v => setTweak("marketCapAnim", v)}
          />
          <window.TweakToggle
            label="Show live match HUD"
            value={tweaks.showMatchHud}
            onChange={v => setTweak("showMatchHud", v)}
          />
        </window.TweakSection>
      </window.TweaksPanel>
    </React.Fragment>
  );
}

const root = ReactDOM.createRoot(document.getElementById("root"));
root.render(<App />);
