"use client";

import { useCallback, useEffect, useMemo, useRef, useState } from "react";
import Image from "next/image";
import { urlAsset } from "@/lib/utils/assets";
import type { Produit } from "@/types/produit";
import styles from "./ProduitsCarousel.module.css";

export type Format = Pick<Produit, "id" | "nom" | "dimensions" | "description" | "imageUrl">;

const MIN_SLIDES = 6;

export default function ProduitsCarousel({ formats }: { formats: Format[] }) {
  const pisteRef = useRef<HTMLDivElement>(null);
  const slideRefs = useRef<(HTMLDivElement | null)[]>([]);
  const [actif, setActif] = useState(0);
  const [enPause, setEnPause] = useState(false);

  // En dessous de 3 sacs, on duplique la liste pour que le carrousel ait
  // toujours l'air de défiler en continu (pas de trou visuel à la fin).
  const slides = useMemo(() => {
    if (formats.length === 0) return [];
    if (formats.length >= 3) return formats.map((f, i) => ({ format: f, cle: `${f.id}-${i}` }));

    const repetitions = Math.ceil(MIN_SLIDES / formats.length);
    return Array.from({ length: repetitions }).flatMap((_, rep) =>
      formats.map((f) => ({ format: f, cle: `${f.id}-${rep}` })),
    );
  }, [formats]);

  useEffect(() => {
    const piste = pisteRef.current;
    if (!piste) return;

    const observer = new IntersectionObserver(
      (entries) => {
        for (const entry of entries) {
          if (entry.isIntersecting) {
            const index = slideRefs.current.findIndex((el) => el === entry.target);
            if (index !== -1) setActif(index);
          }
        }
      },
      { root: piste, threshold: 0.6 },
    );

    slideRefs.current.forEach((el) => el && observer.observe(el));
    return () => observer.disconnect();
  }, [slides.length]);

  // Défile uniquement la piste horizontale du carrousel (jamais la page :
  // scrollIntoView remontait aussi le scroll vertical de la page, un bug).
  const allerA = useCallback((index: number) => {
    const piste = pisteRef.current;
    const slide = slideRefs.current[index];
    if (!piste || !slide) return;

    piste.scrollTo({ left: slide.offsetLeft - piste.offsetLeft, behavior: "smooth" });
  }, []);

  // Défilement automatique en continu, y compris avec seulement 2 sacs (dupliqués ci-dessus).
  useEffect(() => {
    if (enPause || slides.length <= 1) return;

    const interval = setInterval(() => {
      setActif((prev) => {
        const suivant = (prev + 1) % slides.length;
        allerA(suivant);
        return suivant;
      });
    }, 4000);

    return () => clearInterval(interval);
  }, [enPause, slides.length, allerA]);

  const indexOriginal = formats.length > 0 ? actif % formats.length : 0;

  return (
    <div
      className={styles.conteneur}
      onMouseEnter={() => setEnPause(true)}
      onMouseLeave={() => setEnPause(false)}
    >
      <div className={styles.ligne}>
        <button
          type="button"
          className={styles.fleche}
          onClick={() => allerA((actif - 1 + slides.length) % slides.length)}
          aria-label="Sac précédent"
        >
          <svg viewBox="0 0 24 24" fill="none" aria-hidden="true">
            <path d="M15 6l-6 6 6 6" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round" />
          </svg>
        </button>

        <div className={styles.piste} ref={pisteRef}>
          {slides.map(({ format, cle }, index) => (
            <div
              key={cle}
              ref={(el) => {
                slideRefs.current[index] = el;
              }}
              className={styles.slide}
            >
              <div className={styles.carte}>
                {format.imageUrl && (
                  <div className={styles.imageConteneur}>
                    <Image
                      src={urlAsset(format.imageUrl)}
                      alt={format.nom}
                      fill
                      sizes="(min-width: 768px) 480px, 85vw"
                      className={styles.image}
                    />
                  </div>
                )}
                <div className={styles.carteContenu}>
                  <h3 className={styles.carteTitre}>{format.nom}</h3>
                  <span className={styles.dimensions}>{format.dimensions}</span>
                  <p className={styles.carteTexte}>{format.description}</p>
                </div>
              </div>
            </div>
          ))}
        </div>

        <button
          type="button"
          className={styles.fleche}
          onClick={() => allerA((actif + 1) % slides.length)}
          aria-label="Sac suivant"
        >
          <svg viewBox="0 0 24 24" fill="none" aria-hidden="true">
            <path d="M9 6l6 6-6 6" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round" />
          </svg>
        </button>
      </div>

      <div className={styles.pagination}>
        {formats.map((format, index) => (
          <button
            key={format.id}
            type="button"
            className={`${styles.point} ${index === indexOriginal ? styles.pointActif : ""}`}
            onClick={() => allerA(index)}
            aria-label={`Voir ${format.nom}`}
          />
        ))}
      </div>
    </div>
  );
}
