import { useEffect, useRef } from 'react';
import { useInfiniteQuery } from 'react-query';

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

import useGeneralError from 'src/hooks/useGeneralError';
import { getPeopleList } from 'src/services/users';
import { useLokaliseTranslation } from 'src/utils/i18n';
import { flatPages } from 'src/utils/pagination';

import { peopleSearchKeys } from '../../../queries';

const LIMIT = 10;

const useInfinitePeopleSearch = () => {
  const lastKnownTotalRef = useRef<number>(0);
  const lastQueryRef = useRef<string>('');
  const showGeneralError = useGeneralError();
  const { t } = useLokaliseTranslation('people');

  const { Search, params, HuTableSortingHeader, form } = useHuPagination({
    defaultOrderBy: 'NAME',
  });

  const search = params.search;
  const debouncedQuery = useDebounce(search);

  const { data, isLoading, fetchNextPage, isFetchingNextPage } =
    useInfiniteQuery(
      peopleSearchKeys.moduleList(debouncedQuery, params.order, params.orderBy),
      ({ pageParam = 1 }) =>
        getPeopleList(
          debouncedQuery,
          pageParam,
          LIMIT,
          params.orderBy,
          params.order,
        ),
      {
        getNextPageParam: (lastPage, pages) => {
          const { page, totalPages } = pages[pages.length - 1]?.data || {};

          return page < totalPages ? pages.length + 1 : undefined;
        },
        onError: err => showGeneralError(err, t('ERROR_LOADING_CONTACTS')),
      },
    );

  const results = flatPages(data);

  useEffect(() => {
    if (data?.pages[0]?.data.count !== undefined) {
      lastKnownTotalRef.current = data.pages[0].data.count;
    }
  }, [data?.pages[0]?.data.count]);

  useEffect(() => {
    lastQueryRef.current = debouncedQuery;
  }, [debouncedQuery]);

  const totalUsers = (() => {
    if (data?.pages[0]?.data.count !== undefined) {
      return data.pages[0].data.count;
    }
    if (lastKnownTotalRef.current > 0) {
      return lastKnownTotalRef.current;
    }
    return 0;
  })();

  return {
    search: {
      component: Search,
      value: search,
    },
    table: {
      sortingHeader: HuTableSortingHeader,
      results,
      totalUsers,
    },
    loading: {
      isLoading,
      isFetchingNextPage,
    },
    actions: {
      fetchNextPage,
    },
    form,
  };
};

export default useInfinitePeopleSearch;
