"use client";

import { useEffect, useRef } from "react";
import { motion, useMotionValue, useMotionValueEvent, useReducedMotion, useScroll, useTransform } from "motion/react";
import { useState } from "react";
import Icon from "@/components/ui/Icon";
import { searchSuggestions } from "@/data/home";
import { media } from "@/config/media";

const ease = [0.2, 0.7, 0.2, 1] as const;
const cine = [0.77, 0, 0.175, 1] as const;

/* Intro choreography (seconds). Each beat leads into the next. */
export const INTRO = { media: 0, nav: 0.9, title: 1.0, sub: 1.55, cta: 1.7, foot: 1.95 };

const rise = (delay: number, reduce: boolean | null) => ({
  initial: reduce ? (false as const) : { opacity: 0, y: 24 },
  animate: { opacity: 1, y: 0 },
  transition: { duration: 0.8, delay, ease },
});

export default function Hero() {
  const reduce = useReducedMotion();
  const videoRef = useRef<HTMLVideoElement>(null);
  const { scrollY } = useScroll();
  const vh = useMotionValue(900);
  const [q, setQ] = useState("");

  useEffect(() => {
    const set = () => vh.set(window.innerHeight);
    set();
    window.addEventListener("resize", set);
    return () => window.removeEventListener("resize", set);
  }, [vh]);

  // Scroll-linked recede while the cream sheet rises over the hero (transform/opacity only).
  const contentY = useTransform([scrollY, vh], ([y, h]: number[]) => (reduce ? 0 : -(Math.min(y, h) / h) * 90));
  const contentOpacity = useTransform([scrollY, vh], ([y, h]: number[]) => (reduce ? 1 : 1 - Math.min(y / (h * 0.55), 1)));
  const mediaScale = useTransform([scrollY, vh], ([y, h]: number[]) => (reduce ? 1 : 1 + (Math.min(y, h) / h) * 0.12));
  const fade = useTransform([scrollY, vh], ([y, h]: number[]) => (reduce ? 0 : Math.min(y / h, 1) * 0.65));

  // Stop decoding video frames once the sheet fully covers the hero.
  useMotionValueEvent(scrollY, "change", (y) => {
    const v = videoRef.current;
    if (!v || reduce) return;
    if (y > vh.get() * 1.05) v.pause();
    else if (v.paused) v.play().catch(() => {});
  });

  useEffect(() => {
    if (reduce) videoRef.current?.pause();
  }, [reduce]);

  const { video, videoWebm, poster, caption } = media.hero;

  return (
    <section className="hero" id="top" aria-label="Discover Syria">
      <motion.div
        className="hero-media"
        initial={reduce ? false : { clipPath: "inset(13% 9% 13% 9% round 28px)" }}
        animate={{ clipPath: "inset(0% 0% 0% 0% round 0px)" }}
        transition={{ duration: 1.4, delay: INTRO.media, ease: cine }}
      >
        <motion.div
          className="hero-media-inner"
          initial={reduce ? false : { scale: 1.28 }}
          animate={{ scale: 1 }}
          transition={{ duration: 2.2, delay: INTRO.media, ease }}
        >
          <motion.div className="hero-media-inner" style={{ scale: mediaScale }}>
            {video ? (
              <video
                ref={videoRef}
                className="hero-video"
                autoPlay={!reduce}
                muted
                loop
                playsInline
                preload="metadata"
                poster={poster ?? undefined}
                aria-hidden="true"
              >
                {videoWebm && <source src={videoWebm} type="video/webm" />}
                <source src={video} type="video/mp4" />
              </video>
            ) : poster ? (
              <img className="hero-video" src={poster} alt="" />
            ) : (
              <div className="hero-placeholder" />
            )}
          </motion.div>
        </motion.div>
        <div className="hero-scrim" />
        <motion.div className="hero-fade" style={{ opacity: fade }} />
      </motion.div>

      {!video && !poster && (
        <motion.span className="hero-slot-note" {...rise(INTRO.foot, reduce)}>
          hero video slot: src/config/media.ts
        </motion.span>
      )}

      <motion.div className="hero-content" style={{ y: contentY, opacity: contentOpacity }}>
        <div className="wrap">
          <div className="hero-grid">
            <h1 className="hero-title">
              {["Discover", "Syria"].map((w, i) => (
                <span className="line" key={w}>
                  <motion.span
                    className={`word${i === 1 ? " accent" : ""}`}
                    initial={reduce ? false : { y: "112%" }}
                    animate={{ y: "0%" }}
                    transition={{ duration: 1.05, delay: INTRO.title + i * 0.12, ease }}
                  >
                    {w}
                  </motion.span>
                </span>
              ))}
            </h1>

            <div className="hero-side">
              <motion.p className="hero-sub" {...rise(INTRO.sub, reduce)}>
                From the souqs of Damascus to the colonnades of Palmyra and the coast of Latakia.
              </motion.p>
              <motion.div {...rise(INTRO.cta, reduce)}>
                <form className="search" role="search" onSubmit={(e) => e.preventDefault()}>
                  <Icon name="search" />
                  <label>
                    <span>Where do you want to go?</span>
                    <input
                      type="search"
                      value={q}
                      onChange={(e) => setQ(e.target.value)}
                      placeholder="Search places, food, stays"
                    />
                  </label>
                  <button className="btn btn-rose" type="submit">Search</button>
                </form>
                <div className="suggest">
                  {searchSuggestions.map((x) => (
                    <button key={x} type="button" className="chip" aria-pressed={q === x} onClick={() => setQ(x)}>
                      {x}
                    </button>
                  ))}
                </div>
              </motion.div>
            </div>
          </div>

          <motion.div className="hero-foot" {...rise(INTRO.foot, reduce)}>
            <span className="hero-caption">
              <Icon name="location_on" />
              {caption}
            </span>
            <a className="scroll-cue" href="#intro" aria-label="Scroll to content">
              <span>Scroll</span>
              <span className="scroll-cue-line" aria-hidden="true" />
            </a>
          </motion.div>
        </div>
      </motion.div>
    </section>
  );
}
