export default defineNuxtPlugin((nuxtApp) => {
  const reducedMotion = () => window.matchMedia('(prefers-reduced-motion: reduce)').matches

  let io: IntersectionObserver | null = null
  const getObserver = () => {
    if (io || reducedMotion() || !('IntersectionObserver' in window)) return io
    io = new IntersectionObserver(
      (entries) => {
        entries.forEach((entry) => {
          if (entry.isIntersecting) {
            entry.target.classList.add('is-visible')
            io?.unobserve(entry.target)
          }
        })
      },
      { threshold: 0.12, rootMargin: '0px 0px -60px 0px' },
    )
    return io
  }

  nuxtApp.vueApp.directive('reveal', {
    getSSRProps() {
      return { class: 'reveal' }
    },
    mounted(el: HTMLElement) {
      el.classList.add('reveal')
      if (reducedMotion()) {
        el.classList.add('is-visible')
        return
      }
      const rect = el.getBoundingClientRect()
      if (rect.top < window.innerHeight && rect.bottom > 0) {
        el.classList.add('is-visible')
      } else {
        getObserver()?.observe(el)
      }
    },
    unmounted(el: HTMLElement) {
      io?.unobserve(el)
    },
  })
})
