import { type UseFormReturn } from 'react-hook-form';
import { useMutation, useQuery } from 'react-query';
import { useNavigate } from 'react-router';

import { queryClient } from 'src/config/react-query';
import { useLokaliseTranslation } from 'src/utils/i18n';
import { LogEvents, logEvent } from 'src/utils/logging';

import useSnackbar from '../../hooks/useSnackbar';
import { serviceManagementKeys } from '../../queries';
import { serviceManagementRoutes } from '../../routes';
import {
  changeServiceItemStatus,
  deleteServiceItem,
  getServiceItem,
} from '../../services';
import {
  type SectionCreationSteps,
  ServiceItemStatus,
  ServiceManagementRole,
  Step,
} from '../../types';
import {
  parseAndCreateDraftServiceItem,
  parseAndUpdateDraftServiceItem,
} from '../../utils';

type Props = {
  id: string | undefined;
  isEdit: boolean;
  form: UseFormReturn<SectionCreationSteps>;
  setFormTag: (formTag: string) => void;
  navigateToServiceItems: () => void;
};

const useServiceItem = ({
  id,
  isEdit,
  form,
  setFormTag,
  navigateToServiceItems,
}: Props) => {
  const { t } = useLokaliseTranslation(['service_management', 'general']);
  const navigate = useNavigate();
  const { showSnackbar } = useSnackbar();

  const {
    data: serviceItem,
    isLoading: loadingServiceItem,
    isError: isServiceItemError,
  } = useQuery(
    serviceManagementKeys.serviceItems.detail(id!),
    () => getServiceItem(id!),
    {
      enabled: isEdit,
      select: response => response.data,
      onSuccess(data) {
        setFormTag(data.formTag);
      },
    },
  );

  const createDraftMutation = useMutation(
    () =>
      parseAndCreateDraftServiceItem(form.getValues() as SectionCreationSteps),
    {
      onSuccess: ({ data: catalogItemDraft }) => {
        const draftId = catalogItemDraft.id;
        navigate(serviceManagementRoutes.edit(draftId));
        logEvent(LogEvents.SERVICE_MGMT_SERVICE_CREATED, {
          role: ServiceManagementRole.ADMIN,
          serviceId: draftId,
          serviceName: catalogItemDraft.name,
          categoryId: catalogItemDraft.category?.id,
          categoryName: catalogItemDraft.category?.name,
          stateName: catalogItemDraft.status,
          status: catalogItemDraft.status,
        });
      },
      onError: () => {
        showSnackbar({
          title: t('saved_as_draft_error'),
          variant: 'error',
        });
      },
    },
  );

  const updateDraftMutation = useMutation(
    () =>
      parseAndUpdateDraftServiceItem(
        serviceItem!,
        form.getValues() as SectionCreationSteps,
      ),
    {
      onSuccess: async () => {
        await queryClient.invalidateQueries(
          serviceManagementKeys.serviceItems.detail(id!),
        );
        showSnackbar({
          title: t('saved_as_draft_success'),
          variant: 'success',
        });
      },
      onError: () => {
        showSnackbar({
          title: t('saved_as_draft_error'),
          variant: 'error',
        });
      },
    },
  );

  const deleteDraftMutation = useMutation(() => deleteServiceItem(id!), {
    onSuccess: () => {
      logEvent(LogEvents.SERVICE_MGMT_SERVICE_DELETED, {
        serviceId: serviceItem?.id,
        role: ServiceManagementRole.ADMIN,
        serviceName: serviceItem?.name,
        categoryId: serviceItem?.category?.id,
        categoryName: serviceItem?.category?.name,
        stateName: serviceItem?.status,
        status: serviceItem?.status,
      });
    },
  });

  const changeStatusMutation = useMutation(
    (newStatus: ServiceItemStatus) => changeServiceItemStatus(id!, newStatus),
    {
      onSuccess: (_, newStatus: ServiceItemStatus) => {
        t('change_service_item_status_success', {
          name: form.getValues(Step.BASIC_INFORMATION).name,
          status: t(newStatus),
        });
        navigateToServiceItems();
        if (newStatus === ServiceItemStatus.ACTIVE) {
          logEvent(LogEvents.SERVICE_MGMT_SERVICE_ACTIVATED, {
            serviceId: serviceItem?.id,
            role: ServiceManagementRole.ADMIN,
            serviceName: serviceItem?.name,
            categoryId: serviceItem?.category?.id,
            categoryName: serviceItem?.category?.name,
            stateName: serviceItem?.status,
            status: ServiceItemStatus.ACTIVE,
          });
        }
      },
      onError: () => {
        showSnackbar({
          title: t('change_service_item_status_error'),
          variant: 'error',
        });
      },
    },
  );

  return {
    serviceItem,
    loadingServiceItem,
    isServiceItemError,
    createDraftMutation,
    updateDraftMutation,
    deleteDraftMutation,
    changeStatusMutation,
  };
};

export default useServiceItem;
