import { useMemo, useState } from 'react';
import { useInfiniteQuery } from 'react-query';

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

import useSegmentationGroups from 'src/hooks/queryHooks/useSegmentationGroups';
import { usersKeys } from 'src/pages/dashboard/Users/queries';
import { getPublicUsers } from 'src/services/usersService';

import { type SegmentationGroupMainApi } from '../../types';

type Props = {
  limit: number;
  appliedSegmentations: number[];
  isAgent?: boolean;
  enabled?: boolean;
};

const useUserSelector = ({
  limit,
  appliedSegmentations,
  isAgent,
  enabled = true,
}: Props) => {
  const [query, setQuery] = useState('');
  const debouncedQuery = useDebounce(query);

  const {
    data: segmentationGroups = [],
    isLoading: segmentationGroupsIsLoading,
  } = useSegmentationGroups<SegmentationGroupMainApi[]>(
    {
      refetchOnWindowFocus: false,
      refetchOnMount: false,
      cacheTime: Infinity,
      staleTime: Infinity,
    },
    false,
    true,
  );

  const {
    data,
    isLoading,
    isFetching,
    fetchNextPage,
    hasNextPage,
    isFetchingNextPage,
    isSuccess,
  } = useInfiniteQuery(
    usersKeys.usersWithParams({
      limit,
      search: debouncedQuery,
      segmentationItemIds: appliedSegmentations,
      isAgent,
    }),
    ({ pageParam = 0 }) =>
      getPublicUsers({
        limit,
        page: pageParam,
        segmentationItemIds: appliedSegmentations,
        search: debouncedQuery,
        isAgent,
      }),
    {
      getNextPageParam: lastPage =>
        lastPage.data.page === lastPage.data.totalPages
          ? undefined
          : lastPage.data.page,
      refetchOnMount: false,
      refetchOnWindowFocus: false,
      enabled,
    },
  );
  const coordinators = data?.pages.flatMap(page => page.data.items) || [];

  const hasActiveFilters =
    appliedSegmentations.length > 0 || debouncedQuery.length > 0;

  const isEmpty = !isLoading && coordinators.length === 0 && !hasActiveFilters;

  const isEmptySearch =
    !isLoading && coordinators.length === 0 && hasActiveFilters;

  // Count unique segmentation groups that have at least one item selected
  const segmentationGroupsCount = useMemo(() => {
    if (segmentationGroupsIsLoading || !appliedSegmentations.length) {
      return 0;
    }

    const selectedGroupIds = new Set();

    segmentationGroups.forEach(group => {
      const hasSelectedItem = group.items.some(item =>
        appliedSegmentations.includes(item.id),
      );

      if (hasSelectedItem) {
        selectedGroupIds.add(group.id);
      }
    });

    return selectedGroupIds.size;
  }, [segmentationGroupsIsLoading, appliedSegmentations, segmentationGroups]);

  return {
    segmentationGroups,
    segmentationGroupsIsLoading,
    query,
    debouncedQuery,
    setQuery,
    coordinators,
    isLoading,
    isFetching,
    fetchNextPage,
    hasNextPage,
    isFetchingNextPage,
    isSuccess,
    isEmpty,
    isEmptySearch,
    segmentationGroupsCount,
  };
};

export default useUserSelector;
