import { useState } from 'react';
import { useNavigate } from 'react-router-dom';

import { TaskTypes } from '@material-hu/components/composed-components/learning';

import { logEvent } from 'src/config/logging';
import { EventName } from 'src/types/amplitude';

import useIds from '../../hooks/useIds';
import useRoutes from '../../hooks/useRoutes';
import useGetPath from '../../paths/hooks/useGetPath';
import { PathStatus } from '../../paths/types';
import useGetCourse from '../hooks/useGetCourse';
import { type Course, type Task } from '../types';
import {
  getNextTask,
  getPreviousTask,
  getTaskById,
  getTaskPosition,
  isCourseCompletion,
  isModuleFinished,
  isPendingSignature,
} from '../utils';

const useTaskNavigation = () => {
  const [showModuleFinished, setShowModuleFinished] = useState(false);

  const navigate = useNavigate();
  const routes = useRoutes();
  const { courseId, pathId, taskId } = useIds();

  const { course, refetch: refetchCourse } = useGetCourse({ courseId });
  const { refetch: refetchPath } = useGetPath({ pathId });

  const handlePrevious = () => {
    if (!course) return;

    if (showModuleFinished) {
      return setShowModuleFinished(false);
    }

    const previousTask = getPreviousTask(course, taskId!);

    if (previousTask) {
      return navigate(
        routes.courses.lesson(course.id, previousTask.id, previousTask.tag),
      );
    }

    navigate(routes.courses.detail(course.id));
  };

  const handlePendingSignature = () => {
    navigate(routes.courses.sign(courseId!));
  };

  const handleCourseCompletion = async () => {
    logEvent(EventName.COURSE_FINISHED, { courseId });

    if (pathId) {
      logEvent(EventName.PATH_COURSE_FINISHED, { pathId, courseId });

      const { data: updatedPath } = await refetchPath();

      if (updatedPath?.status === PathStatus.FINISHED) {
        navigate(routes.paths.completion(pathId));
        return;
      }
    }

    navigate(routes.courses.completion(courseId!));
  };

  const handleNextTask = (updatedCourse: Course, nextTask: Task) => {
    const taskPosition = getTaskPosition(course, taskId!);
    const nextTaskLocation = getTaskPosition(updatedCourse, nextTask.id);
    const completed = isModuleFinished(
      updatedCourse.modules[taskPosition.moduleIndex],
    );

    if (
      nextTaskLocation != null &&
      nextTaskLocation.moduleIndex !== taskPosition.moduleIndex &&
      completed &&
      !showModuleFinished
    ) {
      setShowModuleFinished(true);
      logEvent(EventName.COURSE_MODULE_FINISHED, { courseId });
      return;
    }

    setShowModuleFinished(false);
    navigate(routes.courses.lesson(courseId!, nextTask.id, nextTask.tag));
  };

  const handleNext = async () => {
    const { data: updatedCourse } = await refetchCourse();

    if (!updatedCourse || !course) return;

    if (isPendingSignature(updatedCourse)) {
      return handlePendingSignature();
    }

    if (isCourseCompletion(course, updatedCourse)) {
      await handleCourseCompletion();
      return;
    }

    const nextTask = getNextTask(course, taskId!);

    if (nextTask) {
      return handleNextTask(updatedCourse, nextTask);
    }

    navigate(routes.courses.detail(courseId!));
  };

  const courseTask = getTaskById(course, taskId!);

  const showTaskEvaluation =
    courseTask?.type === TaskTypes.EVALUATION && !showModuleFinished;

  const showTaskBase =
    courseTask?.type !== TaskTypes.EVALUATION && !showModuleFinished;

  return {
    showTaskEvaluation,
    showTaskBase,
    showModuleFinished,
    handlePrevious,
    handleNext,
  };
};

export default useTaskNavigation;
