"use client";

import { useEffect, useRef, useState } from "react";
import { AnimatePresence, motion } from "framer-motion";
import { ArrowRight } from "@/components/ui/icons";
import AnimatedButton from "@/components/ui/AnimatedButton";

/**
 * Thumbnail-slider hero. Full-bleed background, content left, preview deck
 * bottom-right. Slide changes reveal the new image through an expanding
 * circle anchored to the clicked card — every image layer stays full-bleed
 * and is only clipped/uniformly transformed, so distortion is impossible.
 *
 * Swap the slide images in /public/images/opt (optimized WebP — run
 * scripts/optimize-images.mjs after adding new source images).
 */
const SLIDES = [
  {
    id: "game",
    image: "/images/opt/Pillar1.webp",
    tag: "Game Development",
    title: "Game Development",
    desc: "Immersive 2D, 3D, AR/VR and multiplayer games — from concept and art to live ops.",
  },
  {
    id: "data",
    image: "/images/opt/HeroBanner3.png",
    tag: "Data Analytics & AI",
    title: "Data Analytics & AI",
    desc: "BI, predictive analytics and AI that turn raw data into decisions and automation.",
  },
  {
    id: "web",
    image: "/images/opt/HeroBanner1.webp",
    tag: "Web Development",
    title: "Web Development",
    desc: "Web apps, custom software and cloud — engineered on a modern stack to scale.",
  },
  {
    id: "media",
    image: "/images/opt/HeroBanner2.webp",
    tag: "Media & Creative",
    title: "Media & Creative",
    desc: "Branding, video, motion and social creative that commands attention.",
  },
];

const EASE = [0.76, 0, 0.24, 1];

