/* global React, ReactDOM, InwardCarousel, StarField, ScaleSection, FeaturedClients, Marquee, Services, Performance, Stats, Process, CTA, Footer */

const { useEffect, useRef, useState } = React;

function Header() {
  const [menuOpen, setMenuOpen] = useState(false);
  const [hidden, setHidden] = useState(false);
  useEffect(() => {
    document.body.style.overflow = menuOpen ? "hidden" : "";
    return () => { document.body.style.overflow = ""; };
  }, [menuOpen]);
  // Hide header on scroll down, show on scroll up — MOBILE ONLY. On desktop
  // the floating pill stays pinned because there's plenty of horizontal
  // room and a disappearing nav at the top of a wide canvas feels worse
  // than just leaving it in place.
  useEffect(() => {
    const isMobile = () => window.matchMedia("(max-width: 760px)").matches;
    let lastY = window.scrollY;
    let raf = 0;
    const tick = () => {
      if (!isMobile()) { setHidden(false); raf = 0; return; }
      const y = window.scrollY;
      const dy = y - lastY;
      if (y < 60) {
        setHidden(false);
      } else if (Math.abs(dy) > 4) {
        setHidden(dy > 0); // scrolling down → hide
      }
      lastY = y;
      raf = 0;
    };
    const onScroll = () => { if (!raf) raf = requestAnimationFrame(tick); };
    window.addEventListener("scroll", onScroll, { passive: true });
    return () => window.removeEventListener("scroll", onScroll);
  }, []);
  const close = () => setMenuOpen(false);
  return (
    <header className={`topnav ${hidden ? "is-hidden" : ""}`}>
      <div className="nav-pill">
        <a href="#top" className="brand-mark" onClick={close}>
          <img src="logo-mark.png" alt="ROAS Marketing" className="brand-logo"/>
        </a>
        <nav className="navlinks">
          <a href="#performance">Work</a>
          <a href="#services">Services</a>
          <a href="#contact">Contact</a>
        </nav>
        <a href="#contact" className="nav-cta nav-cta-desktop">
          Book a call <span aria-hidden>↗</span>
        </a>
        <button
          className="nav-burger"
          aria-label={menuOpen ? "Close menu" : "Open menu"}
          aria-expanded={menuOpen}
          onClick={() => setMenuOpen((v) => !v)}
        >
          {menuOpen
            ? (<svg width="22" height="22" viewBox="0 0 22 22" aria-hidden><path d="M5 5l12 12M17 5L5 17" stroke="currentColor" strokeWidth="1.6" strokeLinecap="round"/></svg>)
            : (<svg width="22" height="22" viewBox="0 0 22 22" aria-hidden><path d="M4 7h14M4 15h14" stroke="currentColor" strokeWidth="1.6" strokeLinecap="round"/></svg>)
          }
        </button>
      </div>

      {/* Mobile full-screen menu overlay */}
      <div className={`mobile-menu ${menuOpen ? "is-open" : ""}`} role="dialog" aria-hidden={!menuOpen}>
        <nav className="mobile-menu-links" onClick={close}>
          <a href="#performance">Work</a>
          <a href="#services">Services</a>
          <a href="#contact">Contact</a>
        </nav>
        <a href="#contact" className="mobile-menu-cta" onClick={close}>
          Book a call <span aria-hidden>↗</span>
        </a>
      </div>
    </header>
  );
}

