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

const useScrollPagination = ({ loading, fetchMore, data, getItems }) => {
  const observer = useRef(null)
  const observerElem = useRef(null)
  const [finished, setFinished] = useState(false)

  const reconfigureIntersectionObserver = () => {
    var options = {
      root: null,
      rootMargin: '-100% 0px 0px 0px',
      threshold: 0,
    }

    // delete old observer
    if (observer.current) observer.current.disconnect()

    if (finished) return

    // configure new observer
    observer.current = new IntersectionObserver(entities => {
      if (entities.find(x => x.isIntersecting == false)) {
        let itemCount = getItems(data).length
        fetchMore({
          variables: {
            offset: itemCount,
          },
        }).then(result => {
          const newItemCount = getItems(result.data).length
          if (newItemCount == 0) {
            setFinished(true)
          }
        })
      }
    }, options)

    // activate new observer
    if (observerElem.current && !loading) {
      observer.current.observe(observerElem.current)
    }
  }

  const containerElem = useCallback(node => {
    observerElem.current = node

    // cleanup
    if (observer.current != null) {
      observer.current.disconnect()
    }

    if (node != null) {
      reconfigureIntersectionObserver()
    }
  }, [])

  // only observe when not loading
  useEffect(() => {
    if (observer.current != null) {
      if (loading) {
        observer.current.unobserve(observerElem.current)
      } else {
        observer.current.observe(observerElem.current)
      }
    }
  }, [loading])

  // reconfigure observer if fetchMore function changes
  useEffect(() => {
    reconfigureIntersectionObserver()
  }, [fetchMore, data, finished])

  return {
    containerElem,
    finished,
  }
}

export default useScrollPagination
