import { type FC, useCallback, useState } from 'react';
import { Helmet } from 'react-helmet-async';
import { FormProvider } from 'react-hook-form';
import { useLocation, useNavigate, useParams } from 'react-router';

import Box from '@material-hu/mui/Box';
import Grid from '@material-hu/mui/Grid';
import Stack from '@material-hu/mui/Stack';

import TaskFocusHeader from '@material-hu/components/design-system/Header/TaskFocus';
import { type TaskFocusMainAction } from '@material-hu/components/design-system/Header/TaskFocus/types';
import Spinner from '@material-hu/components/design-system/ProgressIndicators/Spinner';

import useHuGoTheme from 'src/hooks/useHuGoTheme';
import { formatTitle } from 'src/utils/helmetUtils';

import CircularProgress from 'src/components/CircularProgress';

import { serviceManagementRoutes } from '../routes';
import { ServiceItemStatus, Step } from '../types';

import Assignment from './components/Assignment/Assignment';
import BasicInformation from './components/BasicInformation/BasicInformation';
import Collaborators from './components/Collaborators/Collaborators';
import Form from './components/FormCreation/Form';
import PdfCreation from './components/FormCreation/pdf/PdfCreation';
import CreateForm from './components/FormCreation/Regular/CreateForm';
import Revision from './components/Revision/Revision';
import SidebarNavigation from './components/SidebarNavigation';
import StepFooter from './components/StepFooter';
import FormCreationProvider from './contexts/FormCreation';
import PdfCreationProvider from './contexts/PdfFormCreation';
import useDynamicForm from './hooks/useDynamicForm';
import useNewServiceItemForm from './hooks/useNewServiceItemForm';
import useNewServiceItemFormSync from './hooks/useNewServiceItemFormSync';
import usePdfFormFlow from './hooks/usePdfFormFlow';
import useRegularFormFlow from './hooks/useRegularFormFlow';
import useServiceItem from './hooks/useServiceItem';
import useServiceItemActions from './hooks/useServiceItemActions';
import useServiceItemDirty from './hooks/useServiceItemDirty';
import useStepNavigation from './hooks/useStepNavigation';

type LocationState = {
  categoryId: string | null;
  navigatedFromCatalog?: boolean;
};

const DEFAULT_LOCATION_STATE: LocationState = {
  categoryId: null,
  navigatedFromCatalog: false,
};

