"use client";

import { useEffect, useState } from "react";

/**
 * Vidéo de fond du hero — montée côté client, en résolution adaptée au support.
 *
 * Pourquoi un composant client alors que le hero est rendu serveur : une balise
 * <video autoPlay> présente dans le HTML initial est téléchargée par le
 * navigateur quoi qu'on écrive dans `preload`. L'ancienne version servait donc
 * 3,2 Mo à tout le monde — 85 % du poids de la home — pour un fond décoratif
 * recouvert d'un voile sombre à 60 %. Passer par le client est la seule façon de
 * décider QUOI charger, et de ne rien charger du tout quand il le faut.
 *
 * Une seule condition bloque totalement la vidéo : `prefers-reduced-motion`. Une
 * boucle en lecture automatique est exactement ce que ce réglage demande
 * d'éviter (WCAG 2.2.2), et aucune version allégée n'y change quoi que ce soit.
 *
 * Sur mobile la vidéo est conservée — elle porte l'identité visuelle de la page —
 * mais dans un encodage dédié : 854x480 au lieu de 1280x720, soit 122 Ko au lieu
 * de 249 Ko. Le hero mobile est en portrait avec `object-cover`, donc fortement
 * recadré : la résolution horizontale supplémentaire du fichier desktop y serait
 * intégralement perdue au rognage.
 *
 * Le poster reste rendu côté serveur dans HeroServer : c'est lui l'élément LCP,
 * il est préchargé, et il ne dépend pas de ce composant.
 */

const BREAKPOINT = "(min-width: 768px)";

type Variant = "mobile" | "desktop";

const SOURCES: Record<Variant, { src: string; type: string }[]> = {
  // Ordre = préférence : le navigateur retient la première source qu'il sait
  // lire. La chaîne `codecs` est indispensable pour l'AV1 en MP4 — sans elle
  // Safari annonce savoir lire le conteneur, puis échoue.
  desktop: [
    { src: "/videos/hero-bg-720.av1.mp4", type: 'video/mp4; codecs="av01.0.05M.08"' },
    { src: "/videos/hero-bg-720.webm", type: "video/webm" },
    { src: "/videos/hero-bg-720.mp4", type: "video/mp4" },
  ],
  mobile: [
    { src: "/videos/hero-bg-480.av1.mp4", type: 'video/mp4; codecs="av01.0.05M.08"' },
    { src: "/videos/hero-bg-480.mp4", type: "video/mp4" },
  ],
};

export function HeroVideo() {
  const [variant, setVariant] = useState<Variant | null>(null);

  useEffect(() => {
    const wide = window.matchMedia(BREAKPOINT);
    const reducedMotion = window.matchMedia("(prefers-reduced-motion: reduce)");

    const update = () =>
      setVariant(
        reducedMotion.matches ? null : wide.matches ? "desktop" : "mobile",
      );
    update();

    wide.addEventListener("change", update);
    reducedMotion.addEventListener("change", update);
    return () => {
      wide.removeEventListener("change", update);
      reducedMotion.removeEventListener("change", update);
    };
  }, []);

  if (!variant) return null;

  return (
    <video
      // `key` force le remontage quand on franchit le point de rupture : sans
      // lui, React réutiliserait l'élément et le navigateur garderait la source
      // déjà résolue, ignorant les nouvelles balises <source>.
      key={variant}
      autoPlay
      muted
      loop
      playsInline
      preload="auto"
      // Purement décoratif, et le poster équivalent est déjà dans le DOM :
      // l'annoncer une seconde fois n'apporterait rien.
      aria-hidden="true"
      tabIndex={-1}
      className="absolute inset-0 -z-10 h-full w-full object-cover"
      width={variant === "desktop" ? 1280 : 854}
      height={variant === "desktop" ? 720 : 480}
    >
      {SOURCES[variant].map((source) => (
        <source key={source.src} src={source.src} type={source.type} />
      ))}
    </video>
  );
}
