import {
  useCallback,
  useMemo,
  useRef,
} from 'react'

import debounce from 'lodash/debounce'

import { getSearchItems } from 'requests'

import { useRequest } from 'hooks'

import { SEARCH_DELAY } from 'features/Search/config'
import type { NormalizedSearchResults } from 'features/Search/helpers'
import { normalizeItems } from 'features/Search/helpers'

type Updater = (results: NormalizedSearchResults) => void

export const useSearchRequest = (updater: Updater) => {
  const abortRef = useRef<AbortController | null>(null)

  const {
    isFetching,
    request: searchItemsRequest,
  } = useRequest(getSearchItems)

  const search = useMemo(
    () => debounce((query: string) => {
      const abortController = new AbortController()
      searchItemsRequest(query, abortController.signal).then((searchResult) => {
        abortRef.current = null
        updater(normalizeItems(searchResult))
      })
      abortRef.current = abortController
    }, SEARCH_DELAY),
    [searchItemsRequest, updater],
  )

  const cancelSearch = useCallback(() => {
    abortRef.current?.abort()
    abortRef.current = null
  }, [])

  return {
    cancelSearch,
    isFetching,
    search,
  }
}
