import { useMutation } from 'react-query';

import { queryClient } from 'src/config/react-query';
import { type RequestError, type RequestSuccess } from 'src/types/services';
import { LogEvents, logEvent } from 'src/utils/logging';

import { CertificateAction } from '../constants';
import { learningCertificatesKeys } from '../queries';
import { deleteLearningCertificate } from '../services';
import { type DeleteLearningCertificateParams } from '../types';
import { isLearningCertificateInUseError } from '../utils';
import {
  type LearningCertificatesListSnapshot,
  optimisticallyUpdateLearningCertificatesList,
  restoreLearningCertificatesListQueries,
} from '../utils/queries';

import { useCertificateActionSnackbars } from './useCertificateActionSnackbars';

export type TSuccess = RequestSuccess<typeof deleteLearningCertificate>;
export type TError = RequestError;
export type TValues = DeleteLearningCertificateParams;
type TContext = { previousQueries: LearningCertificatesListSnapshot };

export const useDeleteLearningCertificate = () => {
  const snackbars = useCertificateActionSnackbars();

  return useMutation<TSuccess, TError, TValues, TContext>({
    mutationFn: deleteLearningCertificate,
    onMutate: async ({ certificateId }) => {
      const previousQueries =
        await optimisticallyUpdateLearningCertificatesList(items =>
          items.filter(certificate => certificate.id !== certificateId),
        );

      return { previousQueries };
    },
    onSuccess: (_, { certificateId, certificateName }) => {
      logEvent(LogEvents.CERTIFICATE_DELETED, { certificateId });
      snackbars.success(CertificateAction.DELETE, certificateName);
    },
    onError: (error, _, context) => {
      if (context?.previousQueries) {
        restoreLearningCertificatesListQueries(context.previousQueries);
      }

      if (isLearningCertificateInUseError(error)) {
        snackbars.inUseError(CertificateAction.DELETE);
        return;
      }

      snackbars.error(CertificateAction.DELETE);
    },
    onSettled: () => {
      queryClient.invalidateQueries(learningCertificatesKeys.list.all());
    },
  });
};
