import { useContext, useEffect, useState, useCallback, useRef } from 'react'
import { Button, Divider, Flex, Space } from 'antd'
import { useSearchParams } from 'react-router-dom'
import ArrowLeftIcon from '../../Icons/ArrowLeftIcon.jsx'
import ArrowRightIcon from '../../Icons/ArrowRightIcon.jsx'
import PropTypes from 'prop-types'
import { ApiServerContext } from '../context/ApiServerContext'
import { AuthContext } from '../context/AuthContext'
import {
  getActiveFilterValues,
  useTableStatePersistence
} from '../context/TableStateContext'
import KeyboardShortcut from './KeyboardShortcut.jsx'

const ObjectTableNavigationButtons = ({
  disabled,
  _id,
  objectType,
  showEndingDivider = false
}) => {
  const { getObjectNeighbors } = useContext(ApiServerContext)
  const { token } = useContext(AuthContext)
  const [searchParams, setSearchParams] = useSearchParams()
  const [neighbors, setNeighbors] = useState({ next: null, previous: null })
  const [loading, setLoading] = useState(false)

  const { getPersistedFilter, getPersistedSorter } = useTableStatePersistence({
      scope: objectType,
      useFilterInSession: true,
      useSortInSession: true
    })

  const getObjectNeighborsRef = useRef(getObjectNeighbors)
  getObjectNeighborsRef.current = getObjectNeighbors

  const getPersistedFilterRef = useRef(getPersistedFilter)
  getPersistedFilterRef.current = getPersistedFilter

  const getPersistedSorterRef = useRef(getPersistedSorter)
  getPersistedSorterRef.current = getPersistedSorter

  useEffect(() => {
    if (!_id || !objectType || !token) {
      setNeighbors({ next: null, previous: null })
      setLoading(false)
      return
    }

    let cancelled = false

    const loadNeighbors = async () => {
      setLoading(true)
      const filter = getActiveFilterValues(getPersistedFilterRef.current())
      const sorter = getPersistedSorterRef.current()
      const result = await getObjectNeighborsRef.current(objectType, {
        id: _id,
        filter,
        sorter
      })

      if (!cancelled) {
        setNeighbors(result || { next: null, previous: null })
        setLoading(false)
      }
    }

    loadNeighbors()

    return () => {
      cancelled = true
    }
  }, [token, objectType, _id])

  const navigateToNeighbor = useCallback(
    (neighbor) => {
      if (!neighbor?._id || !objectType) return

      const nextParams = new URLSearchParams(searchParams)
      const objectTypeUpper = objectType.toUpperCase()

      for (const [key] of nextParams.entries()) {
        if (key.toUpperCase().includes(objectTypeUpper)) {
          nextParams.set(key, neighbor._id)
        }
      }

      setSearchParams(nextParams, { replace: true })
    },
    [searchParams, setSearchParams, objectType]
  )

  const handlePrevious = useCallback(() => {
    navigateToNeighbor(neighbors.previous)
  }, [navigateToNeighbor, neighbors.previous])

  const handleNext = useCallback(() => {
    navigateToNeighbor(neighbors.next)
  }, [navigateToNeighbor, neighbors.next])

  const handlePreviousShortcut = useCallback(() => {
    if (!disabled && !loading && neighbors.previous?._id) {
      handlePrevious()
    }
  }, [disabled, loading, neighbors.previous?._id, handlePrevious])

  const handleNextShortcut = useCallback(() => {
    if (!disabled && !loading && neighbors.next?._id) {
      handleNext()
    }
  }, [disabled, loading, neighbors.next?._id, handleNext])

  return (
    <Flex gap='small' align='center'>
      {showEndingDivider && (
        <Divider type='vertical' style={{ margin: '0 4px', height: '18px' }} />
      )}
      <Space size='small'>
        <KeyboardShortcut
          shortcut='alt+arrowleft'
          hint='ALT ←'
          onTrigger={handlePreviousShortcut}
        >
          <Button
            icon={<ArrowLeftIcon />}
            onClick={handlePrevious}
            disabled={disabled || loading || !neighbors.previous?._id}
          />
        </KeyboardShortcut>
        <KeyboardShortcut
          shortcut='alt+arrowright'
          hint='ALT →'
          onTrigger={handleNextShortcut}
        >
          <Button
            icon={<ArrowRightIcon />}
            onClick={handleNext}
            disabled={disabled || loading || !neighbors.next?._id}
          />
        </KeyboardShortcut>
      </Space>
    </Flex>
  )
}

ObjectTableNavigationButtons.propTypes = {
  disabled: PropTypes.bool,
  _id: PropTypes.string,
  objectType: PropTypes.string,
  showEndingDivider: PropTypes.bool
}

export default ObjectTableNavigationButtons