function GlobalCursor() {
  // A single arrow cursor that follows the mouse across the WHOLE page
  // (hero + every section below). The StarField canvas still paints its
  // constellation lines + soft glow under the cursor inside the hero, but
  // the arrow itself is now this DOM element so it stays visible everywhere.
  const cursorRef = useRef(null);
  useEffect(() => {
    // Skip on touch devices — they keep the native tap experience.
    if (window.matchMedia("(hover: none)").matches) return;
    const el = cursorRef.current;
    if (!el) return;
    let x = -100, y = -100;
    const onMove = (e) => {
      x = e.clientX; y = e.clientY;
      el.style.transform = `translate3d(${x}px, ${y}px, 0)`;
      if (el.style.opacity !== "1") el.style.opacity = "1";
    };
    const onLeave = () => { el.style.opacity = "0"; };
    const onDown = () => { el.classList.add("is-down"); };
    const onUp   = () => { el.classList.remove("is-down"); };
    window.addEventListener("mousemove", onMove);
    window.addEventListener("mouseleave", onLeave);
    window.addEventListener("mousedown", onDown);
    window.addEventListener("mouseup",   onUp);
    document.body.classList.add("has-custom-cursor");
    return () => {
      window.removeEventListener("mousemove", onMove);
      window.removeEventListener("mouseleave", onLeave);
      window.removeEventListener("mousedown", onDown);
      window.removeEventListener("mouseup",   onUp);
      document.body.classList.remove("has-custom-cursor");
    };
  }, []);
  return (
    <div className="global-cursor" ref={cursorRef} aria-hidden>
      <svg width="26" height="28" viewBox="0 0 20 22" fill="none">
        <path
          d="M0.5 0.5 L0.5 16 L4.7 12.2 L7.7 18.4 L10.5 17.2 L7.5 11 L13 11 Z"
          fill="white"
          stroke="rgba(0,0,0,0.55)"
          strokeWidth="1"
          strokeLinejoin="round"
        />
      </svg>
    </div>
  );
}

function Hero() {
  return (
    <section className="hero" id="top">
      <div className="hero-grain" aria-hidden></div>
      <StarField />

      <div className="hero-inner shell">
        <h1 className="hero-title">
          AI Creatives That Turn<br className="brk-mobile"/> <span className="em">Attention <span className="em-light">Into</span><br className="brk-mobile"/> Revenue.</span>
        </h1>

        <div className="hero-cta-row">
          <a href="#contact" className="btn-primary">
            Book a call <span aria-hidden>↗</span>
          </a>
          <a href="#performance" className="btn-secondary">
            Learn more
          </a>
        </div>
      </div>

      <InwardCarousel />
    </section>
  );
}

function App() {
  // Apply reveal-on-scroll for .reveal elements
  useEffect(() => {
    const els = document.querySelectorAll(".reveal");
    const io = new IntersectionObserver((entries) => {
      entries.forEach((e) => {
        if (e.isIntersecting) { e.target.classList.add("in"); io.unobserve(e.target); }
      });
    }, { threshold: 0.15 });
    els.forEach((el) => io.observe(el));
    return () => io.disconnect();
  }, []);

  // Smooth-scroll for in-page anchor clicks. The browser's
  // scroll-behavior: smooth alone is unreliable inside iframes / when html
  // has overflow rules — wiring up a global handler guarantees it works.
  useEffect(() => {
    const HEADER_OFFSET = 96;
    const DURATION = 450;
    const easeInOutCubic = (t) => t < 0.5 ? 4*t*t*t : 1 - Math.pow(-2*t + 2, 3) / 2;
    let activeAnim = 0;
    const smoothScrollTo = (targetY) => {
      cancelAnimationFrame(activeAnim);
      const startY = window.scrollY;
      const delta = targetY - startY;
      if (Math.abs(delta) < 2) return;
      const startT = performance.now();
      const step = (now) => {
        const t = Math.min(1, (now - startT) / DURATION);
        window.scrollTo(0, startY + delta * easeInOutCubic(t));
        if (t < 1) activeAnim = requestAnimationFrame(step);
      };
      activeAnim = requestAnimationFrame(step);
    };
    const onClick = (e) => {
      const a = e.target.closest && e.target.closest('a[href^="#"]');
      if (!a) return;
      const href = a.getAttribute("href");
      if (!href || href === "#" || href.length < 2) return;
      const target = document.querySelector(href);
      if (!target) return;
      e.preventDefault();
      const top = target.getBoundingClientRect().top + window.scrollY - HEADER_OFFSET;
      smoothScrollTo(top);
    };
    document.addEventListener("click", onClick);
    return () => {
      document.removeEventListener("click", onClick);
      cancelAnimationFrame(activeAnim);
    };
  }, []);

  return (
    <main>
      <GlobalCursor />
      <Header />
      <Hero />
      <ScaleSection />
      <FeaturedClients />
      <Performance />
      <Services />
      <CTA />
      <Footer />
    </main>
  );
}

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