"use client";

import Image from "next/image";
import { useCallback, useEffect, useState } from "react";

import type { SliderPhoto } from "@/lib/slider-photos";

const ROTATE_MS = 5500;

function PromoStripSingleSlide({
  photos,
  activeIndex,
}: {
  photos: SliderPhoto[];
  activeIndex: number;
}) {
  const n = photos.length;

  return (
    <div className="relative min-h-[140px] w-full sm:min-h-[168px] md:min-h-[190px] lg:min-h-[210px]">
      {n > 0 ? (
        photos.map((photo, i) => (
          <Image
            key={photo.src}
            src={photo.src}
            alt={photo.alt}
            fill
            className={`object-cover object-center transition-opacity duration-[900ms] ease-in-out ${
              i === activeIndex ? "z-[1] opacity-100" : "pointer-events-none z-0 opacity-0"
            }`}
            sizes="100vw"
            aria-hidden={i !== activeIndex}
          />
        ))
      ) : (
        <div className="absolute inset-0 bg-neutral-200 dark:bg-neutral-800" aria-hidden />
      )}
    </div>
  );
}

function useSliderPhotos(): { photos: SliderPhoto[]; loading: boolean } {
  const [photos, setPhotos] = useState<SliderPhoto[]>([]);
  const [loading, setLoading] = useState(true);

  useEffect(() => {
    let cancelled = false;
    fetch("/api/slider-photos", { cache: "no-store" })
      .then((r) => (r.ok ? r.json() : []))
      .then((data: unknown) => {
        if (cancelled) return;
        if (Array.isArray(data)) {
          setPhotos(
            data.filter(
              (x): x is SliderPhoto =>
                typeof x === "object" &&
                x !== null &&
                "src" in x &&
                typeof (x as SliderPhoto).src === "string" &&
                "alt" in x &&
                typeof (x as SliderPhoto).alt === "string",
            ),
          );
        } else {
          setPhotos([]);
        }
      })
      .catch(() => {
        if (!cancelled) setPhotos([]);
      })
      .finally(() => {
        if (!cancelled) setLoading(false);
      });
    return () => {
      cancelled = true;
    };
  }, []);

  return { photos, loading };
}

/** Slider: one image at a time from `public/slider` (see `lib/slider-photos.ts`). */
export function TvonePromoStrip() {
  const { photos, loading } = useSliderPhotos();
  const [index, setIndex] = useState(0);
  const [reduceMotion, setReduceMotion] = useState(false);

  useEffect(() => {
    const mq = window.matchMedia("(prefers-reduced-motion: reduce)");
    const sync = () => setReduceMotion(mq.matches);
    sync();
    mq.addEventListener("change", sync);
    return () => mq.removeEventListener("change", sync);
  }, []);

  const advance = useCallback(() => {
    if (photos.length <= 1) return;
    setIndex((i) => (i + 1) % photos.length);
  }, [photos.length]);

  useEffect(() => {
    if (photos.length <= 1 || reduceMotion) return;
    const id = window.setInterval(advance, ROTATE_MS);
    return () => window.clearInterval(id);
  }, [photos.length, reduceMotion, advance]);

  useEffect(() => {
    setIndex((prev) => (photos.length === 0 ? 0 : Math.min(prev, photos.length - 1)));
  }, [photos.length]);

  const current = photos.length > 0 ? photos[index] : null;
  const regionLabel = loading ? "A carregar galeria" : current?.alt ?? "Galeria";

  return (
    <div
      className="relative w-full overflow-hidden border-y border-neutral-200/80 bg-neutral-100 dark:border-neutral-700 dark:bg-neutral-900"
      role="region"
      aria-roledescription="carrossel"
      aria-label={regionLabel}
    >
      <span className="sr-only" aria-live="polite">
        {current ? current.alt : loading ? "A carregar" : "Sem imagens"}
      </span>

      <div className="relative flex min-h-[140px] w-full flex-col sm:min-h-[168px] md:min-h-[190px] lg:min-h-[210px]">
        <PromoStripSingleSlide photos={photos} activeIndex={index} />
      </div>
    </div>
  );
}
