import { useMemo } from 'react';
import { FormProvider, useForm } from 'react-hook-form';
import { useMutation, useQueryClient } from 'react-query';

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

import Dialog from '@material-hu/components/design-system/Dialog';
import FormDatePicker from '@material-hu/components/design-system/Inputs/DatePicker/form';
import useHuSnackbar from '@material-hu/components/design-system/Snackbar';

import { useLokaliseTranslation } from 'src/utils/i18n';
import { requiredLabel } from 'src/utils/stringUtils';

import { getMaxTodayDate, parseBackendDate } from '../../../dateUtils';
import { applicantsKeys } from '../../../queries';
import { hireApplicant } from '../../../services';
import {
  type ApplicationStage,
  type HireApplicantFormValues,
} from '../../../types';
import { hireApplicantFormResolver } from '../../utils';

type UseHireModalProps = {
  jobId: number;
  applicationId: number;
  applicantName: string;
  stage?: ApplicationStage;
  onSuccess: () => void;
};

export const useHireModal = ({
  jobId,
  applicationId,
  applicantName,
  stage,
  onSuccess,
}: UseHireModalProps) => {
  const { t } = useLokaliseTranslation(['ats', 'validations', 'general']);
  const queryClient = useQueryClient();
  const { enqueueSnackbar } = useHuSnackbar();

  const resolver = useMemo(
    () => (values: Partial<HireApplicantFormValues>) =>
      hireApplicantFormResolver(values, t, stage),
    [t, stage],
  );

  const form = useForm<Partial<HireApplicantFormValues>>({
    defaultValues: {
      hireDate: new Date(),
      startDate: undefined,
    },
    mode: 'onChange',
    shouldUnregister: false,
    resolver,
  });

  const { mutate, isLoading } = useMutation({
    mutationFn: (values: Partial<HireApplicantFormValues>) =>
      hireApplicant({ values, jobId, applicationId }),
    onSuccess: () => {
      enqueueSnackbar({
        title: t('job_application.actions.hire.success', {
          name: applicantName,
        }),
        variant: 'success',
      });
      closeModal();
      queryClient.invalidateQueries(
        applicantsKeys.applicationDetail(jobId, applicationId),
      );
      onSuccess();
    },
    onError: () => {
      enqueueSnackbar({
        title: t('general:error_title'),
        variant: 'error',
      });
    },
  });

  const onSubmit = form.handleSubmit(
    (values: Partial<HireApplicantFormValues>) => {
      mutate(values);
    },
  );

  const hireDate = form.watch('hireDate');

  const { closeModal, ...modalProps } = useModal(
    Dialog,
    {
      fullWidth: true,
    },
    {
      title: t('job_application.actions.hire.title'),
      body: (
        <Stack>
          <Typography
            variant="globalS"
            fontWeight="fontWeightRegular"
          >
            {t('job_application.actions.hire.description')}
          </Typography>
          <FormProvider {...form}>
            <Stack sx={{ gap: 2, flexDirection: 'column', mt: 2 }}>
              <FormDatePicker
                name="hireDate"
                inputProps={{
                  label: requiredLabel(
                    t('job_candidates.list.hired.columns.date'),
                  ),
                  enableClear: false,
                  minDate: stage?.startDate
                    ? parseBackendDate(stage.startDate)
                    : undefined,
                  maxDate: getMaxTodayDate(),
                }}
              />
              <FormDatePicker
                name="startDate"
                inputProps={{
                  label: requiredLabel(
                    t('job_candidates.list.hired.columns.start_date_long'),
                  ),
                  enableClear: false,
                  minDate: hireDate,
                }}
              />
            </Stack>
          </FormProvider>
        </Stack>
      ),
      primaryButtonProps: {
        children: t('job_candidates.actions.hire'),
        loading: isLoading,
        disabled: isLoading || !form.formState.isValid,
        onClick: () => {
          onSubmit();
        },
      },
      secondaryButtonProps: {
        children: t('general:cancel'),
        onClick: () => {
          closeModal();
        },
      },
    },
  );

  return { ...modalProps, closeModal };
};
