"use client";

// components/landing/PrizeSlider.tsx
// §1.2 "Big prize banner — the hook." A rotating banner that cycles through
// slides every ~5s: current-period prizes, then previous winners, etc. This is a
// SHELL built to slot the team's delivered art (Alex + Churchill): pass real
// slides (banner artwork + the inspirational beneficiary image) via the `slides`
// prop. Until the art lands, the landing feeds it the confirmed prizes so the
// banner is never empty, and a calm placeholder shows when there is nothing yet.
//
// Accessibility (WCAG 2.2.2 pause/stop/hide): auto-advance pauses on hover and
// keyboard focus and is fully disabled under prefers-reduced-motion. Slides are
// navigable by dots; the active slide is announced politely. The crossfade is a
// pure CSS opacity transition (no GSAP dependency at the call site), so it
// degrades to an instant swap when motion is reduced.

import * as React from "react";
import { AnimatedHeading } from "./AnimatedHeading";

export interface PrizeSlide {
  id: string;
  /** Optional banner image (sponsor/host art lives off our remotePatterns, so a
   *  plain lazy <img> is used, matching PrizeGrid). */
  imageUrl?: string | null;
  /** Small eyebrow tag, e.g. "Premio destacado" or "Ganador anterior". */
  kicker?: string;
  title: string;
  caption?: string;
}

function usePrefersReducedMotion(): boolean {
  const [reduced, setReduced] = React.useState(false);
  React.useEffect(() => {
    if (typeof window === "undefined" || !window.matchMedia) return;
    const mq = window.matchMedia("(prefers-reduced-motion: reduce)");
    const update = () => setReduced(mq.matches);
    update();
    mq.addEventListener?.("change", update);
    return () => mq.removeEventListener?.("change", update);
  }, []);
  return reduced;
}

export interface PrizeSliderProps {
  slides: PrizeSlide[];
  /** Auto-advance interval. Defaults to 5s per the brief. */
  intervalMs?: number;
  className?: string;
}

export function PrizeSlider({
  slides,
  intervalMs = 5000,
  className = "",
}: PrizeSliderProps) {
  const reduced = usePrefersReducedMotion();
  const [active, setActive] = React.useState(0);
  const [paused, setPaused] = React.useState(false);
  const count = slides.length;
  // Clamp during render (never in an effect) so a shrinking slide set can never
  // leave the shown index out of range, with no setState-in-effect.
  const safeActive = count > 0 ? Math.min(active, count - 1) : 0;

  // Auto-advance. Disabled when there is one (or no) slide, when paused
  // (hover/focus), or when the user prefers reduced motion.
  React.useEffect(() => {
    if (reduced || paused || count < 2) return;
    const id = window.setInterval(() => {
      setActive((i) => (i + 1) % count);
    }, intervalMs);
    return () => window.clearInterval(id);
  }, [reduced, paused, count, intervalMs]);

  if (count === 0) {
    return (
      <section
        aria-label="Premios de la rifa"
        className={["bg-canvas px-5 pt-section", className].filter(Boolean).join(" ")}
      >
        <div className="mx-auto flex aspect-[16/9] max-w-[1100px] flex-col items-center justify-center gap-2 rounded-2xl border border-dashed border-hairline bg-track/40 px-6 text-center sm:aspect-[21/9]">
          <span className="font-impact text-heading-lg font-bold text-muted opacity-50">
            Teletón
          </span>
          <p className="max-w-[44ch] font-body text-body-md text-muted">
            Pronto verás aquí los premios de la Rifa Solidaria.
          </p>
        </div>
      </section>
    );
  }

  return (
    <section
      aria-roledescription="carrusel"
      aria-label="Premios de la rifa"
      className={["bg-canvas px-5 pt-section", className].filter(Boolean).join(" ")}
      onMouseEnter={() => setPaused(true)}
      onMouseLeave={() => setPaused(false)}
      onFocusCapture={() => setPaused(true)}
      onBlurCapture={() => setPaused(false)}
    >
      <div className="relative mx-auto aspect-[16/9] max-w-[1100px] overflow-hidden rounded-2xl bg-primary text-on-primary shadow-drop sm:aspect-[21/9]">
        {slides.map((slide, i) => {
          const isActive = i === safeActive;
          return (
            <article
              key={slide.id}
              aria-hidden={!isActive}
              aria-roledescription="diapositiva"
              aria-label={`${i + 1} de ${count}`}
              className="absolute inset-0 flex flex-col justify-end"
              style={{
                opacity: isActive ? 1 : 0,
                transition: reduced ? "none" : "opacity 0.6s ease",
                pointerEvents: isActive ? "auto" : "none",
              }}
            >
              {slide.imageUrl ? (
                // eslint-disable-next-line @next/next/no-img-element
                <img
                  src={slide.imageUrl}
                  alt={slide.title}
                  loading={i === 0 ? "eager" : "lazy"}
                  decoding="async"
                  className="absolute inset-0 h-full w-full object-cover"
                />
              ) : (
                <span
                  aria-hidden="true"
                  className="absolute inset-0 flex items-center justify-center font-impact text-display-sm font-bold text-on-primary/15"
                >
                  Teletón
                </span>
              )}
              {/* Legibility scrim under the copy. */}
              <div className="absolute inset-x-0 bottom-0 h-2/3 bg-gradient-to-t from-black/65 to-transparent" />
              <div className="relative z-10 flex flex-col gap-1 p-6 sm:p-8">
                {slide.kicker ? (
                  <span className="font-body text-caption font-bold uppercase tracking-wide text-on-primary/90">
                    {slide.kicker}
                  </span>
                ) : null}
                <AnimatedHeading
                  as="h2"
                  className="font-display text-heading-lg font-extrabold tracking-tight text-on-primary sm:text-display-sm"
                >
                  {slide.title}
                </AnimatedHeading>
                {slide.caption ? (
                  <p className="max-w-[52ch] font-body text-body-md text-on-primary/90">
                    {slide.caption}
                  </p>
                ) : null}
              </div>
            </article>
          );
        })}
      </div>

      {/* Dots: manual navigation + the active announcement. */}
      {count > 1 ? (
        <div className="mx-auto mt-4 flex max-w-[1100px] items-center justify-center gap-2">
          {slides.map((slide, i) => (
            <button
              key={slide.id}
              type="button"
              aria-label={`Ir a la diapositiva ${i + 1}`}
              aria-current={i === safeActive}
              onClick={() => setActive(i)}
              className={[
                "h-2.5 rounded-full transition-all focus-visible:outline focus-visible:outline-[3px] focus-visible:outline-offset-2 focus-visible:outline-steelblue",
                i === safeActive ? "w-6 bg-primary" : "w-2.5 bg-track hover:bg-muted/50",
              ].join(" ")}
            />
          ))}
        </div>
      ) : null}
    </section>
  );
}
