// App — top-level composition
const { useEffect: useAppEffect } = React;

function App() {
  const [tweaks, setTweak] = window.useTweaks(window.TWEAK_DEFAULTS);

  // Inject Snell's-law SVG refraction filters for glass elements
  useAppEffect(() => {
    if (window.buildGlassRefractFilters) window.buildGlassRefractFilters();
  }, []);

  // Deep links (e.g. the case pages' "../index.html#projects" back-link) never
  // worked: the browser resolves the hash while React is still being compiled
  // by in-browser Babel, finds no such element, and never retries. Re-run the
  // jump once the target actually exists.
  //
  // Reads the hash once on mount only, so clicking in-page anchors later is
  // untouched. Does nothing at all when there is no hash, so a normal load is
  // unaffected. scroll-behavior is forced to auto for the jump — inheriting
  // the global `smooth` would animate a long scroll from the top on arrival.
  useAppEffect(() => {
    const id = decodeURIComponent((window.location.hash || '').slice(1));
    if (!id) return;

    let frames = 0;
    let raf = 0;
    const jump = () => {
      const el = document.getElementById(id);
      if (el) {
        const root = document.documentElement;
        const prev = root.style.scrollBehavior;
        root.style.scrollBehavior = 'auto';
        el.scrollIntoView({ block: 'start' });
        root.style.scrollBehavior = prev;
        return;
      }
      // ~2s ceiling: enough for Babel + mount, short enough to give up quietly
      if (frames++ < 120) raf = requestAnimationFrame(jump);
    };
    raf = requestAnimationFrame(jump);
    return () => cancelAnimationFrame(raf);
  }, []);

  // Apply theme immediately (before paint) when tweaks load from localStorage
  useAppEffect(() => {
    const root = document.documentElement;
    root.setAttribute('data-theme', tweaks.theme);
    root.setAttribute('data-accent', tweaks.accent);
    root.setAttribute('data-font', tweaks.font);
    root.setAttribute('data-motion', tweaks.motion);
    try { localStorage.setItem('yui_tweaks', JSON.stringify(tweaks)); } catch (e) { }

    // Re-scan reveal targets after layout shifts
    if (window.__scanReveal) setTimeout(window.__scanReveal, 60);
  }, [tweaks]);

  // Load font dynamically based on tweaks
  useAppEffect(() => {
    const fontMap = {
      geist: 'https://fonts.googleapis.com/css2?family=Geist:wght@400;500;600;700;800&display=swap',
      space: 'https://fonts.googleapis.com/css2?family=Space+Grotesk:wght@400;500;600;700&display=swap',
      serif: 'https://fonts.googleapis.com/css2?family=Instrument+Serif:ital@0;1&display=swap',
    };
    const url = fontMap[tweaks.font];
    if (!url) return;
    const id = 'font-' + tweaks.font;
    if (document.getElementById(id)) return;
    const link = document.createElement('link');
    link.rel = 'stylesheet';
    link.href = url;
    link.id = id;
    document.head.appendChild(link);
  }, [tweaks.font]);

  const data = window.PORTFOLIO_DATA;

  return (
    <>
      <window.Cursor />
      {/* Ambient aurora — fixed behind everything, sui.io-style layered blobs */}
      <div className="bg-orb bg-orb--1" aria-hidden="true" />
      <div className="bg-orb bg-orb--2" aria-hidden="true" />
      <div className="bg-orb bg-orb--3" aria-hidden="true" />
      <div className="bg-orb bg-orb--4" aria-hidden="true" />
      <div className="bg-orb bg-orb--5" aria-hidden="true" />
      <main>
        <window.Hero tweaks={tweaks} />
        {/* Marquee pins (sticky) while the Projects Container scrolls under it */}
        <div className="mq-sticky">
          <window.HeroMarquee />
          <window.Projects />
        </div>
        <window.Stack />
        <window.MarqueeStrip items={data.marqueeBottom} small slow reverse />
      </main>
      {/* Outside <main> on purpose: main is z:1, and .mq-sticky inside it is
          z:41. Rendering the fixed nav pill here puts it in the root stacking
          context, so it stays clickable over the Works section. */}
      <window.SiteBrand />
      <window.HeroNavPill />
      <window.Footer />
      <window.Tweaks tweaks={tweaks} setTweak={setTweak} />
    </>
  );
}

window.App = App;
