import { useQuery } from 'react-query';

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

import {
  PaginatedQueryStates,
  usePaginatedQueryState,
} from 'src/hooks/usePaginatedQueryState';
import { getCourses } from 'src/services/courses';
import { type RequestError, type RequestSuccess } from 'src/types/services';

import { coursesKeys } from '../queries';
import {
  CourseCategories,
  type CourseFilters,
  type CourseStatus,
} from '../types';
import { getCourseFiltersCount } from '../utils';

enum CoursesPaginatedQueryStatesEnum {
  EMPTY_CATEGORY = 'emptyCategory',
}

export type CoursesPaginatedQueryStates =
  | PaginatedQueryStates
  | CoursesPaginatedQueryStatesEnum;

export type TSuccess = RequestSuccess<typeof getCourses>;
export type TError = RequestError;
export type TData = TSuccess['data'];
export type TParams = PaginationParams &
  CourseFilters & {
    status: CourseStatus;
    category: string;
  };

export const useGetCourses = (params: TParams) => {
  const { search, pagination, category, ...rest } = params;

  const debouncedSearch = useDebounce(search);

  const debouncedParams = {
    ...pagination,
    ...rest,
    search: debouncedSearch,
    categoryIds: category !== CourseCategories.ALL ? category : undefined,
  };

  const coursesQuery = useQuery<TSuccess, TError, TData>(
    coursesKeys.list(debouncedParams),
    () => getCourses(debouncedParams, false),
    {
      select: response => response.data,
      keepPreviousData: true,
    },
  );

  const filteredByCategory = Boolean(
    debouncedParams.categoryIds && debouncedParams.categoryIds.length > 0,
  );

  const filteredBySearch = search?.length > 0;

  const filteredByOthers = getCourseFiltersCount(params) > 0;

  const isFiltered = filteredBySearch || filteredByCategory || filteredByOthers;

  const queryState = usePaginatedQueryState(
    coursesQuery.data,
    coursesQuery.status,
    isFiltered,
  );

  const stateString =
    queryState.isEmptySearch && !filteredBySearch && filteredByCategory
      ? CoursesPaginatedQueryStatesEnum.EMPTY_CATEGORY
      : queryState.state;

  const state = {
    ...queryState,
    state: stateString,
    isEmptySearch: stateString === PaginatedQueryStates.EMPTY_SEARCH,
    isEmptyCategory:
      stateString === CoursesPaginatedQueryStatesEnum.EMPTY_CATEGORY,
  };

  return {
    ...coursesQuery,
    ...state,
    isFiltered,
  };
};

export default useGetCourses;
