// This is the default dynamic form that is created when a new form is created. This is used to "restore" the form to its original state.
import { useState } from 'react';
import { useMutation, useQuery } from 'react-query';

import { FileAsset } from '@material-hu/types/attachments';

import { queryClient } from 'src/config/react-query';
import {
  getDynamicForm,
  updateDynamicForm,
} from 'src/services/dynamicFormsService';
import {
  DynamicFormActionType,
  DynamicFormEventType,
  DynamicFormType,
} from 'src/types/dynamicForms';
import { useLokaliseTranslation } from 'src/utils/i18n';

import useSnackbar from '../../hooks/useSnackbar';
import { serviceManagementKeys } from '../../queries';
import { SectionCreationSteps, Step } from '../../types';
import { parseAndUpdateDynamicForm } from '../../utils';
import { parseAndUpdateDynamicFormPdf } from '../components/FormCreation/pdf/utils';

const defaultDynamicForm = {
  title: 'Form Title',
  type: DynamicFormType.REGULAR,
  variables: {},
  sectionsCount: 1,
  initialAction: {
    event: DynamicFormEventType.FORM_START,
    nameId: 'formStart',
    nextSection: 'section01',
    payload: {},
    type: DynamicFormActionType.STATIC,
  },
  sections: [
    {
      action: {
        event: DynamicFormEventType.SECTION_COMPLETE,
        nameId: 'success',
        nextSection: 'NEXT',
        payload: {},
        type: DynamicFormActionType.STATIC,
      },
      components: [],
      data: {},
      nameId: 'section01',
      title: 'Section 01',
    },
  ],
};

const useDynamicForm = (formValues: SectionCreationSteps[Step.FORM]) => {
  const { t } = useLokaliseTranslation('service_management');
  const { showSnackbar } = useSnackbar();

  const [formTag, setFormTag] = useState<string | null>(null);
  const [hasEditedForm, setHasEditedForm] = useState(false);
  const [showFormValidations, setShowFormValidations] = useState(false);
  const [creatingForm, setCreatingForm] = useState(false);
  const [creatingPdfForm, setCreatingPdfForm] = useState(false);
  const [
    hasModifiedFormForActiveServiceItem,
    setHasModifiedFormForActiveServiceItem,
  ] = useState(false);

  const [errorSensitiveFields, setErrorSensitiveFields] = useState<
    Record<string, boolean | undefined>
  >({});

  const { data: dynamicForm, isLoading: loadingDynamicForm } = useQuery(
    serviceManagementKeys.dynamicForms.detail(formTag!),
    () => getDynamicForm(formTag!),
    {
      enabled: !!formTag,
      select: response => response.data,
      keepPreviousData: true,
    },
  );

  // This is used to update the dynamic form with the fresh react-hook-form values
  const updateRegularFormMutation = useMutation(
    () =>
      parseAndUpdateDynamicForm({
        formTag: formTag!,
        formValues,
        dynamicForm: dynamicForm!,
      }),
    {
      onSuccess: () => {
        setHasEditedForm(true);
        queryClient.invalidateQueries(
          serviceManagementKeys.dynamicForms.detail(formTag!),
        );
      },
    },
  );

  const updatePdfFormMutation = useMutation(
    () =>
      parseAndUpdateDynamicFormPdf({
        formTag: formTag!,
        formValues,
        dynamicForm: dynamicForm!,
      }),
    {
      onSuccess: () => {
        showSnackbar({
          title: t('pdf_form_updated_success'),
          variant: 'success',
        });
        setHasEditedForm(true);
        // I need to invalidate the query instead of setQueryData because
        // the fileAsset is not returned in the response, just the fileAssetId.
        queryClient.invalidateQueries(
          serviceManagementKeys.dynamicForms.detail(formTag!),
        );
      },
      onError: () => {
        showSnackbar({
          title: t('pdf_form_update_error'),
          description: t('try_again_later'),
          variant: 'error',
        });
      },
    },
  );

  // This is used to update the dynamic form with the pdf metadata
  const updatePdfAssetMutation = useMutation(
    (pdfAsset: FileAsset) => {
      return updateDynamicForm(formTag!, {
        ...defaultDynamicForm, // Reset the form to its original state
        fileAssetId: pdfAsset.id,
        type: DynamicFormType.PDF,
      });
    },
    {
      onSuccess: () => {
        setShowFormValidations(false);
        setErrorSensitiveFields({});
        queryClient.invalidateQueries(
          serviceManagementKeys.dynamicForms.detail(formTag!),
        );
      },
      onError: () => {
        showSnackbar({
          title: t('pdf_asset_update_error'),
          description: t('try_again_later'),
          variant: 'error',
        });
      },
    },
  );

  // Artificial "delete" mutation to reset the form to its original state
  const restoreToEmptyDynamicFormMutation = useMutation(
    () => updateDynamicForm(formTag!, defaultDynamicForm),
    {
      onError: () => {
        showSnackbar({
          title: t('delete_pdf_error'),
          description: t('try_again_later'),
          variant: 'error',
        });
      },
      onSuccess: async () => {
        await queryClient.invalidateQueries(
          serviceManagementKeys.dynamicForms.detail(formTag!),
        );
      },
    },
  );

  return {
    // Form Tag
    formTag,
    setFormTag,
    // Dynamic Form
    dynamicForm,
    loadingDynamicForm,
    // Mutations
    updateRegularFormMutation,
    updatePdfFormMutation,
    restoreToEmptyDynamicFormMutation,
    updatePdfAssetMutation,
    // Flags
    creatingForm,
    setCreatingForm,
    creatingPdfForm,
    setCreatingPdfForm,
    showFormValidations,
    setShowFormValidations,
    hasEditedForm,
    setHasEditedForm,
    hasModifiedFormForActiveServiceItem,
    setHasModifiedFormForActiveServiceItem,
    errorSensitiveFields,
    setErrorSensitiveFields,
  };
};

export default useDynamicForm;