const NewServiceItem: FC = () => {
  const HuGoThemeProvider = useHuGoTheme();
  const location = useLocation();
  const navigate = useNavigate();
  const { categoryId = null, navigatedFromCatalog = false } =
    (location.state as LocationState) ?? DEFAULT_LOCATION_STATE;
  const { id } = useParams<{ id: string }>();
  const isEdit = !!id;

  // eslint-disable-next-line react/hook-use-state
  const [navigatedToEdit] = useState(isEdit);

  const navigateToServiceItems = useCallback(() => {
    if (navigatedFromCatalog && categoryId) {
      navigate(serviceManagementRoutes.serviceItemsByCategory(categoryId));
    } else {
      navigate(serviceManagementRoutes.serviceItems());
    }
  }, [navigate, navigatedFromCatalog, categoryId]);

  // Form ------------------------------------------------------------------

  const { form, formValues, nameValue, isFormReady, setIsFormReady, t } =
    useNewServiceItemForm({ isEdit });

  // Server data -----------------------------------------------------------

  const dynamic = useDynamicForm(form.getValues(Step.FORM));

  const service = useServiceItem({
    id,
    isEdit,
    form,
    setFormTag: dynamic.setFormTag,
    navigateToServiceItems,
  });

  const { serviceItem, loadingServiceItem, isServiceItemError } = service;

  // Effects that sync RHF state with server data.
  useNewServiceItemFormSync({
    form,
    formValues,
    isEdit,
    serviceItem,
    isServiceItemError,
    dynamic,
    setIsFormReady,
    t,
  });

  // Derived state ---------------------------------------------------------

  const actionLoading =
    service.createDraftMutation.isLoading ||
    service.updateDraftMutation.isLoading ||
    dynamic.updateRegularFormMutation.isLoading ||
    dynamic.updatePdfFormMutation.isLoading ||
    dynamic.updatePdfAssetMutation.isLoading ||
    service.deleteDraftMutation.isLoading;

  const { isServiceItemDirty, isDynamicFormDirty } = useServiceItemDirty({
    formValues,
    serviceItem,
    dynamicForm: dynamic.dynamicForm,
    actionLoading,
    t,
  });

  // Step navigation -------------------------------------------------------

  const nav = useStepNavigation({
    formValues,
    nameValue,
    dynamic,
    serviceItem,
    createDraftMutation: service.createDraftMutation,
    isServiceItemDirty,
    isDynamicFormDirty,
    isEdit,
    actionLoading,
    t,
  });

  // Lifecycle actions (save / activate / exit + their modals) -------------

  const actions = useServiceItemActions({
    isEdit,
    nameValue,
    serviceItem,
    hasEditedForm: dynamic.hasEditedForm,
    isServiceItemDirty,
    navigatedFromCatalog,
    navigateToServiceItems,
    service,
    isValidStep: nav.isValidStep,
    setShowCreationValidations: nav.setShowCreationValidations,
  });

  // Form-creation flows ---------------------------------------------------

  const regular = useRegularFormFlow({
    form,
    formValues,
    dynamic,
    serviceItem,
  });

  const pdf = usePdfFormFlow({ form, formValues, dynamic, serviceItem });

  // Render ----------------------------------------------------------------

  const showActionButton =
    serviceItem?.status !== ServiceItemStatus.ACTIVE || dynamic.creatingForm;
  const mainTitle = navigatedToEdit
    ? t('edit_service_item')
    : t('create_service_item');
  const saveActionLabel = dynamic.creatingForm
    ? t('save_form')
    : t('general:save');

  const showAssignmentError =
    nav.showCreationValidations &&
    !!nav.sidebarItems.find(i => i.value === Step.ASSIGNMENT)?.hasError;

  const renderContent = () => {
    switch (nav.selectedNavItem) {
      case Step.BASIC_INFORMATION:
        return (
          <BasicInformation
            showValidations={nav.showCreationValidations}
            selectedCategoryId={categoryId}
          />
        );
      case Step.FORM:
        return (
          <Form
            showValidations={nav.showCreationValidations}
            onFormCreate={regular.handlers.onOpenCreateForm}
            onPdfSelected={pdf.handlers.onPdfSelected}
            onDeleteSelectedPdf={pdf.handlers.onDeleteSelectedPdf}
            dynamicForm={dynamic.dynamicForm}
            isActiveServiceItem={
              serviceItem?.status === ServiceItemStatus.ACTIVE
            }
            onEdit={nav.handlers.onNavigateToEditForm}
            loading={dynamic.loadingDynamicForm}
            loadingPdfAsset={dynamic.updatePdfAssetMutation.isLoading}
            loadingDeletePdf={
              dynamic.restoreToEmptyDynamicFormMutation.isLoading
            }
            hasModifiedFormForActiveServiceItem={
              dynamic.hasModifiedFormForActiveServiceItem
            }
          />
        );
      case Step.ASSIGNMENT:
        return <Assignment showError={showAssignmentError} />;
      case Step.COLLABORATORS: {
        const showCollaboratorsError =
          nav.showCreationValidations && !nav.isValidStep(Step.COLLABORATORS);
        return <Collaborators showError={showCollaboratorsError} />;
      }
      case Step.REVISION:
        return (
          <Revision
            onNavigateToSection={nav.handlers.onNavigateToSection}
            onNavigateToEditForm={nav.handlers.onNavigateToEditForm}
            showValidations={nav.showCreationValidations}
          />
        );
      default:
        return null;
    }
  };

  return (
    <HuGoThemeProvider>
      <Helmet>
        <title>{formatTitle(mainTitle)}</title>
      </Helmet>
      <Stack
        sx={{
          backgroundColor: 'background.paper',
          height: '100%',
        }}
      >
        {actions.modals}
        {regular.modal}
        <FormProvider {...form}>
          {(loadingServiceItem || !isFormReady) && (
            <CircularProgress centered />
          )}
          {!loadingServiceItem && isFormReady && (
            <Stack
              component="form"
              onSubmit={event => event.preventDefault()}
              noValidate
              sx={{ height: 1 }}
            >
              {!dynamic.creatingPdfForm && (
                <TaskFocusHeader
                  title={dynamic.creatingForm ? t(`${Step.FORM}`) : mainTitle}
                  onBack={
                    dynamic.creatingForm
                      ? regular.handlers.onCloseCreateForm
                      : undefined
                  }
                  onClose={
                    dynamic.creatingForm ? undefined : actions.handlers.onExit
                  }
                  mainActions={
                    showActionButton
                      ? [
                          {
                            key: 'save',
                            children: actionLoading
                              ? undefined
                              : saveActionLabel,
                            onClick: dynamic.creatingForm
                              ? () => regular.handlers.onFormSubmission()
                              : actions.handlers.onSave,
                            disabled: nav.saveButtonDisabled || actionLoading,
                            endIcon: actionLoading ? (
                              <Spinner size={16} />
                            ) : undefined,
                          } satisfies TaskFocusMainAction,
                        ]
                      : []
                  }
                />
              )}
              {dynamic.creatingForm && (
                <FormCreationProvider>
                  <CreateForm showValidations={dynamic.showFormValidations} />
                </FormCreationProvider>
              )}
              {dynamic.creatingPdfForm && (
                <PdfCreationProvider>
                  <PdfCreation
                    dynamicForm={dynamic.dynamicForm}
                    onSave={pdf.handlers.onSavePdfForm}
                    onRegisterScroll={pdf.handlers.onRegisterPdfScroll}
                    showValidations={dynamic.showFormValidations}
                    errorSensitiveFields={pdf.errorSensitiveFields}
                    onSaveAndExit={pdf.handlers.onSaveAndExitPdfForm}
                    onExitWithoutSaving={
                      pdf.handlers.onExitWithoutSavingPdfForm
                    }
                    onReplace={pdf.handlers.onReplacePdfForm}
                    loadingSave={dynamic.updatePdfFormMutation.isLoading}
                    loadingReplace={dynamic.updatePdfAssetMutation.isLoading}
                    isActiveServiceItem={
                      serviceItem?.status === ServiceItemStatus.ACTIVE
                    }
                  />
                </PdfCreationProvider>
              )}
              {!dynamic.creatingForm && !dynamic.creatingPdfForm && (
                <Grid
                  container
                  sx={{ flex: 1, minHeight: 0, overflow: 'hidden' }}
                >
                  <Grid
                    item
                    sm={4}
                    md={2}
                    sx={{
                      height: '100%',
                      // Stacking context above StepFooter so the sidebar covers its boxShadow
                      position: 'relative',
                      zIndex: 1,
                    }}
                  >
                    <SidebarNavigation
                      items={nav.sidebarItems}
                      selectedItem={nav.selectedNavItem}
                      onItemSelect={nav.handlers.onNavItemSelect}
                    />
                  </Grid>
                  <Grid
                    item
                    sm={8}
                    md={10}
                    sx={{
                      height: '100%',
                      display: 'flex',
                      flexDirection: 'column',
                    }}
                  >
                    <Box
                      sx={{
                        flex: 1,
                        overflow: 'auto',
                        backgroundColor: theme =>
                          theme.palette.new.background.layout.default,
                      }}
                    >
                      {renderContent()}
                    </Box>
                    <StepFooter
                      onAction={
                        nav.inRevision
                          ? actions.handlers.onActivate
                          : nav.handlers.onContinue
                      }
                      label={nav.continueButtonText}
                      loading={actionLoading}
                      disabled={nav.continueButtonDisabled}
                    />
                  </Grid>
                </Grid>
              )}
            </Stack>
          )}
        </FormProvider>
      </Stack>
    </HuGoThemeProvider>
  );
};

export default NewServiceItem;
