"use client";

import {
  motion,
  useReducedMotion,
  useScroll,
  useTransform,
} from "framer-motion";
import { Logo } from "../ui/Logo";
import { ButtonLink } from "../ui/ButtonLink";
import { HERO_VIDEO, STUDIO } from "@/lib/site";
import { EASE_OUT_EXPO } from "@/lib/motion";

/**
 * Full-height hero.
 *
 * The dark plate sits under the video, so the headline is readable from the
 * first paint — before the background has loaded, and for visitors who have
 * reduced motion enabled (they get no video at all).
 *
 * Layout note: everything is in normal flow — the scroll hint is NOT absolutely
 * positioned. On a laptop (wide but only ~900px tall) an absolute hint sat on
 * top of the buttons. Spacing and type are clamped against `vh` so the block
 * shrinks with the viewport height instead of overflowing it.
 */
export function HomeHero() {
  const reduced = useReducedMotion();

  // Skip entrance animations entirely when reduced motion is requested.
  const fade = (delay: number) =>
    reduced
      ? {}
      : {
          initial: { opacity: 0, y: 24 },
          animate: { opacity: 1, y: 0 },
          transition: { duration: 0.8, delay, ease: "easeOut" as const },
        };

  /**
   * Scroll response. The video drifts slower than the page and the copy
   * dissolves before the section ends, so the hero hands over to the next band
   * instead of sliding out of frame intact. Page scroll is read directly —
   * the hero is always at offset 0, so there is nothing to measure.
   */
  const { scrollY } = useScroll();
  const videoY = useTransform(scrollY, [0, 800], [0, 150], { clamp: true });
  const contentY = useTransform(scrollY, [0, 600], [0, 70], { clamp: true });
  // Holds at full strength for the first 100px: a visitor who nudges the wheel
  // to see whether the page moves should not find the headline already faded.
  const contentOpacity = useTransform(scrollY, [100, 560], [1, 0], {
    clamp: true,
  });
  const hintOpacity = useTransform(scrollY, [0, 180], [1, 0], { clamp: true });

  return (
    <section className="relative isolate flex min-h-[100svh] flex-col overflow-hidden bg-background px-6 pt-[max(6rem,10vh)] pb-[clamp(1.5rem,4vh,2.5rem)] lg:px-10">
      {!reduced && (
        // Taller than the section and pulled up, so the parallax never
        // uncovers the bottom edge of the frame.
        <motion.video
          autoPlay
          muted
          loop
          playsInline
          preload="metadata"
          poster={HERO_VIDEO.poster ?? undefined}
          aria-hidden
          tabIndex={-1}
          style={{ y: videoY }}
          className="absolute -top-[10%] left-0 z-0 h-[120%] w-full object-cover"
        >
          <source src={HERO_VIDEO.src} type="video/mp4" />
        </motion.video>
      )}

      {/* Readability scrim: flat tint + vignette, in a single layer */}
      <div
        aria-hidden
        className="absolute inset-0 z-10 bg-background/65"
        style={{
          backgroundImage:
            "radial-gradient(ellipse at 50% 45%, rgba(10,10,10,0) 25%, rgba(10,10,10,0.9) 100%)",
        }}
      />

      <motion.div
        style={reduced ? undefined : { y: contentY, opacity: contentOpacity }}
        className="relative z-20 mx-auto flex w-full max-w-4xl flex-1 flex-col items-center justify-center text-center"
      >
        <motion.div
          {...(reduced
            ? {}
            : {
                initial: { opacity: 0, scale: 0.94 },
                animate: { opacity: 1, scale: 1 },
                transition: { duration: 1, ease: EASE_OUT_EXPO },
              })}
          className="mb-[clamp(1.5rem,4vh,2.5rem)]"
        >
          <Logo
            width={200}
            priority
            className="h-auto w-[clamp(110px,13vh,200px)] drop-shadow-[0_0_40px_rgba(196,184,150,0.2)]"
          />
        </motion.div>

        <motion.h1
          {...fade(0.25)}
          className="font-display text-[min(3rem,12vh)] leading-[0.95] tracking-wider text-balance sm:text-[min(4.5rem,12vh)] lg:text-[min(6rem,12vh)]"
        >
          HIGHLAND GAMES
          <br />
          <span className="text-accent">STUDIO</span>
        </motion.h1>

        <motion.p
          {...fade(0.45)}
          className="mt-[clamp(1.25rem,3vh,2rem)] max-w-xl text-lg tracking-wide text-foreground-muted text-balance sm:text-xl"
        >
          {STUDIO.tagline}
        </motion.p>

        <motion.div
          {...fade(0.65)}
          className="mt-[clamp(1.75rem,4vh,3rem)] flex w-full flex-col items-center gap-4 sm:w-auto sm:flex-row"
        >
          <ButtonLink href="/games" block>
            EXPLORE OUR GAMES
          </ButtonLink>
          <ButtonLink href="/studio" variant="outline" block>
            MEET THE STUDIO
          </ButtonLink>
        </motion.div>
      </motion.div>

      {!reduced && (
        // Fades on the first flick of the wheel: an invitation to scroll that
        // is still there once you have is just decoration. Two layers, because
        // one element cannot hold both a load-time `animate` opacity and a
        // scroll-driven one.
        <motion.div
          style={{ opacity: hintOpacity }}
          aria-hidden
          className="relative z-20 mt-[clamp(1.5rem,3vh,2.5rem)] flex shrink-0 flex-col items-center self-center"
        >
          <motion.div
            initial={{ opacity: 0 }}
            animate={{ opacity: 1 }}
            transition={{ delay: 1.4, duration: 0.8 }}
            className="flex flex-col items-center gap-2 text-xs tracking-widest text-foreground-muted"
          >
            <span className="font-display">SCROLL</span>
            <motion.span
              animate={{ y: [0, 8, 0] }}
              transition={{ duration: 1.8, repeat: Infinity, ease: "easeInOut" }}
              className="block h-[clamp(1.25rem,3vh,2rem)] w-px bg-foreground-muted"
            />
          </motion.div>
        </motion.div>
      )}
    </section>
  );
}
