import { type FC, useState } from 'react';
import { FormProvider, useForm } from 'react-hook-form';
import { useMutation, useQuery, useQueryClient } from 'react-query';
import { useLocation, useNavigate, useParams } from 'react-router-dom';

import { type AxiosError } from 'axios';
import Stack from '@material-hu/mui/Stack';
import { type FileAsset } from '@material-hu/types/attachments';

import { useDialogLayer } from '@material-hu/components/layers/Dialogs';

import { logEvent } from 'src/config/logging';
import useGeneralError from 'src/hooks/useGeneralError';
import { withHuGoTheme } from 'src/hooks/useHuGoTheme';
import { serviceManagementKeys } from 'src/pages/dashboard/serviceManagement/queries';
import SuccessCreationModal from 'src/pages/dashboard/serviceManagement/servicePortal/serviceItem/components/SuccessCreationModal';
import {
  createForm,
  getServiceItem,
  initForm,
  updateProgress,
} from 'src/pages/dashboard/serviceManagement/services';
import {
  DynamicFormType,
  type FormSectionBody,
  type SectionContent,
  type ServiceManagementError,
} from 'src/pages/dashboard/serviceManagement/types';
import { EventName } from 'src/types/amplitude';
import { useLokaliseTranslation } from 'src/utils/i18n';

import { UNAUTHORIZED_ERROR_CODE } from '../../constants';
import UnauthorizedServiceCatalog from '../../general/UnauthorizedServiceCatalog';
import { serviceManagementRoutes } from '../../routes';

import RegularFormCompletion from './components/RegularFormCompletion';
import PdfCompletionProvider from './contexts/PdfFormCompletionProvider';
import PdfFormCompletion from './pdf/PdfFormCompletion';