export default function HeroSlider() {
  const [active, setActive] = useState(0);
  const [committed, setCommitted] = useState(0); // base layer slide
  const [origin, setOrigin] = useState({ x: 80, y: 78 }); // reveal origin (%)
  const sectionRef = useRef(null);
  const firstCardRef = useRef(null);
  const len = SLIDES.length;
  const slide = SLIDES[active];
  const revealing = active !== committed;

  // upcoming preview cards (next 3, wrapping)
  const upcoming = [1, 2, 3].map((o) => (active + o) % len);

  /** Jump to a slide; the circle reveal grows out of `el` (or the 1st card). */
  const go = (idx, el) => {
    if (idx === active) return;
    // If a reveal is still mid-flight, lock its image in as the base first —
    // otherwise aborting it would flash the older slide underneath.
    if (revealing) setCommitted(active);
    const cardEl = el || firstCardRef.current;
    const s = sectionRef.current?.getBoundingClientRect();
    if (cardEl && s) {
      const c = cardEl.getBoundingClientRect();
      setOrigin({
        x: ((c.left + c.width / 2 - s.left) / s.width) * 100,
        y: ((c.top + c.height / 2 - s.top) / s.height) * 100,
      });
    }
    setActive(idx);
  };
  const next = () => go((active + 1) % len);
  const prev = () => go((active - 1 + len) % len);

  // Warm all slide images once so the first reveals never wipe in a
  // not-yet-decoded (blank) layer on a cold cache.
  useEffect(() => {
    SLIDES.forEach((s) => {
      const img = new window.Image();
      img.src = s.image;
    });
  }, []);

  // auto-advance; resets whenever active changes
  useEffect(() => {
    const id = setTimeout(next, 5200);
    return () => clearTimeout(id);
  }, [active]);

  return (
    <section ref={sectionRef} className="relative h-[calc(100svh-5rem)] overflow-hidden">
      {/* Base layer — committed slide (pushes back during reveal, Ken Burns
          idle). On commit it snaps back instantly — the reveal layer covers
          the swap, so no visible zoom/brightness shift on the new image. */}
      <div
        className="absolute inset-0 -z-30 overflow-hidden"
        style={{
          // Inline styles update in the same frame as React's commit — using
          // framer here lagged one frame behind the reveal unmount and caused
          // an intermittent dim/zoom blink on the fresh image.
          transform: revealing ? "scale(1.06)" : "scale(1)",
          opacity: revealing ? 0.75 : 1,
          transition: revealing
            ? "transform 1.3s cubic-bezier(0.76,0,0.24,1), opacity 1.3s cubic-bezier(0.76,0,0.24,1)"
            : "none",
        }}
      >
        <div
          key={SLIDES[committed].id}
          className="h-full w-full animate-kenburns"
          style={{
            backgroundImage: `url(${SLIDES[committed].image})`,
            backgroundSize: "cover",
            backgroundPosition: "center",
          }}
        />
      </div>

      {/* Reveal layer — full-bleed new slide, clipped by an expanding circle.
          The layer itself never resizes → no distortion, ever. */}
      {revealing && (
        <motion.div
          key={`${slide.id}-${origin.x}-${origin.y}`}
          initial={{ clipPath: `circle(0% at ${origin.x}% ${origin.y}%)` }}
          animate={{ clipPath: `circle(150% at ${origin.x}% ${origin.y}%)` }}
          transition={{ duration: 1.3, ease: EASE }}
          onAnimationComplete={() => setCommitted(active)}
          className="absolute inset-0 -z-20 will-change-[clip-path]"
          style={{
            backgroundImage: `url(${slide.image})`,
            backgroundSize: "cover",
            backgroundPosition: "center",
          }}
        />
      )}

      {/* Legibility overlays */}
      <div className="absolute inset-0 -z-10 bg-gradient-to-r from-background via-background/60 to-background/20" />
      <div className="absolute inset-0 -z-10 bg-gradient-to-t from-background via-transparent to-background/40" />

      {/* Content */}
      <div className="container relative flex h-full flex-col justify-center">
        <span className="hidden w-fit items-center gap-2 rounded-full border border-border bg-surface/50 px-4 py-1.5 text-xs font-semibold uppercase tracking-wider text-muted-foreground backdrop-blur sm:inline-flex">
          <span className="relative flex h-2 w-2">
            <span className="absolute inline-flex h-full w-full animate-ping rounded-full bg-accent opacity-75" />
            <span className="relative inline-flex h-2 w-2 rounded-full bg-accent" />
          </span>
          Build. Analyze. Create. Grow.
        </span>

        <h1 className="mt-6 max-w-3xl font-heading text-4xl font-bold leading-[1.08] tracking-tight text-foreground drop-shadow-[0_2px_30px_rgba(0,0,0,0.6)] sm:text-5xl md:text-6xl">
          Building digital experiences that{" "}
          <span className="animate-text-shimmer bg-gradient-to-r from-primary via-accent to-primary bg-clip-text text-transparent">
            drive growth.
          </span>
        </h1>

        <AnimatePresence mode="wait">
          <motion.div
            key={slide.id}
            initial={{ opacity: 0, y: 20 }}
            animate={{ opacity: 1, y: 0 }}
            exit={{ opacity: 0, y: -20 }}
            transition={{ duration: 0.5, ease: EASE }}
            className="mt-5 max-w-xl"
          >
            <span className="text-sm font-semibold uppercase tracking-wider text-primary">
              {slide.tag}
            </span>
            <p className="mt-2 max-w-xl text-base text-muted-foreground sm:text-lg">{slide.desc}</p>
          </motion.div>
        </AnimatePresence>

        <div className="mt-8 flex flex-wrap items-center gap-4">
          <AnimatedButton href="/contact">Start a project</AnimatedButton>
        </div>
      </div>

      {/* Bottom-right preview deck */}
      <div className="absolute bottom-6 right-4 z-20 flex items-center gap-3 sm:bottom-10 sm:right-10">
        <AnimatePresence mode="popLayout" initial={false}>
          {upcoming.map((idx, pos) => {
            const s = SLIDES[idx];
            return (
              <motion.button
                key={s.id}
                ref={pos === 0 ? firstCardRef : undefined}
                layout
                initial={{ opacity: 0, x: 70, scale: 0.85 }}
                animate={{ opacity: 1, x: 0, scale: 1 }}
                exit={{ opacity: 0, x: -70, scale: 0.85 }}
                transition={{ duration: 0.55, ease: EASE }}
                onClick={(e) => go(idx, e.currentTarget)}
                aria-label={`Show ${s.title}`}
                className="group relative h-24 w-32 shrink-0 overflow-hidden rounded-2xl border border-white/20 shadow-xl shadow-black/50 sm:h-36 sm:w-52"
              >
                <span
                  className="block h-full w-full bg-cover bg-center transition-transform duration-500 group-hover:scale-110"
                  style={{ backgroundImage: `url(${s.image})` }}
                />
                <span className="absolute inset-0 bg-gradient-to-t from-black/70 via-transparent to-transparent" />
                <span className="absolute bottom-2 left-2.5 text-xs font-semibold text-white">
                  {s.tag}
                </span>
              </motion.button>
            );
          })}
        </AnimatePresence>

        {/* Arrows */}
        <div className="ml-1 flex flex-col gap-2">
          <button
            onClick={prev}
            aria-label="Previous"
            className="flex h-10 w-10 items-center justify-center rounded-full border border-white/25 bg-surface/40 text-foreground backdrop-blur transition-colors hover:border-primary hover:text-primary"
          >
            <ArrowRight className="h-4 w-4 rotate-180" />
          </button>
          <button
            onClick={next}
            aria-label="Next"
            className="flex h-10 w-10 items-center justify-center rounded-full border border-white/25 bg-surface/40 text-foreground backdrop-blur transition-colors hover:border-primary hover:text-primary"
          >
            <ArrowRight className="h-4 w-4" />
          </button>
        </div>
      </div>

      {/* Progress dots */}
      <div className="absolute bottom-6 left-4 z-20 flex gap-2 sm:left-10">
        {SLIDES.map((s, i) => (
          <button
            key={s.id}
            onClick={() => go(i)}
            aria-label={`Go to ${s.title}`}
            className={
              "h-1.5 rounded-full transition-all " +
              (i === active ? "w-7 bg-primary" : "w-3 bg-foreground/30 hover:bg-foreground/60")
            }
          />
        ))}
      </div>
    </section>
  );
}
