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

export type NavigateArgs = {
  search: string
}

export type NavigateFunction = (args: NavigateArgs) => void

export type LocationObject = {
  search: string
}

export type StorageOptions = {
  enabled?: boolean
  prefix?: string
  namespace?: string
}

export type UsePagePaginationOptions = {
  navigate: NavigateFunction
  location: LocationObject
  storage?: StorageOptions
  steps?: number[]
}

export const usePagePagination = ({
  navigate,
  location,
  storage = {
    enabled: false,
    prefix: 'app',
    namespace: 'main',
  },
  steps = [5, 10, 20, 40, 80, 100],
}: UsePagePaginationOptions) => {
  const queryParams = useMemo(
    () => new URLSearchParams(location.search),
    [location.search],
  )
  const page = Number(queryParams.get('page')) || 1
  const storageSizeKey = useMemo(
    () => `${storage.prefix}_${storage.namespace}_pagination_size`,
    [storage],
  )
  const [size, setSize] = useState(
    localStorage.getItem(storageSizeKey) && storage.enabled
      ? parseInt(localStorage.getItem(storageSizeKey) as string)
      : steps[0],
  )

  const _setSize = useCallback(
    (size: number) => {
      setSize(size)
      if (size && storage.enabled) {
        localStorage.setItem(storageSizeKey, JSON.stringify(size))
      }
    },
    [storageSizeKey, storage],
  )

  useEffect(() => {
    if (!queryParams.has('page')) {
      queryParams.set('page', '1')
      navigate({ search: `?${queryParams.toString()}` })
    }
  }, [queryParams, navigate])

  const setPage = useCallback(
    (page: number) => {
      queryParams.set('page', String(page))
      navigate({ search: `?${queryParams.toString()}` })
    },
    [queryParams, navigate],
  )

  return { page, size, steps, setPage, setSize: _setSize }
}
