import { useCallback } from 'react'
import config from '../../../config'
import loglevel from 'loglevel'
const logger = loglevel.getLogger('useTableScroll')
logger.setLevel(config.logLevel)

export const useTableScroll = ({
  lazyLoading,
  hasMore,
  hasPrevious,
  currentLoadedPageNumber,
  loadingPages,
  createSkeletonData,
  fetchData,
  setCurrentLoadedPageNumber,
  setLazyLoading,
  setPages,
  setLoadedPages,
  loadedPages
}) => {
  const handleScroll = useCallback(
    (e) => {
      const { target } = e
      const scrollHeight = target.scrollHeight
      const scrollTop = target.scrollTop
      const clientHeight = target.clientHeight

      // Load more data when scrolling down
      if (
        scrollHeight - scrollTop - clientHeight < 100 &&
        !lazyLoading &&
        hasMore
      ) {
        logger.debug(loadedPages)
        const lowestPage = Math.max(...loadedPages)
        const nextPage = lowestPage + 1
        if (!loadingPages.has(nextPage)) {
          setLazyLoading(true)
          setCurrentLoadedPageNumber(nextPage)
          setPages((prev) => {
            const filteredPages = prev.map((page) => ({
              ...page,
              items: page.items.filter((item) => !item.isSkeleton)
            }))
            const relevantPages = filteredPages.slice(-2)
            logger.debug('Pages after scroll down:', {
              current: currentLoadedPageNumber,
              next: nextPage,
              keeping: relevantPages.map((p) => p.pageNum)
            })
            return [
              ...relevantPages,
              { pageNum: nextPage, items: createSkeletonData() }
            ]
          })
          // Adjust scroll position to center the new content
          setTimeout(() => {
            const newScrollTop = (target.scrollHeight - clientHeight) / 2
            target.scrollTo({ top: newScrollTop })
          }, 0)
          fetchData(nextPage, true)
        }
      }

      // Load previous data when scrolling up
      if (
        scrollTop < 100 &&
        !lazyLoading &&
        hasPrevious &&
        currentLoadedPageNumber > 1
      ) {
        const lowestPage = Math.min(...loadedPages)
        const prevPage = lowestPage - 1

        if (!loadingPages.has(prevPage)) {
          setLazyLoading(true)
          setCurrentLoadedPageNumber(prevPage)
          setPages((prev) => {
            const relevantPages = filteredPages.slice(0, 1)
            const filteredPages = prev.map((page) => ({
              ...page,
              items: page.items.filter((item) => !item.isSkeleton)
            }))

            logger.debug('Pages after scroll up:', {
              current: currentLoadedPageNumber,
              prev: prevPage,
              keeping: relevantPages.map((p) => p.pageNum)
            })
            return [
              { pageNum: prevPage, items: createSkeletonData() },
              ...relevantPages
            ]
          })
          setLoadedPages((prev) => {
            const relevantPages = prev.slice(0, 1)
            return [prevPage, ...relevantPages]
          })
          // Adjust scroll position to center the new content
          setTimeout(() => {
            const newScrollTop = (target.scrollHeight - clientHeight) / 2
            target.scrollTo({ top: newScrollTop })
          }, 0)
          fetchData(prevPage, false, true)
        }
      }
    },
    [
      lazyLoading,
      hasMore,
      hasPrevious,
      currentLoadedPageNumber,
      loadingPages,
      createSkeletonData,
      fetchData,
      setCurrentLoadedPageNumber,
      setLazyLoading,
      setPages,
      setLoadedPages,
      loadedPages
    ]
  )

  return { handleScroll }
}
