import { useMutation, useQuery, useQueryClient } from 'react-query';
import { useNavigate, useParams } from 'react-router';

import { isEqual } from 'lodash-es';
import { useModal } from '@material-hu/hooks/useModal';
import Stack from '@material-hu/mui/Stack';
import { fadeIn } from '@material-hu/utils/animations';

import Button from '@material-hu/components/design-system/Buttons/Button';
import Dialog from '@material-hu/components/design-system/Dialog';
import useSnackbar from '@material-hu/components/design-system/Snackbar';
import Title from '@material-hu/components/design-system/Title';

import useAuth from 'src/contexts/JWTContext';
import { employeeLifecycleKeys } from 'src/pages/dashboard/EmployeeLifecycle/queries';
import { employeeLifecycleRoutes } from 'src/pages/dashboard/EmployeeLifecycle/routes';
import {
  activateProcess,
  getProcessSummary,
} from 'src/pages/dashboard/EmployeeLifecycle/services';
import { useLokaliseTranslation } from 'src/utils/i18n';
import { LogEvents, logEvent } from 'src/utils/logging';

import StepLayout from '../../StepLayout';

import AssignmentSummary from './components/AssignmentSummary';
import GeneralDataSummary from './components/GeneralDataSummary';
import ProcessSummary from './components/ProcessSummary';
import { type ReviewStepProps } from './types';

