import type { Directive } from 'vue';

// Directive `v-reveal` : révèle un bloc quand il entre dans le viewport.
// Reprend l'intention du setupReveal() du design (seuil ~92% de la hauteur),
// via un IntersectionObserver partagé. Respecte prefers-reduced-motion.
let reducedMotion = false;
try {
  reducedMotion = window.matchMedia('(prefers-reduced-motion: reduce)').matches;
} catch {
  /* matchMedia indisponible */
}

let observer: IntersectionObserver | null = null;

function getObserver(): IntersectionObserver | null {
  if (typeof IntersectionObserver === 'undefined') return null;
  if (!observer) {
    observer = new IntersectionObserver(
      (entries) => {
        for (const entry of entries) {
          if (entry.isIntersecting) {
            entry.target.classList.add('is-visible');
            observer?.unobserve(entry.target);
          }
        }
      },
      // -8% en bas ≈ déclenche quand le haut du bloc franchit ~92% du viewport.
      { threshold: 0, rootMargin: '0px 0px -8% 0px' },
    );
  }
  return observer;
}

export const reveal: Directive<HTMLElement> = {
  mounted(el) {
    el.classList.add('reveal');
    if (reducedMotion) {
      el.classList.add('is-visible');
      return;
    }
    const io = getObserver();
    if (!io) {
      // Pas d'IntersectionObserver : on révèle immédiatement (pas de contenu caché).
      el.classList.add('is-visible');
      return;
    }
    io.observe(el);
  },
  unmounted(el) {
    observer?.unobserve(el);
  },
};