export const InitialForm: FC = () => {
  const { t } = useLokaliseTranslation('service_management');
  const { id } = useParams();
  const queryClient = useQueryClient();
  const navigate = useNavigate();
  const location = useLocation();
  const showGeneralError = useGeneralError();

  const navigatedFromServiceItems =
    location.state?.navigatedFromServiceItems || false;

  const handleNavigateBack = () => {
    if (navigatedFromServiceItems) {
      navigate(-1);
      return;
    }
    navigate(serviceManagementRoutes.userSide.serviceItems());
  };

  const [isUnauthorized, setIsUnauthorized] = useState(false);
  const [progressionId, setProgressionId] = useState<string | null>(null);
  const [tagId, setTagId] = useState<string | null>(null);
  const [currentForm, setCurrentForm] = useState<SectionContent | null>(null);
  const [showDescription, setShowDescription] = useState(true);
  const [formType, setFormType] = useState<DynamicFormType | null>(null);
  const [isLoading, setIsLoading] = useState(true);
  const [pdfFileAsset, setPdfFileAsset] = useState<FileAsset | null>(null);

  const [erroredFormAnswerId, setErroredFormAnswerId] = useState<number | null>(
    null,
  );

  const { mutate: startForm } = useMutation(
    ({ tag, token }: { tag: string; token: string }) => initForm(tag, token),
    {
      onSuccess: data => {
        setProgressionId(data.data.id);
        setTagId(data.data.formTag);
        setCurrentForm(data.data.nextSection.content);
        setFormType(data.data.form?.type || null);
        setPdfFileAsset(data.data.form?.fileAsset || null);
        setIsLoading(false);
      },
    },
  );

  const { data: serviceItem, isLoading: isLoadingServiceItem } = useQuery(
    serviceManagementKeys.detail(id!),
    () => getServiceItem(id!),
    {
      enabled: !!id,
      select: response => response.data,
      onSuccess: data => {
        startForm({
          tag: data.formTag,
          token: data.formProgressionToken,
        });
      },
      onError: (err: AxiosError<ServiceManagementError>) => {
        if (
          err.response?.status === 403 &&
          err.response?.data?.code === UNAUTHORIZED_ERROR_CODE
        ) {
          setIsUnauthorized(true);
          setIsLoading(false);
        } else {
          showGeneralError(err, t('error_loading_catalog_items'));
        }
      },
    },
  );

  const form = useForm({ mode: 'onChange' });
  const {
    getValues,
    reset,
    formState: { dirtyFields },
  } = form;

  const { openDialog, closeDialog } = useDialogLayer();

  const handleShowSuccessCreationModal = (taskId: string) => {
    if (!serviceItem) return;

    openDialog({
      content: (
        <SuccessCreationModal
          id={taskId}
          title={serviceItem.name}
          automaticMessage={serviceItem.automaticMessage || undefined}
        />
      ),
      dialogProps: {
        fullScreen: true,
        PaperProps: {
          sx: {
            borderRadius: 0,
          },
        },
      },
    });

    logEvent(EventName.SERVICE_MGMT_REQUEST_COMPLETED, {
      serviceId: serviceItem.id,
      serviceName: serviceItem.name,
      categoryId: serviceItem.category?.id,
      categoryName: serviceItem.category?.name,
    });
  };

  const handleCloseFormModal = () => {
    if (Object.keys(dirtyFields).length > 0) {
      openDialog({
        title: t('close_form_title'),
        textBody: t('close_form_description'),
        onClose: () => closeDialog(),
        primaryButtonProps: {
          children: t('continue_completing'),
          onClick: () => closeDialog(),
        },
        secondaryButtonProps: {
          children: t('leave'),
          onClick: handleNavigateBack,
        },
        dialogProps: {
          maxWidth: 'lg',
        },
      });
    } else {
      handleNavigateBack();
    }
  };

  const createFormMutation = useMutation(
    ({
      catalogItemId,
      formAnswerId,
    }: {
      catalogItemId: string;
      formAnswerId: number;
    }) => createForm(catalogItemId, formAnswerId),
    {
      onSuccess: data => {
        queryClient.invalidateQueries(serviceManagementKeys.tasks.all());
        handleShowSuccessCreationModal(data.data.id);
        setErroredFormAnswerId(null);
      },
      onError: (_err, vars) => {
        if (vars.formAnswerId) {
          setErroredFormAnswerId(vars.formAnswerId);
        }
      },
    },
  );

  const { mutate: doUpdateSectionMutation, isLoading: isLoadingSectionUpdate } =
    useMutation(
      serviceManagementKeys.form.nextSectionForm(
        serviceItem?.formTag!,
        progressionId!,
      ),
      (bodyData: FormSectionBody) => {
        return updateProgress(tagId!, progressionId!, bodyData);
      },
      {
        onSuccess: data => {
          if (data.data.nextSection) {
            setProgressionId(data.data.id);
            setCurrentForm(data.data.nextSection.content);
            reset(getValues());
            setShowDescription(
              data.data.firstSection === data.data.currentSection,
            );
            setErroredFormAnswerId(null);
          } else {
            setErroredFormAnswerId(data.data.formAnswerId!);
            createFormMutation.mutate({
              catalogItemId: id!,
              formAnswerId: data.data.formAnswerId!,
            });
          }
        },
      },
    );

  // Wrapper to short-circuit update flow when we already have a saved formAnswerId
  const updateSectionMutation = (variables: FormSectionBody, options?: any) => {
    if (erroredFormAnswerId) {
      if (createFormMutation.isLoading) return;
      createFormMutation.mutate(
        {
          catalogItemId: id!,
          formAnswerId: erroredFormAnswerId!,
        },
        options,
      );
      return;
    }
    return doUpdateSectionMutation(variables, options);
  };

  const loading = isLoading || isLoadingServiceItem;

  if (isUnauthorized) {
    return <UnauthorizedServiceCatalog />;
  }

  return (
    <Stack
      sx={{
        backgroundColor: ({ palette }) =>
          palette.new.background.layout.tertiary,
        height: 1,
        overflow: 'auto',
      }}
    >
      <FormProvider {...form}>
        {(loading || formType === DynamicFormType.REGULAR) && (
          <RegularFormCompletion
            currentForm={currentForm}
            isLoading={loading}
            isLoadingSection={isLoadingSectionUpdate}
            createFormMutation={createFormMutation}
            serviceItem={serviceItem}
            updateSectionMutation={updateSectionMutation}
            handleCloseFormModal={handleCloseFormModal}
            showDescription={showDescription}
          />
        )}
        {!loading && formType === DynamicFormType.PDF && pdfFileAsset && (
          <PdfCompletionProvider>
            <PdfFormCompletion
              pdfFileAsset={pdfFileAsset}
              currentForm={currentForm}
              serviceItem={serviceItem}
              onCloseForm={handleCloseFormModal}
              updateSectionMutation={updateSectionMutation}
              loadingSendForm={
                isLoadingSectionUpdate || createFormMutation.isLoading
              }
            />
          </PdfCompletionProvider>
        )}
      </FormProvider>
    </Stack>
  );
};

export default withHuGoTheme(InitialForm);
