import { type FieldNamesMarkedBoolean } from 'react-hook-form';
import {
  type UseMutationOptions,
  useMutation,
  useQueryClient,
} from 'react-query';
import { useNavigate } from 'react-router-dom';

import useSnackbar from '@material-hu/components/design-system/Snackbar';

import { logEvent } from 'src/config/logging';
import { EventName } from 'src/types/amplitude';
import { type RequestError, type RequestSuccess } from 'src/types/services';
import { useLokaliseTranslation } from 'src/utils/i18n';

import { librariesKeys } from '../queries';
import { huLibrariesRoutes } from '../routes';
import { type ArticleFormValues } from '../schemas';
import { updateArticle } from '../services';
import { type Article } from '../types';
import { formatArticleEditPayload } from '../utils';

const HTTP_NOT_FOUND = 404;

type TValues = {
  values: ArticleFormValues;
  dirtyFields?: FieldNamesMarkedBoolean<ArticleFormValues>;
};

type TSuccess = RequestSuccess<typeof updateArticle>;
type TError = RequestError;
type TOptions = UseMutationOptions<TSuccess, TError, TValues>;

export const useUpdateArticle = (article: Article, options: TOptions = {}) => {
  const { t } = useLokaliseTranslation('libraries');
  const { enqueueSnackbar } = useSnackbar();
  const queryClient = useQueryClient();
  const navigate = useNavigate();

  return useMutation<TSuccess, TError, TValues>({
    mutationFn: async ({ values, dirtyFields }) =>
      updateArticle(
        article.id,
        await formatArticleEditPayload(values, dirtyFields),
      ),
    ...options,
    onSuccess: (...args) => {
      options.onSuccess?.(...args);
      enqueueSnackbar({
        title: t('article.save.success'),
        variant: 'success',
      });
      logEvent(EventName.LIBRARY_CONTENT_EDIT_SAVE, {
        libraryId: article.id,
        parentId: article.parentId,
        title: article.title,
      });
      queryClient.invalidateQueries(librariesKeys.all());
    },
    onError: (err, ...args) => {
      options.onError?.(err, ...args);

      if (err?.response?.status === HTTP_NOT_FOUND) {
        enqueueSnackbar({
          title: t('library.not_available'),
          variant: 'error',
        });
        navigate(huLibrariesRoutes.base(), { replace: true });
        return;
      }

      enqueueSnackbar({
        title: t('article.save.error'),
        variant: 'error',
      });
    },
  });
};
