import { useEffect, useRef } from 'react'

type Args = {
  onIntersect: (
    target: IntersectionObserverEntry,
    observer: IntersectionObserver,
  ) => void,
  options?: IntersectionObserverInit,
}

/**
 * Хук для отслежения пересечение targetRef с rootRef
 * targetRef нужно повесить на целевой элемент который будет наблюдаться,
 * rootRef на корневой элемент с которым пересекается targetRef.
 * Также можно проигнорить rootRef тогда по-умолчанию отслеживается
 * пересечение с областью видимости документа
 */
export const useIntersectionObserver = ({ onIntersect, options }: Args) => {
  const callbackRef = useRef(onIntersect)
  const rootRef = useRef<HTMLDivElement>(null)
  const targetRef = useRef<HTMLDivElement>(null)

  useEffect(() => {
    callbackRef.current = onIntersect
  }, [onIntersect])

  useEffect(() => {
    const rootElement = rootRef.current
    const targetElement = targetRef.current
    if (!targetElement) {
      return undefined
    }

    const observerOptions = { root: rootElement, ...options }
    const callback = ([target]: Array<IntersectionObserverEntry>) => {
      if (target.isIntersecting) {
        callbackRef.current(target, observer)
      }
    }

    const observer = new IntersectionObserver(callback, observerOptions)
    observer.observe(targetElement)

    return () => {
      observer.disconnect()
    }
  }, [options])

  return { rootRef, targetRef }
}
