"use client";

/**
 * HERO — the signature moment. One orchestrated, choreographed page-load with
 * staggered reveals (the single highest-impact "alive" moment on the page).
 *   - Real background VIDEO (autoplay/muted/loop/playsinline, poster, cover,
 *     deferred load via IO, paused on hidden tab; reduced-motion -> poster only).
 *   - ANIMATED SVG: a revenue growth line that DRAWS itself (GSAP DrawSVG) with
 *     an area fill that fades up, grid ticks that draw in, and a "live" marker
 *     that springs in then pulses.
 *   - Headline revealed line-by-line behind a mask (clip + yPercent) with the
 *     custom expo curve; eyebrow/sub/CTAs/trust stagger up with a blur mask.
 *   - Pointer spotlight (spring-smoothed via CSS var) + parallax on scroll.
 *   - Custom easing personality throughout; honors prefers-reduced-motion.
 */
import { useEffect, useRef } from "react";
import Link from "next/link";
import { gsap, SplitText } from "./gsap";
import Magnetic from "./Magnetic";
import { SITE } from "../content";

/* Custom GSAP eases that mirror the CSS tokens (registered once, idempotent). */
gsap.registerEase?.("emilOut", (p) => {
  // approximates cubic-bezier(0.23,1,0.32,1) feel — strong, soft landing
  return 1 - Math.pow(1 - p, 3.2);
});

