/* global React, ReactDOM, Loader, Nav, Roadster, Hero, About, Lineup, Contact, FooterCTA, useTweaks, TweaksPanel, TweakSection, TweakColor */
const { useState, useEffect } = React;

const TWEAK_DEFAULTS = /*EDITMODE-BEGIN*/{
  "palette": ["#FBD22E", "#3FBDC9", "#E94926", "#F4E5C5", "#1A1A1A"]
}/*EDITMODE-END*/;

// Each palette is [page-yellow, accent-cyan, accent-red, soft-cream, ink-text]
const PALETTE_OPTIONS = [
  ["#FBD22E", "#3FBDC9", "#E94926", "#F4E5C5", "#1A1A1A"],   // groovy yellow (default)
  ["#9FD2DE", "#1F4A52", "#E97A38", "#E8DECB", "#1A1A1A"],   // mint + teal diner
  ["#F6CCD2", "#1F4A52", "#C9384A", "#FCF3DC", "#1A1A1A"],   // bubblegum diner
  ["#0F1B2D", "#FF6B35", "#F7C548", "#F4F1DE", "#F8F1E5"],   // midnight neon
  ["#E8E2D5", "#2C5F4F", "#D5573B", "#F4ECDB", "#1F1B16"],   // tea room
  ["#FFE6A7", "#118AB2", "#EF476F", "#FFFCF2", "#073B4C"],   // pop
  ["#F4A300", "#A23E48", "#2E2A26", "#F0D78C", "#FBF1D6"],   // sunset
  ["#101010", "#FFD23F", "#EE4266", "#F8F1E5", "#F8F1E5"],   // late-night
];

function hexToRgb(hex) {
  const h = hex.replace("#", "");
  const n = parseInt(h.length === 3 ? h.split("").map(c => c + c).join("") : h, 16);
  return { r: (n >> 16) & 255, g: (n >> 8) & 255, b: n & 255 };
}
function rgbToHex({ r, g, b }) {
  const c = (v) => Math.max(0, Math.min(255, Math.round(v))).toString(16).padStart(2, "0");
  return `#${c(r)}${c(g)}${c(b)}`;
}
function lighten(hex, amt) {
  const { r, g, b } = hexToRgb(hex);
  return rgbToHex({ r: r + (255 - r) * amt, g: g + (255 - g) * amt, b: b + (255 - b) * amt });
}
function darken(hex, amt) {
  const { r, g, b } = hexToRgb(hex);
  return rgbToHex({ r: r * (1 - amt), g: g * (1 - amt), b: b * (1 - amt) });
}

function applyPalette(arr) {
  const root = document.documentElement;
  const [bg, cyan, red, cream, ink] = arr;
  root.style.setProperty("--yellow", bg);
  root.style.setProperty("--yellow-soft", lighten(bg, 0.18));
  root.style.setProperty("--yellow-deep", darken(bg, 0.18));
  root.style.setProperty("--cyan", cyan);
  root.style.setProperty("--cyan-soft", lighten(cyan, 0.18));
  root.style.setProperty("--cyan-deep", darken(cyan, 0.22));
  root.style.setProperty("--red", red);
  root.style.setProperty("--red-deep", darken(red, 0.18));
  root.style.setProperty("--red-soft", lighten(red, 0.18));
  root.style.setProperty("--cream", cream);
  root.style.setProperty("--cream-warm", darken(cream, 0.08));
  root.style.setProperty("--paper", lighten(cream, 0.08));
  root.style.setProperty("--ink", ink);
  root.style.setProperty("--ink-soft", lighten(ink, 0.1));
}

// Show the brand intro loader only on the visitor's first landing this session.
// Internal navigation (e.g. Home ⇄ Shop) skips it.
function hasSeenIntro() {
  try { return sessionStorage.getItem("wc-seen-intro") === "1"; } catch (e) { return false; }
}
function markIntroSeen() {
  try { sessionStorage.setItem("wc-seen-intro", "1"); } catch (e) {}
}
function prefersReducedMotion() {
  try { return window.matchMedia("(prefers-reduced-motion: reduce)").matches; } catch (e) { return false; }
}

