import { lazy, type MouseEvent, Suspense, useState } from 'react';
import { useNavigate } from 'react-router-dom';

import { useModal } from '@material-hu/hooks/useModal';
import { useTheme } from '@material-hu/mui/index';
import Stack from '@material-hu/mui/Stack';

import MenuList, {
  type MenuListProps,
} from '@material-hu/components/composed-components/MenuList';
import Skeleton from '@material-hu/components/design-system/Skeleton';
import TableCell from '@material-hu/components/design-system/Table/components/TableCell';

import { coursesRoutes } from 'src/pages/dashboard/Learning/Courses/routes';
import { insertIf } from 'src/utils/arrayUtils';
import { useLokaliseTranslation } from 'src/utils/i18n';

import useCheckCourseOnPath from '../../../hooks/useCheckCourseOnPath';
import useDuplicateCourse from '../../../hooks/useDuplicateCourse';
import useEditCourseStatus from '../../../hooks/useEditCourseStatus';
import useNotifyCourseAudience from '../../../hooks/useNotifyCourseAudience';
import {
  type CourseListItem,
  CourseStatus,
  NotificationOptions,
} from '../../../types';
import { getToggleStatus } from '../../utils';

import {
  ActivateDrawer,
  type ActivateFormCallbacks,
  type ActivateFormValues,
} from './ActivateDrawer';
import {
  NotifyDrawer,
  type NotifyFormCallbacks,
  type NotifyFormValues,
} from './NotifyDrawer';
import { type PathCourseWarningProps } from './PathCourseWarning';

const PathCourseWarning = lazy(() => import('./PathCourseWarning'));
const DeleteCourseModal = lazy(() => import('./DeleteCourseModal'));
const DeactivateCourseModal = lazy(() => import('./DeactivateCourseModal'));

type CoursesTableRowActionsProps = {
  course: CourseListItem;
};

