/* global React, ReactDOM, gsap, ScrollTrigger, Navbar, ForestJourney, About, TechStack, Services, Process, Projects, Footer, prefersReduced */
gsap.registerPlugin(ScrollTrigger);
const { useRef: useRefA, useLayoutEffect: useLayoutEffectA } = React;

/* Drifting mist particles that cross the screen in continuous scroll-parallax */
const DOTS = [
  { top: '12%', left: '8%',  size: 220, drift: 60 },
  { top: '30%', left: '82%', size: 300, drift: -90 },
  { top: '55%', left: '18%', size: 180, drift: 70 },
  { top: '68%', left: '70%', size: 260, drift: -60 },
  { top: '85%', left: '40%', size: 320, drift: 80 },
  { top: '5%',  left: '55%', size: 160, drift: -50 },
];

function GlobalAtmosphere() {
  const ref = useRefA(null);
  useLayoutEffectA(() => {
    const el = ref.current;
    if (!el || prefersReduced) return;
    const ctx = gsap.context(() => {
      el.querySelectorAll('.mist-dot').forEach((d, i) => {
        gsap.to(d, {
          yPercent: DOTS[i] ? DOTS[i].drift : 60,
          xPercent: (i % 2 ? -1 : 1) * 12,
          ease: 'none',
          scrollTrigger: { start: 0, end: 'max', scrub: 1.4 },
        });
      });
    }, el);
    return () => ctx.revert();
  }, []);

  return (
    <div ref={ref} className="atmosphere" aria-hidden="true">
      {DOTS.map((d, i) => (
        <span key={i} className="mist-dot" style={{ top: d.top, left: d.left, width: d.size, height: d.size }} />
      ))}
    </div>
  );
}

/* Custom cursor — small dot (immediate) + sage glow aura (lagged) */
function CursorGlow() {
  const glowRef = useRefA(null);
  const dotRef  = useRefA(null);

  useLayoutEffectA(() => {
    if (prefersReduced) return;
    if (!window.matchMedia('(hover: hover) and (pointer: fine)').matches) return;

    const glow = glowRef.current;
    const dot  = dotRef.current;
    if (!glow || !dot) return;

    // Inject cursor:none once (avoids React re-render side-effects)
    const style = document.createElement('style');
    style.textContent = '* { cursor: none !important; }';
    document.head.appendChild(style);

    gsap.set([glow, dot], { opacity: 0 });

    let mx = -999, my = -999, glowX = -999, glowY = -999;

    const glowXQ = gsap.quickSetter(glow, 'x', 'px');
    const glowYQ = gsap.quickSetter(glow, 'y', 'px');
    const dotXQ  = gsap.quickSetter(dot,  'x', 'px');
    const dotYQ  = gsap.quickSetter(dot,  'y', 'px');

    const onMove = (e) => {
      mx = e.clientX; my = e.clientY;
      dotXQ(mx); dotYQ(my);
      gsap.to([glow, dot], { opacity: 1, duration: 0.35, overwrite: 'auto' });
    };
    const onLeave = () => gsap.to([glow, dot], { opacity: 0, duration: 0.5, overwrite: 'auto' });
    const onEnter = () => gsap.to([glow, dot], { opacity: 1, duration: 0.3, overwrite: 'auto' });

    const tick = () => {
      glowX += (mx - glowX) * 0.09;
      glowY += (my - glowY) * 0.09;
      glowXQ(glowX); glowYQ(glowY);
    };

    gsap.ticker.add(tick);
    document.addEventListener('mousemove', onMove);
    document.addEventListener('mouseleave', onLeave);
    document.addEventListener('mouseenter', onEnter);

    return () => {
      style.remove();
      gsap.ticker.remove(tick);
      document.removeEventListener('mousemove', onMove);
      document.removeEventListener('mouseleave', onLeave);
      document.removeEventListener('mouseenter', onEnter);
    };
  }, []);

  return (
    <>
      {/* Glow aura — lags behind, sage radial light */}
      <div ref={glowRef} aria-hidden="true" style={{
        position: 'fixed', left: 0, top: 0,
        width: 340, height: 340,
        marginLeft: -170, marginTop: -170,
        borderRadius: '50%',
        background: 'radial-gradient(circle, rgba(124,152,133,0.18) 0%, rgba(124,152,133,0.07) 40%, transparent 70%)',
        pointerEvents: 'none', zIndex: 9998,
        mixBlendMode: 'screen',
        willChange: 'transform',
      }} />
      {/* Dot — follows immediately */}
      <div ref={dotRef} aria-hidden="true" style={{
        position: 'fixed', left: 0, top: 0,
        width: 6, height: 6,
        marginLeft: -3, marginTop: -3,
        borderRadius: '50%',
        background: '#E8EDE9',
        pointerEvents: 'none', zIndex: 9999,
        mixBlendMode: 'difference',
        willChange: 'transform',
        boxShadow: '0 0 6px 1px rgba(124,152,133,0.55)',
      }} />
    </>
  );
}

function App() {
  return (
    <div id="top" style={{ background: '#0B0F0D' }}>
      {/* Teleportation flash overlay — controlled by Navbar's teleportTo */}
      <div id="teleport-overlay" aria-hidden="true" style={{
        position: 'fixed', inset: 0, zIndex: 9997,
        background: '#0B0F0D', opacity: 0, pointerEvents: 'none',
      }} />
      <CursorGlow />
      <Navbar />
      <GlobalAtmosphere />
      <ForestJourney />
      <main className="relative z-10 bg-night">
        <About />
        <TechStack />
        <Services />
        <Process />
        <Projects />
        <Footer />
      </main>
    </div>
  );
}

// Fetch site data (projects + settings) before mounting so GSAP always sees
// the final DOM on first render. Falls back to data.json defaults on error.
async function bootstrap() {
  try {
    const r = await fetch('/api/data');
    if (r.ok) window.__SITE_DATA__ = await r.json();
  } catch {}
  ReactDOM.createRoot(document.getElementById('root')).render(<App />);
}
bootstrap();

// Refresh once everything (fonts, images, layout) settles.
window.addEventListener('load', () => {
  if (window.ScrollTrigger) ScrollTrigger.refresh();
});