export default function Hero() {
  const root = useRef<HTMLDivElement>(null);
  const videoRef = useRef<HTMLVideoElement>(null);
  // Spring-smoothed spotlight target so the glow trails the cursor with momentum
  // instead of snapping to raw pointer position.
  const target = useRef({ x: 50, y: 40 });
  const current = useRef({ x: 50, y: 40 });

  const onPointerMove = (e: React.PointerEvent) => {
    const el = root.current;
    if (!el) return;
    const r = el.getBoundingClientRect();
    target.current.x = ((e.clientX - r.left) / r.width) * 100;
    target.current.y = ((e.clientY - r.top) / r.height) * 100;
  };

  useEffect(() => {
    const el = root.current;
    if (!el) return;
    const reduce = window.matchMedia("(prefers-reduced-motion: reduce)").matches;

    // --- spotlight: lerp current toward target each frame (momentum) ---
    let rafId = 0;
    if (!reduce) {
      const tick = () => {
        current.current.x += (target.current.x - current.current.x) * 0.08;
        current.current.y += (target.current.y - current.current.y) * 0.08;
        el.style.setProperty("--mx", `${current.current.x}%`);
        el.style.setProperty("--my", `${current.current.y}%`);
        rafId = requestAnimationFrame(tick);
      };
      rafId = requestAnimationFrame(tick);
    }

    const video = videoRef.current;
    let io: IntersectionObserver | null = null;
    let onVis: (() => void) | null = null;

    if (!reduce) {
      if (video) {
        io = new IntersectionObserver(
          ([entry]) => {
            if (entry.isIntersecting) video.play().catch(() => {});
            else video.pause();
          },
          { threshold: 0.1 }
        );
        io.observe(video);
        onVis = () => {
          if (document.hidden) video.pause();
          else if (video.getBoundingClientRect().top < window.innerHeight)
            video.play().catch(() => {});
        };
        document.addEventListener("visibilitychange", onVis);
      }

      const ctx = gsap.context(() => {
        // 1) Headline: split into lines+words, reveal each line from behind a
        //    mask (overflow hidden on lines) with a deliberate stagger.
        const split = new SplitText(".hero__h1", {
          type: "lines,words",
          linesClass: "hero__line",
        });
        gsap.set(".hero__h1", { autoAlpha: 1 });
        gsap.set(".hero__line", { overflow: "hidden" });
        gsap.from(split.words, {
          yPercent: 118,
          duration: 1.15,
          ease: "emilOut",
          stagger: 0.045,
          delay: 0.2,
        });

        // 2) Eyebrow, sub, CTAs, trust — lift + blur mask, tight stagger.
        gsap.set(".hero__stagger", { autoAlpha: 0 });
        gsap.to(".hero__stagger", {
          autoAlpha: 1,
          y: 0,
          filter: "blur(0px)",
          duration: 1,
          ease: "emilOut",
          stagger: 0.07,
          delay: 0.55,
          startAt: { y: 26, filter: "blur(5px)" },
        });

        // 3) ANIMATED SVG — grid draws, the revenue line draws itself, area
        //    fades up, the live marker springs in (back ease => overshoot).
        gsap.set(".hero-svg__area", { autoAlpha: 0 });
        const tl = gsap.timeline({ delay: 0.45 });
        tl.from(".hero-svg__grid line", {
          drawSVG: "0%",
          duration: 0.9,
          stagger: 0.06,
          ease: "power2.out",
        })
          .from(
            ".hero-svg__line",
            { drawSVG: "0%", duration: 2, ease: "power2.inOut" },
            "-=0.5"
          )
          .to(".hero-svg__area", { autoAlpha: 1, duration: 1 }, "-=1.2")
          .from(
            ".hero-svg__dot",
            {
              scale: 0,
              transformOrigin: "center",
              duration: 0.6,
              ease: "back.out(2.2)",
            },
            "-=0.5"
          )
          .from(
            ".hero-svg__dot-ring",
            { scale: 0.4, autoAlpha: 0, transformOrigin: "center", duration: 0.6, ease: "emilOut" },
            "<"
          );

        // 4) Parallax: video drifts slower; content + SVG drift at different
        //    rates as you scroll away => layered depth.
        gsap.to(".hero__media", {
          yPercent: 16,
          ease: "none",
          scrollTrigger: { trigger: el, start: "top top", end: "bottom top", scrub: 0.6 },
        });
        gsap.to(".hero-svg", {
          yPercent: 8,
          ease: "none",
          scrollTrigger: { trigger: el, start: "top top", end: "bottom top", scrub: 0.6 },
        });
        gsap.to(".hero__content", {
          yPercent: -10,
          opacity: 0.3,
          ease: "none",
          scrollTrigger: { trigger: el, start: "top top", end: "bottom top", scrub: 0.6 },
        });
      }, el);

      return () => {
        cancelAnimationFrame(rafId);
        io?.disconnect();
        if (onVis) document.removeEventListener("visibilitychange", onVis);
        ctx.revert();
      };
    }

    // Reduced motion: reveal everything statically, show poster only.
    gsap.set([".hero__h1", ".hero__stagger", ".hero-svg__area"], {
      autoAlpha: 1,
      y: 0,
      filter: "none",
    });
    return () => cancelAnimationFrame(rafId);
  }, []);

  return (
    <section
      ref={root}
      className="hero"
      aria-labelledby="hero-h1"
      onPointerMove={onPointerMove}
    >
      {/* ---- background video (deferred) + poster + scrims ---- */}
      <div className="hero__media" aria-hidden="true">
        <video
          ref={videoRef}
          className="hero__video"
          poster="/assets/hero-poster.jpg"
          muted
          loop
          playsInline
          preload="none"
        >
          <source src="/assets/hero.mp4" type="video/mp4" />
        </video>
        <div className="hero__scrim" />
        <div className="hero__spotlight" />
        <div className="hero__noise" />
      </div>

      {/* ---- animated SVG growth chart ---- */}
      <svg
        className="hero-svg"
        viewBox="0 0 1200 600"
        preserveAspectRatio="xMidYMid slice"
        aria-hidden="true"
      >
        <defs>
          <linearGradient id="heroLine" x1="0" y1="0" x2="1" y2="0">
            <stop offset="0%" stopColor="#3b82f6" />
            <stop offset="55%" stopColor="#8b5cf6" />
            <stop offset="100%" stopColor="#10b981" />
          </linearGradient>
          <linearGradient id="heroArea" x1="0" y1="0" x2="0" y2="1">
            <stop offset="0%" stopColor="#8b5cf6" stopOpacity="0.35" />
            <stop offset="100%" stopColor="#8b5cf6" stopOpacity="0" />
          </linearGradient>
        </defs>
        <g className="hero-svg__grid">
          <line x1="0" y1="150" x2="1200" y2="150" />
          <line x1="0" y1="300" x2="1200" y2="300" />
          <line x1="0" y1="450" x2="1200" y2="450" />
        </g>
        <path
          className="hero-svg__area"
          fill="url(#heroArea)"
          d="M0,520 C160,520 220,470 340,430 C470,388 520,300 660,290 C820,278 880,160 1040,120 C1110,102 1160,92 1200,86 L1200,600 L0,600 Z"
        />
        <path
          className="hero-svg__line"
          fill="none"
          stroke="url(#heroLine)"
          strokeWidth="4"
          strokeLinecap="round"
          d="M0,520 C160,520 220,470 340,430 C470,388 520,300 660,290 C820,278 880,160 1040,120 C1110,102 1160,92 1200,86"
        />
        <circle className="hero-svg__dot-ring" cx="1200" cy="86" r="18" fill="none" stroke="#10b981" strokeWidth="1.5" opacity="0.5" />
        <circle className="hero-svg__dot" cx="1200" cy="86" r="9" fill="#10b981" />
      </svg>

      {/* ---- content ---- */}
      <div className="hero__content wrap">
        <p className="hero__eyebrow hero__stagger">
          <span className="hero__live" aria-hidden="true" />
          Results-driven digital marketing agency
        </p>

        <h1 id="hero-h1" className="hero__h1">
          Marketing that grows your <span className="grad">revenue.</span>
        </h1>

        <p className="hero__sub hero__stagger">
          We run paid, SEO, and content programs built around your revenue
          targets, then show you exactly what they returned. Every month.
        </p>

        <div className="hero__cta hero__stagger">
          <Magnetic strength={0.4}>
            <Link
              href={SITE.booking}
              className="btn btn--accent"
              data-cursor="Book it"
            >
              Get your growth audit
            </Link>
          </Magnetic>
          <Magnetic strength={0.3}>
            <a href="#work" className="btn btn--ghost" data-cursor="See proof">
              See the results <span className="arrow" aria-hidden="true">→</span>
            </a>
          </Magnetic>
        </div>

        <dl className="hero__trust hero__stagger">
          <div>
            <dt>$40M+</dt>
            <dd>in client revenue generated</dd>
          </div>
          <div className="hero__trust-div" aria-hidden="true" />
          <div>
            <dt>50+</dt>
            <dd>brands grown</dd>
          </div>
        </dl>
      </div>

      <a
        href="#manifesto"
        className="hero__scroll hero__stagger"
        aria-label="Scroll to content"
      >
        <span className="hero__scroll-line" aria-hidden="true" />
        Scroll
      </a>
    </section>
  );
}