const CoursesTableRowActions = ({ course }: CoursesTableRowActionsProps) => {
  const { palette } = useTheme();
  const [openActivateDrawer, setOpenActivateDrawer] = useState(false);
  const [openNotifyDrawer, setOpenNotifyDrawer] = useState(false);

  const { t } = useLokaliseTranslation('learning');
  const navigate = useNavigate();

  const checkCourseOnPath = useCheckCourseOnPath(course?.id);

  const editStatusMutation = useEditCourseStatus(course, {
    onSuccess: () => setOpenActivateDrawer(false),
  });

  const notifyMutation = useNotifyCourseAudience(course, {
    onSuccess: () => setOpenNotifyDrawer(false),
  });

  const duplicateMutation = useDuplicateCourse(course, {
    onSuccess: response => {
      const newCourse = response.data;
      navigate(coursesRoutes.duplicateCourse(newCourse.id));
    },
  });

  const {
    modal: deleteModal,
    showModal: showDeleteModal,
    closeModal: closeDeleteModal,
  } = useModal(
    () => (
      <Suspense
        fallback={
          <Skeleton
            width={600}
            height={260}
          />
        }
      >
        <DeleteCourseModal
          course={course}
          onClose={closeDeleteModal}
        />
      </Suspense>
    ),
    { onClick: (e: MouseEvent<HTMLDivElement>) => e.stopPropagation() },
  );

  const {
    modal: deactivateModal,
    showModal: showDeactivateModal,
    closeModal: closeDeactivateModal,
  } = useModal(
    () => (
      <Suspense
        fallback={
          <Skeleton
            width={600}
            height={236}
          />
        }
      >
        <DeactivateCourseModal
          course={course}
          onClose={closeDeactivateModal}
        />
      </Suspense>
    ),
    { onClick: (e: MouseEvent<HTMLDivElement>) => e.stopPropagation() },
  );

  const {
    showModal: showPathCourseWarning,
    modal: pathCourseWarning,
    closeModal: closePathCourseWarning,
  } = useModal(
    ({ learningPaths, isDelete }: Omit<PathCourseWarningProps, 'onClose'>) => (
      <Suspense
        fallback={
          <Skeleton
            width={600}
            height={320}
          />
        }
      >
        <PathCourseWarning
          onClose={closePathCourseWarning}
          learningPaths={learningPaths}
          isDelete={isDelete}
        />
      </Suspense>
    ),
    {
      maxWidth: 'sm',
      onClick: (e: MouseEvent<HTMLDivElement>) => e.stopPropagation(),
    },
  );

  const handleActivateConfirm = (
    values: ActivateFormValues,
    callbacks: ActivateFormCallbacks,
  ) =>
    editStatusMutation.mutateAsync(
      {
        status: CourseStatus.ACTIVE,
        sendNotification: values.sendNotification !== NotificationOptions.NONE,
      },
      callbacks,
    );

  const handleActivateCancel = () => setOpenActivateDrawer(false);

  const handleDelete = async () => {
    const { data: courseOnPath } = await checkCourseOnPath.refetch();

    if (courseOnPath && courseOnPath.hasLearningPaths) {
      showPathCourseWarning({
        isDelete: true,
        learningPaths: courseOnPath.learningPaths,
      });
      return;
    }

    showDeleteModal();
  };

  const handleDuplicate = () => duplicateMutation.mutateAsync(undefined);

  const handleNotify = () => setOpenNotifyDrawer(true);

  const handleNotifyCancel = () => setOpenNotifyDrawer(false);

  const handleNotifyConfirm = (
    _: NotifyFormValues,
    callbacks: NotifyFormCallbacks,
  ) => notifyMutation.mutateAsync(undefined, callbacks);

  const handleReport = () => navigate(coursesRoutes.reportCourse(course.id));

  const handleToggleStatus = async () => {
    const newStatus = getToggleStatus(course.status);

    const { data: courseOnPath } = await checkCourseOnPath.refetch();
    if (
      courseOnPath &&
      courseOnPath.hasLearningPaths &&
      newStatus === CourseStatus.INACTIVE
    ) {
      showPathCourseWarning({
        learningPaths: courseOnPath.learningPaths,
      });
      return;
    }

    if (newStatus === CourseStatus.ACTIVE) {
      setOpenActivateDrawer(true);
    } else {
      showDeactivateModal();
    }
  };

  const options: MenuListProps['options'] = [
    ...insertIf(course.status === CourseStatus.ACTIVE, {
      onClick: () => handleNotify(),
      title: t('common.send_reminder'),
    }),
    ...insertIf(course.status !== CourseStatus.DRAFT, {
      onClick: () => handleReport(),
      title: t('common.see_report'),
    }),
    ...insertIf(course.status !== CourseStatus.DRAFT, {
      onClick: () => handleToggleStatus(),
      title: t(
        course.status === CourseStatus.ACTIVE
          ? 'general:deactivate'
          : 'general:activate',
      ),
    }),
    {
      onClick: () => handleDuplicate(),
      title: t('general:duplicate'),
    },
    {
      onClick: () => handleDelete(),
      title: t('general:delete'),
    },
  ];

  return (
    <>
      {deleteModal}
      {deactivateModal}
      {pathCourseWarning}
      <ActivateDrawer
        open={openActivateDrawer}
        isLoading={editStatusMutation.isLoading}
        onCancel={handleActivateCancel}
        onConfirm={handleActivateConfirm}
        course={course}
      />
      <NotifyDrawer
        open={openNotifyDrawer}
        isLoading={notifyMutation.isLoading}
        onCancel={handleNotifyCancel}
        onConfirm={handleNotifyConfirm}
        course={course}
      />
      <TableCell
        align="right"
        sx={{
          position: 'sticky',
          right: 0,
          zIndex: 1,
          p: 1,
          backgroundColor: palette.new.background.layout.tertiary,
        }}
      >
        <Stack
          sx={{
            height: '100%',
            position: 'absolute',
            left: 0,
            top: 0,
            width: '1px',
            '& > div': {
              display: 'flex',
              alignItems: 'center',
            },
            backgroundColor: palette.new.border.neutral.default,
          }}
        />
        <MenuList
          options={options}
          position="right"
        />
      </TableCell>
    </>
  );
};

export default CoursesTableRowActions;
