import Image from "next/image";

import type { WpImage as WpImageData } from "@/lib/wp/types";
import { cn } from "@/lib/utils";

/**
 * Art-direction mobile/desktop pour next/image.
 *
 * next/image (Next 16) n'a pas d'équivalent à `<picture><source media>` :
 * l'approche documentée est deux `<Image fill>` frères, l'un masqué sous le
 * breakpoint, l'autre au-dessus, via des classes Tailwind STATIQUES (jamais
 * interpolées — sinon Tailwind ne les voit pas au build).
 *
 * Le défaut `breakpoint="md"` reproduit exactement la media query d'origine
 * `(max-width: 767px)` (Tailwind `md` = `min-width: 768px`).
 */
interface ArtDirectedImageProps {
  /** Image affichée sous le breakpoint. Sortie de `mapImage(...)`. */
  mobile: WpImageData | null | undefined;
  /** Image affichée au-dessus du breakpoint. Sortie de `mapImage(...)`. */
  desktop: WpImageData | null | undefined;
  /** Alt partagé (art-direction = même contenu visuel). */
  alt: string;
  /** Opt-in LCP : appliqué aux DEUX images (la visible est le candidat LCP). */
  priority?: boolean;
  /** Breakpoint de bascule. `md` (défaut) = 767px de la media query d'origine. */
  breakpoint?: "sm" | "md" | "lg";
  /** Classe du conteneur (positionnement : `absolute inset-0 -z-10`…). */
  className?: string;
  /** Forwardé à chaque <Image>. */
  sizes?: string;
  /** Classe de chaque <Image> (ex. `object-cover`). */
  imgClassName?: string;
}

/**
 * Lookup STATIQUE des classes de bascule. Indispensable : Tailwind ne détecte
 * pas les chaînes construites dynamiquement (`md:${x}`), seulement les littéraux.
 */
const BREAKPOINT_CLASSES: Record<
  NonNullable<ArtDirectedImageProps["breakpoint"]>,
  { mobileHide: string; desktopShow: string }
> = {
  sm: { mobileHide: "sm:hidden", desktopShow: "hidden sm:block" },
  md: { mobileHide: "md:hidden", desktopShow: "hidden md:block" },
  lg: { mobileHide: "lg:hidden", desktopShow: "hidden lg:block" },
};

function ArtDirectedImage({
  mobile,
  desktop,
  alt,
  priority = false,
  breakpoint = "md",
  className,
  sizes = "100vw",
  imgClassName,
}: ArtDirectedImageProps) {
  // Dégradation gracieuse : si une seule source existe, on l'utilise des deux côtés.
  const mobileSrc = mobile ?? desktop;
  const desktopSrc = desktop ?? mobile;

  if (!mobileSrc?.sourceUrl || !desktopSrc?.sourceUrl) return null;

  const { mobileHide, desktopShow } = BREAKPOINT_CLASSES[breakpoint];

  return (
    <div className={className}>
      <Image
        src={mobileSrc.sourceUrl}
        alt={alt}
        fill
        priority={priority}
        sizes={sizes}
        className={cn(imgClassName, "block", mobileHide)}
      />
      <Image
        src={desktopSrc.sourceUrl}
        alt=""
        aria-hidden
        fill
        priority={priority}
        sizes={sizes}
        className={cn(imgClassName, "hidden", desktopShow)}
      />
    </div>
  );
}

export default ArtDirectedImage;
