import { useEffect, useRef, useState } from 'react'

type Options = {
  root?: Element | null
  rootMargin?: string
  threshold?: number | number[]
  once?: boolean
}

export function useRevealOnScroll(options?: Options) {
  const ref = useRef<HTMLElement | null>(null)
  const [isVisible, setIsVisible] = useState(false)

  useEffect(() => {
    const node = ref.current
    if (!node) return

    const obs = new IntersectionObserver(
      (entries) => {
        entries.forEach((entry) => {
          if (entry.isIntersecting) {
            setIsVisible(true)
            // if once is true, unobserve after first intersection
            if (options?.once ?? true) {
              if (obs && node) obs.unobserve(node)
            }
          }
        })
      },
      {
        root: options?.root ?? null,
        rootMargin: options?.rootMargin ?? '0px',
        threshold: options?.threshold ?? 0.12,
      }
    )

    obs.observe(node)

    return () => {
      try {
        obs.disconnect()
      } catch (e) {
        // ignore
      }
    }
    // eslint-disable-next-line react-hooks/exhaustive-deps
  }, [options?.once, options?.root, options?.rootMargin, options?.threshold])

  return { ref, isVisible }
}

export default useRevealOnScroll