function App() {
  // Skip the intro loader entirely when the visitor prefers reduced motion.
  const [loaded, setLoaded] = useState(() => hasSeenIntro() || prefersReducedMotion());
  const [t, setTweak] = useTweaks(TWEAK_DEFAULTS);

  // Apply palette whenever the user picks a new one
  useEffect(() => { applyPalette(t.palette); }, [t.palette]);

  useEffect(() => {
    if (!loaded) return;
    const gsap = window.gsap;
    const ScrollTrigger = window.ScrollTrigger;
    gsap.registerPlugin(ScrollTrigger);

    // Reduced motion: skip Lenis smooth-scroll; anchor links jump instantly.
    const reduced = prefersReducedMotion();
    let lenis = null;
    if (!reduced) {
      lenis = new window.Lenis({
        duration: 1.2,
        smoothWheel: true,
        smoothTouch: false,
        easing: (t) => Math.min(1, 1.001 - Math.pow(2, -10 * t)),
      });
      lenis.on("scroll", ScrollTrigger.update);
      gsap.ticker.add((time) => lenis.raf(time * 1000));
      gsap.ticker.lagSmoothing(0);
    }

    const onClick = (e) => {
      const a = e.target.closest('a[href^="#"]');
      if (!a) return;
      const id = a.getAttribute("href");
      if (id.length < 2) return;
      const el = document.querySelector(id);
      if (!el) return;
      e.preventDefault();
      if (lenis) lenis.scrollTo(el, { offset: -10, duration: 1.2 });
      else el.scrollIntoView({ behavior: "auto", block: "start" });
    };
    document.addEventListener("click", onClick);

    requestAnimationFrame(() => ScrollTrigger.refresh());

    // Deep-link support (e.g. arriving on index.html#lineup from another page):
    // sections only exist after React mounts, so the browser's native hash
    // jump fired against an empty page — redo it once layout is real.
    if (window.location.hash.length > 1) {
      let target = null;
      try { target = document.querySelector(window.location.hash); } catch (e) {}
      if (target) {
        setTimeout(() => {
          const y = target.getBoundingClientRect().top + window.scrollY - 10;
          window.scrollTo({ top: y, behavior: "auto" });
          if (lenis) lenis.scrollTo(y, { immediate: true });
        }, 120);
      }
    }

    return () => {
      document.removeEventListener("click", onClick);
      if (lenis) lenis.destroy();
    };
  }, [loaded]);

  // Which page are we on? Driven by <body data-page="…">. Each page renders its
  // own sections; the FooterCTA (the "Get Started" / contact band) closes every page.
  // Look components up by name off window and drop any that aren't loaded yet, so a
  // stale/missing script can never crash the whole app (white screen).
  const page = (document.body && document.body.dataset.page) || "home";
  const SECTIONS_BY_PAGE = {
    home:    ["Hero", "Lineup"],
    about:   ["About"],
    contact: ["Contact"],
  };
  const sections = (SECTIONS_BY_PAGE[page] || SECTIONS_BY_PAGE.home)
    .map((name) => window[name])
    .filter(Boolean);

  return (
    <>
      <a className="skip-link" href="#main">Skip to content</a>
      {!loaded && <Loader onDone={() => { markIntroSeen(); setLoaded(true); }} />}
      <div className="entry-swipe checker" aria-hidden="true" />
      <div id="main" tabIndex={-1} className={loaded ? "" : "is-prep"}>
        <Nav />
        <Roadster />
        {sections.map((Section, i) => <Section key={i} />)}
        {/* the contact page IS the conversion point — no brochure footer there */}
        {page !== "contact" && <FooterCTA />}
      </div>

      <TweaksPanel title="Tweaks">
        <TweakSection label="Color Palette" />
        <TweakColor
          label="Preset"
          value={t.palette}
          options={PALETTE_OPTIONS}
          onChange={(v) => setTweak("palette", v)}
        />
        <TweakSection label="Individual Colors" />
        <TweakColor
          label="Background"
          value={t.palette[0]}
          onChange={(v) => setTweak("palette", [v, t.palette[1], t.palette[2], t.palette[3], t.palette[4]])}
        />
        <TweakColor
          label="Cyan Shapes"
          value={t.palette[1]}
          onChange={(v) => setTweak("palette", [t.palette[0], v, t.palette[2], t.palette[3], t.palette[4]])}
        />
        <TweakColor
          label="Red Accents"
          value={t.palette[2]}
          onChange={(v) => setTweak("palette", [t.palette[0], t.palette[1], v, t.palette[3], t.palette[4]])}
        />
        <TweakColor
          label="Cream"
          value={t.palette[3]}
          onChange={(v) => setTweak("palette", [t.palette[0], t.palette[1], t.palette[2], v, t.palette[4]])}
        />
        <TweakColor
          label="Ink (Text)"
          value={t.palette[4]}
          onChange={(v) => setTweak("palette", [t.palette[0], t.palette[1], t.palette[2], t.palette[3], v])}
        />
      </TweaksPanel>
    </>
  );
}

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