import { useMemo } from 'react';
import { useNavigate } from 'react-router';

import { IconFileText, IconFileUpload } from '@material-hu/icons/tabler';
import { useTheme } from '@material-hu/mui/styles';

import { queryClient } from 'src/config/react-query';
import { IconTypes } from 'src/types/icons';
import { useLokaliseTranslation } from 'src/utils/i18n';

import { employeeLifecycleKeys } from '../queries';
import { employeeLifecycleRoutes } from '../routes';
import {
  type JourneyListItemProps,
  type JourneyTask,
  JourneyTaskType,
} from '../types';
import { getTaskPill, groupStepsBySection } from '../utils';

import { useEmployeeLifecycleIds } from './useEmployeeLifecycleIds';

type UseFormatStepTasksProps = {
  tasks: JourneyTask[];
  isUserTasksModule?: boolean;
  isPendingTab?: boolean;
  setDependencyTaskId?: (taskId: number | null) => void;
};

export const useFormatStepTasks = ({
  tasks = [],
  setDependencyTaskId,
  isUserTasksModule = false,
  isPendingTab = false,
}: UseFormatStepTasksProps) => {
  const { t } = useLokaliseTranslation('employee_lifecycle');
  const { journeyId, stepId } = useEmployeeLifecycleIds();
  const navigate = useNavigate();
  const { palette } = useTheme();

  const steps = useMemo(() => {
    if (!tasks || !tasks.length)
      return { availableSteps: [], notAvailableSteps: [] };

    let availableSteps: JourneyTask[] = [];
    let notAvailableSteps: JourneyTask[] = [];

    if (isPendingTab) {
      const sectionsTasks = groupStepsBySection({
        steps: tasks,
        isTasks: true,
      });
      availableSteps = sectionsTasks.availableSteps as JourneyTask[];
      notAvailableSteps = sectionsTasks.notAvailableSteps as JourneyTask[];
    }

    return { availableSteps, notAvailableSteps };
  }, [tasks, isPendingTab]);

  const handleClickJourneyTask = (journeyTask: JourneyTask) => {
    if (!journeyTask.isAvailable && journeyTask.dependsOn) {
      setDependencyTaskId?.(journeyTask.dependsOn);
    } else {
      setDependencyTaskId?.(null);

      if (!journeyTask.id) return;

      const navigateTo = isUserTasksModule
        ? employeeLifecycleRoutes.tasks.detail(journeyTask.id)
        : employeeLifecycleRoutes.journeys.task(
            journeyId!,
            stepId!,
            journeyTask.id,
          );

      navigate(navigateTo, { replace: true });
    }
  };

  const formatTask = (
    task: JourneyTask,
    isNotAvailableStep?: boolean,
  ): JourneyListItemProps => {
    const { icon } = task;

    const isTaskForOtherUser = task.taskAssignee !== task.journeyAssignee.id;

    const description =
      isTaskForOtherUser && isUserTasksModule
        ? t('tasks.tasks_module.task_for', {
            user: task.journeyAssignee.fullName,
          })
        : undefined;

    return {
      id: task.id,
      listItem: {
        onClick: () => handleClickJourneyTask(task),
        sx: {
          ...(isNotAvailableStep && {
            backgroundColor: palette.new.background.layout.default,
          }),
        },
        text: { title: task.actionTitle, description },
        sidePill: getTaskPill(task, t),
        avatar: {
          src: icon?.type === IconTypes.IMAGE ? icon?.value : undefined,
          text: icon?.type === IconTypes.EMOJI ? icon?.value : undefined,
          Icon: !icon
            ? task.actionType === JourneyTaskType.DOCUMENT
              ? IconFileUpload
              : IconFileText
            : undefined,
          color: !icon ? 'primary' : undefined,
        },
      },
      listItemWrapper: {
        onMouseEnter: () => {
          queryClient.prefetchQuery(
            employeeLifecycleKeys.journeys.stepTask(task.dependsOn || task.id),
          );
        },
      },
    };
  };

  const availableTasks: JourneyListItemProps[] = useMemo(
    () => steps.availableSteps.map(task => formatTask(task)),
    [steps.availableSteps],
  );

  const notAvailableTasks: JourneyListItemProps[] = useMemo(
    () => steps.notAvailableSteps.map(task => formatTask(task, true)),
    [steps.notAvailableSteps],
  );

  const completedTasks: JourneyListItemProps[] = useMemo(
    () => tasks.map(task => formatTask(task)),
    [tasks],
  );

  return {
    availableTasks,
    notAvailableTasks,
    completedTasks,
  };
};