const ReviewStep = ({
  processId: inheritedProcessId,
  onNextStep,
  onPreviousStep,
  onJumpToStep,
  isDraft,
  disabled,
  sx,
}: ReviewStepProps) => {
  const { user } = useAuth();
  const navigate = useNavigate();
  const { t } = useLokaliseTranslation('employee_lifecycle');
  const queryClient = useQueryClient();
  const { processId: paramsProcessId } = useParams();
  const { enqueueSnackbar } = useSnackbar();
  const processId = inheritedProcessId || paramsProcessId;

  const processSummaryQuery = useQuery({
    queryKey: employeeLifecycleKeys.processSummary(processId ?? ''),
    queryFn: () => getProcessSummary(processId ?? ''),
  });

  const hasChanges =
    processSummaryQuery.data?.hasChanges ||
    !isEqual(
      processSummaryQuery.data?.parentVersion?.assignmentSummary,
      processSummaryQuery.data?.latestVersion?.assignmentSummary,
    );

  const activateProcessMutation = useMutation({
    mutationFn: activateProcess,
    onError: () => {
      enqueueSnackbar({
        variant: 'error',
        title: t(
          'process_stepper.steps.summary.actions.' +
            (isDraft ? 'activate' : 'apply_changes') +
            '.error',
        ),
      });
    },
    onSuccess: () => {
      queryClient.invalidateQueries(employeeLifecycleKeys.all());
      enqueueSnackbar({
        variant: 'success',
        title: t(
          'process_stepper.steps.summary.actions.' +
            (isDraft ? 'activate' : 'apply_changes') +
            '.success',
        ),
      });
      logEvent(LogEvents.EMP_LIF_ONBOARDING_ACTIVATED, {
        onboardingId: processId ?? '',
        userId: user?.id,
      });
      onNextStep?.();
    },
  });

  const confirmActivationModal = useModal(
    Dialog,
    { maxWidth: 'sm', disableEscapeKeyDown: activateProcessMutation.isLoading },
    {
      onClose: () => {
        if (activateProcessMutation.isLoading) {
          throw new Error('Activation in progress');
        }
        confirmActivationModal.closeModal();
      },
      title: t(
        'process_stepper.steps.summary.actions.activate.confirm_dialog.title',
      ),
      textBody: t(
        'process_stepper.steps.summary.actions.activate.confirm_dialog.description',
      ),
      primaryButtonProps: {
        children: t(
          'process_stepper.steps.summary.actions.activate.confirm_dialog.confirm',
        ),
        loading: activateProcessMutation.isLoading,
        onClick: () => {
          activateProcessMutation.mutate(processId ?? '');
        },
      },
      secondaryButtonProps: {
        children: t(
          'process_stepper.steps.summary.actions.activate.confirm_dialog.cancel',
        ),
        disabled: activateProcessMutation.isLoading,
        onClick: () => {
          confirmActivationModal.closeModal();
        },
      },
    },
  );

  const confirmApplyChangesModal = useModal(
    Dialog,
    { maxWidth: 'sm', disableEscapeKeyDown: activateProcessMutation.isLoading },
    {
      onClose: () => {
        if (activateProcessMutation.isLoading) {
          throw new Error('Activation in progress');
        }
        confirmApplyChangesModal.closeModal();
      },
      title: t(
        'process_stepper.steps.summary.actions.apply_changes.confirm_dialog.title',
      ),
      textBody: t(
        'process_stepper.steps.summary.actions.apply_changes.confirm_dialog.description',
      ),
      primaryButtonProps: {
        children: t('general:confirm').toLowerCase(),
        loading: activateProcessMutation.isLoading,
        sx: {
          textTransform: 'capitalize',
        },
        onClick: () => {
          activateProcessMutation.mutate(processId ?? '');
        },
      },
      secondaryButtonProps: {
        children: t('general:cancel'),
        disabled: activateProcessMutation.isLoading,
        onClick: () => {
          confirmApplyChangesModal.closeModal();
        },
      },
    },
  );

  const confirmButtonText = [
    !isDraft && !hasChanges
      ? t('process_stepper.steps.summary.back_to_list_button')
      : null,
    !isDraft && hasChanges
      ? t('process_stepper.steps.summary.actions.apply_changes.button_text')
      : null,
    isDraft
      ? t('process_stepper.steps.summary.actions.activate.button_text')
      : null,
  ]
    .filter(Boolean)
    .join('');

  return (
    <StepLayout
      sx={sx}
      footer={
        <>
          <Button
            variant="tertiary"
            size="large"
            sx={{
              animation: `${fadeIn} 125ms ease-in-out backwards`,
            }}
            disabled={activateProcessMutation.isLoading}
            onClick={onPreviousStep}
          >
            {t('general:back')}
          </Button>
          <Button
            variant="primary"
            size="large"
            onClick={() => {
              if (isDraft) {
                confirmActivationModal.showModal();
              } else {
                if (!hasChanges) {
                  navigate(employeeLifecycleRoutes.base());
                  return;
                }
                confirmApplyChangesModal.showModal();
              }
            }}
            disabled={activateProcessMutation.isLoading}
            loading={activateProcessMutation.isLoading}
          >
            {confirmButtonText}
          </Button>
        </>
      }
    >
      <Stack sx={{ gap: 5, px: 2 }}>
        <Title
          title={t('process_stepper.steps.summary.title')}
          variant="M"
        />
        <Stack sx={{ gap: 1 }}>
          <GeneralDataSummary
            processId={processId ?? ''}
            onAction={() => onJumpToStep?.('generalData')}
            disableEdit={disabled}
          />
          <ProcessSummary
            processId={processId ?? ''}
            onAction={() => onJumpToStep?.('process')}
            stepsCount={processSummaryQuery.data?.parentVersion.stepsQty ?? 0}
            actionsCount={
              processSummaryQuery.data?.parentVersion.actionsQty ?? 0
            }
            disableEdit={disabled}
          />
          <AssignmentSummary
            criteria={
              processSummaryQuery.data?.latestVersion.assignmentSummary
                ?.criteria ?? []
            }
            newCriteria={
              processSummaryQuery.data?.parentVersion.assignmentSummary
                ?.criteria ?? []
            }
            totalAudience={
              processSummaryQuery.data?.latestVersion.assignmentSummary
                ?.totalAudience ?? 0
            }
            newTotalAudience={
              processSummaryQuery.data?.parentVersion.assignmentSummary
                ?.totalAudience ?? 0
            }
            loading={processSummaryQuery.isLoading}
            onAction={() => onJumpToStep?.('assignment')}
          />
        </Stack>
      </Stack>
      {confirmActivationModal.modal}
      {confirmApplyChangesModal.modal}
    </StepLayout>
  );
};

export default ReviewStep;
