import { useMemo } from 'react';
import { useQuery } from 'react-query';

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

import { type TableLoaderProps as HuTableLoaderProps } from '@material-hu/components/design-system/Table/components/TableLoader/types';

import { EMPLOYEE_LIFECYCLE_STALE_TIME, PAGE_SIZE } from '../constants';
import { employeeLifecycleKeys } from '../queries';
import { getJourneyStepTasks } from '../services';
import {
  type JourneyAssignee,
  type JourneyProgressStatusType,
  type JourneyTasksParams,
} from '../types';

import { useEmployeeLifecycleIds } from './useEmployeeLifecycleIds';
import { useFilterParams } from './useFilterParams';

type UseGetJourneyStepTasksProps = {
  progressStatus: JourneyProgressStatusType[];
  isUserTasksModule: boolean;
};

export const useGetJourneyStepTasks = ({
  progressStatus,
  isUserTasksModule,
}: UseGetJourneyStepTasksProps) => {
  const { journeyId, stepId } = useEmployeeLifecycleIds();
  const { filterParams, setQueryStates } = useFilterParams();

  const debounceSearch = useDebounce(filterParams.search);
  const currentLimit = filterParams.limit || PAGE_SIZE;

  // Debounced params //
  // This are the params that will be used to fetch the tasks
  const debounceParams: JourneyTasksParams = {
    expirationStatus: filterParams.expirationStatus,
    progressStatus: progressStatus.toString(),
    search: debounceSearch || undefined,
    journeyId: journeyId,
    stepId: stepId,
    journeyAssignees: filterParams.collaborators,
  };

  const { data: tasks = [], ...query } = useQuery({
    queryKey: employeeLifecycleKeys.journeys.stepTasks(debounceParams),
    queryFn: () => getJourneyStepTasks(debounceParams),
    select: response => response.data,
    staleTime: EMPLOYEE_LIFECYCLE_STALE_TIME,
  });

  const allTasksParams = omit(debounceParams, 'journeyAssignees', 'search');
  const { data: allTasks = [] } = useQuery({
    queryKey: employeeLifecycleKeys.journeys.tasksCollaborators(allTasksParams),
    queryFn: () => getJourneyStepTasks(allTasksParams),
    select: response => response.data,
    staleTime: EMPLOYEE_LIFECYCLE_STALE_TIME,
  });

  // Filter Tasks //
  // On user tasks module, we want to show only tasks that are available and not dependent on other tasks
  const filteredTasks = useMemo(() => {
    if (!tasks || !tasks.length) return [];

    if (isUserTasksModule) {
      return tasks.filter(task => task.isAvailable);
    }

    return tasks;
  }, [tasks, isUserTasksModule]);

  // Unique collaborators //
  // Used to show a list of unique collaborators inside the drawer filter
  // This allows us to filter the tasks by collaborators
  const uniqueCollaborators = useMemo(() => {
    if (!allTasks.length) return [];

    const collaboratorMap = new Map<number, JourneyAssignee>();

    allTasks.forEach(task => {
      if (task.taskAssignee === task.journeyAssignee.id) return;

      collaboratorMap.set(task.journeyAssignee.id, task.journeyAssignee);
    });

    return Array.from(collaboratorMap.values());
  }, [allTasks]);

  // Paginated tasks //
  // Used to create artificial pagination only tasks list
  const paginatedTasks = useMemo(
    () => filteredTasks.slice(0, currentLimit),
    [filteredTasks, currentLimit],
  );

  // Pagination object //
  // Used on the HuTableLoader component
  const pagination: HuTableLoaderProps = {
    loadedCount: paginatedTasks.length,
    totalCount: filteredTasks.length,
    onLoadMore: () => setQueryStates({ limit: currentLimit + PAGE_SIZE }),
    onScrollToTop: () => {
      const div = document.getElementById('user-tasks-tabs');
      if (!div) return;
      div.scrollIntoView({ behavior: 'smooth', block: 'start' });
    },
  };

  return {
    ...query,
    paginatedTasks,
    uniqueCollaborators,
    pagination,
  };
};
