import { useInfiniteQuery } from 'react-query';

import { useDebounce } from '@material-hu/hooks/useDebounce';
import { type PaginationParams } from '@material-hu/hooks/useHuPagination';

import usePaginatedQueryState from 'src/hooks/usePaginatedQueryState';
import { type RequestError, type RequestSuccess } from 'src/types/services';
import { getNextPageParam } from 'src/utils/pagination';
import { flatPages } from 'src/utils/tableUtils';

import { coursesKeys } from '../queries';
import { getCourses } from '../services';
import { type CoursesListParams } from '../types';

export type TSuccess = RequestSuccess<typeof getCourses>;
export type TError = RequestError;
export type TData = TSuccess;

const useGetCourses = (pagination: PaginationParams) => {
  const debouncedSearch = useDebounce(pagination.search);

  const params: CoursesListParams = {
    order: pagination.order,
    orderBy: pagination.orderBy,
    limit: 10,
    page: 1,
    q: debouncedSearch || undefined,
    categoryIds: pagination.categoryIds,
    includeNoCategory: pagination.includeNoCategory,
    sortingOption: undefined,
  };

  const query = useInfiniteQuery<TSuccess, TError, TData>({
    queryKey: coursesKeys.list.paginated(params),
    queryFn: ({ pageParam = 1 }) => getCourses({ ...params, page: pageParam }),
    getNextPageParam,
    keepPreviousData: true,
  });

  const { data, hasNextPage, isFetchingNextPage, fetchNextPage } = query;

  const courses = flatPages(data);
  const firstPage = data?.pages[0].data;

  const fetchNext = () => {
    hasNextPage && !isFetchingNextPage && fetchNextPage();
  };

  const queryState = usePaginatedQueryState(
    firstPage,
    query.status,
    debouncedSearch !== '',
  );

  return {
    courses,
    fetchNext,
    totalCount: firstPage?.count ?? 0,
    queryState,
    ...query,
  };
};

export default useGetCourses;
