import {
  type UseInfiniteQueryOptions,
  type UseQueryOptions,
  useInfiniteQuery,
  useQuery,
} from 'react-query';

import {
  type SearchFilter,
  type SearchResult,
} from 'src/pages/dashboard/search/types';

import { type SearchResponse, searchGlobal } from './services';

export const searchKeys = {
  all: () => ['global-search'] as const,
  globalSearchResults: (
    query: string,
    filter: SearchFilter,
    options?: { limit?: number; cursor?: string },
  ) => [...searchKeys.all(), query, filter, options],
  paginatedGlobalSearchResults: (
    query: string,
    filter: SearchFilter,
    options?: { limit?: number; cursor?: string },
  ) => [...searchKeys.all(), 'paginated', query, filter, options],
};

export const useGlobalSearchQuery = (
  query: string,
  filter: SearchFilter,
  options?: { limit?: number; cursor?: string },
  queryOptions?: UseQueryOptions<SearchResponse, Error, SearchResult[]>,
) => {
  return useQuery({
    queryKey: searchKeys.globalSearchResults(query, filter, options),
    queryFn: () => searchGlobal(query, filter, options),
    select: response => response.results,
    ...queryOptions,
  });
};

export const usePaginatedGlobalSearchQuery = (
  query: string,
  filter: SearchFilter,
  options?: { limit?: number; cursor?: string },
  queryOptions?: UseInfiniteQueryOptions<SearchResponse, Error>,
) => {
  return useInfiniteQuery({
    queryKey: searchKeys.paginatedGlobalSearchResults(query, filter, options),
    queryFn: ({ pageParam }: { pageParam?: string }) =>
      searchGlobal(query, filter, { ...options, cursor: pageParam }),
    getNextPageParam: last => last.nextCursor || undefined,
    ...queryOptions,
  });
};
