/* app.jsx — root + Tweaks */

/* Custom smooth-scroll: fixed-duration ease-out-cubic via rAF. Beats
 * the browser's native smooth scroll because the speed doesn't change
 * with distance, and it bypasses `html { scroll-behavior: smooth }`
 * which would otherwise contend with our per-frame writes. Honors
 * scroll-margin-top so the section's heading lands clear of the fixed
 * nav. Exposed on window so the nav links can call it without imports. */
window.smoothScrollToId = function smoothScrollToId(id, duration = 380) {
  const el = document.getElementById(id)
  if (!el) return
  // Match the offset that section[id] scroll-margin-top declares in styles.css.
  const offset = parseInt(getComputedStyle(el).scrollMarginTop) || 88
  const targetY = el.getBoundingClientRect().top + window.scrollY - offset
  const startY = window.scrollY
  const dist = targetY - startY
  if (Math.abs(dist) < 1) return
  const t0 = performance.now()
  const tick = (t) => {
    const p = Math.min((t - t0) / duration, 1)
    const eased = 1 - Math.pow(1 - p, 3) // ease-out cubic
    window.scrollTo(0, startY + dist * eased)
    if (p < 1) requestAnimationFrame(tick)
  }
  requestAnimationFrame(tick)
}

window.smoothScrollToTop = function smoothScrollToTop(duration = 320) {
  const startY = window.scrollY
  if (startY < 1) return
  const t0 = performance.now()
  const tick = (t) => {
    const p = Math.min((t - t0) / duration, 1)
    const eased = 1 - Math.pow(1 - p, 3)
    window.scrollTo(0, startY * (1 - eased))
    if (p < 1) requestAnimationFrame(tick)
  }
  requestAnimationFrame(tick)
}

const TWEAK_DEFAULTS = /*EDITMODE-BEGIN*/{
  "headlineFont": "Unison Pro",
  "primary": "#c53400",
  "secondary": "#c53400",
  "base": "#0d0d0d",
  "pool": "wormhole",
  "scanlines": true,
  "glow": true
}/*EDITMODE-END*/;

const HEAD_FONTS = {
  "Unison Pro": '"Unison Pro", "PP Neue Montreal", sans-serif',
  "PP Neue Montreal": '"PP Neue Montreal", sans-serif',
  "GT America Mono": '"GT America Mono", monospace',
};

function hexToRgbStr(hex) {
  const n = parseInt(hex.slice(1), 16);
  return `${(n >> 16) & 255}, ${(n >> 8) & 255}, ${n & 255}`;
}

function App() {
  const [t, setTweak] = useTweaks(TWEAK_DEFAULTS);

  useEffect(() => {
    const r = document.documentElement.style;
    r.setProperty("--display", HEAD_FONTS[t.headlineFont] || HEAD_FONTS["Manrope"]);
    r.setProperty("--green", t.primary);
    r.setProperty("--green-glow", `rgba(${hexToRgbStr(t.primary)}, 0.55)`);
    r.setProperty("--orange", t.primary);
    r.setProperty("--bg", t.base);
    document.body.style.setProperty("--scan-op", t.scanlines ? "0.35" : "0");
    window.__poolStyle = t.pool;
  }, [t]);

  useEffect(() => {
    document.body.style.background = t.base;
  }, [t.base]);

  // Hash scroll on mount. When the user navigates here from /app/* via
  // a /#playlists style link, the browser parses the hash before this
  // landing page has finished mounting (Babel transforms JSX in-browser
  // so the Playlists section appears late). Retry every rAF until the
  // target exists or ~2 seconds have passed, then run the custom
  // smoothScrollToId (fixed 400ms ease-out-cubic) — feels snappier and
  // more uniform than the browser's distance-scaled native smooth scroll.
  useEffect(() => {
    if (!window.location.hash) return
    const targetId = window.location.hash.slice(1)
    let raf = 0
    const deadline = performance.now() + 2000
    const tick = () => {
      const el = document.getElementById(targetId)
      if (el) {
        window.smoothScrollToId(targetId)
        return
      }
      if (performance.now() < deadline) raf = requestAnimationFrame(tick)
    }
    raf = requestAnimationFrame(tick)
    return () => cancelAnimationFrame(raf)
  }, [])

  return (
    <React.Fragment>
      <Nav />
      <Hero />
      <ScrollStory />
      <WalletCTA />
      <Naval />
      <RequestForStartups />
      <Playlists />
      <Footer />

      <TweaksPanel>
        <TweakSection label="Pool style" />
        <TweakRadio label="Pool" value={t.pool}
          options={["wormhole", "tunnel", "spiral"]}
          onChange={(v) => setTweak("pool", v)} />

        <TweakSection label="Typography" />
        <TweakSelect label="Headline" value={t.headlineFont}
          options={Object.keys(HEAD_FONTS)}
          onChange={(v) => setTweak("headlineFont", v)} />

        <TweakSection label="Accent" />
        <TweakColor label="Accent" value={t.primary}
          options={["#c53400", "#c53400", "#a02a00"]}
          onChange={(v) => setTweak("primary", v)} />

        <TweakSection label="Atmosphere" />
        <TweakColor label="Base" value={t.base}
          options={["#0d0d0d", "#141414", "#0a0a0a", "#000000"]}
          onChange={(v) => setTweak("base", v)} />
        <TweakToggle label="Scanline texture" value={t.scanlines}
          onChange={(v) => setTweak("scanlines", v)} />
      </TweaksPanel>
    </React.Fragment>
  );
}

/* Two routes render the dashboard with different chrome:
 *   - /dashboard         → landing chrome (Nav). Clicked from the
 *                          unlaunched landing page so the user keeps
 *                          their "explore" header context.
 *   - /app/dashboard     → app chrome (HeaderApp + AppPage wrapper).
 *                          Used after the user has tapped Launch App
 *                          and entered the /app/* surface.
 * Same Dashboard component in both — the choice of header is what
 * signals "launched" vs "browsing". */
function LandingDashboard() {
  return (
    <React.Fragment>
      <Nav />
      <Dashboard />
    </React.Fragment>
  );
}

const __path = window.location.pathname.replace(/\/+$/, "");
const __search = new URLSearchParams(window.location.search);
const __isBuild = __path === "/build" || __search.has("build");
const __isApply = __path === "/apply";

let __page;
if (__path === "/app/live-apps") __page = <AppPage><LiveApps /></AppPage>;
else if (__path === "/app/dashboard") __page = <AppPage noFooter><Dashboard /></AppPage>;
else if (__path === "/dashboard") __page = <LandingDashboard />;
else if (__path === "/app") __page = <AppPage><LiveApps /></AppPage>;
else if (__isApply) __page = <ApplyPage />;
else if (__isBuild) __page = <BuildPage />;
else __page = <App />;

ReactDOM.createRoot(document.getElementById("root")).render(__page);
