/** biome-ignore-all lint/suspicious/noEmptyBlockStatements: need to return empty function */
import {
  type BaseSyntheticEvent,
  useCallback,
  useEffect,
  useMemo,
  useRef,
  useState,
} from 'react';
import { useMutation, useQueryClient } from 'react-query';
import { useNavigate } from 'react-router-dom';

import { type ButtonProps } from '@material-hu/components/design-system/Buttons/Button';
import useHuSnackbar from '@material-hu/components/design-system/Snackbar';

import { useLokaliseTranslation } from 'src/utils/i18n';

import { type FooterProps } from '../../components/Footer';
import { jobKeys } from '../../queries';
import { recruitingRoutes } from '../../routes';
import { createJobPosting, openJobOffer } from '../../services';
import { StepCompletionStatus, Steps } from '../../types';

import { useApplicationFormChanges } from './useApplicationFormChanges';
import { useGeneralConfigSection } from './useGeneralConfigSection';
import { useJobApplicationForm } from './useJobApplicationForm';
import { useJobApplicationFormSection } from './useJobApplicationFormSection';
import { useJobBoards } from './useJobBoards';
import { useJobPublicDescription } from './useJobPublicDescription';
import { useJobPublicDescriptionSection } from './useJobPublicDescriptionSection';
import { useProcessStagesSection } from './useProcessStagesSection';
import { usePublishForm } from './usePublishForm';

export const useJobForm = () => {
  const { t } = useLokaliseTranslation(['ats', 'validations', 'general']);
  const queryClient = useQueryClient();
  const [activeStep, setActiveStep] = useState<number>(0);
  const [hasVisitedPublish, setHasVisitedPublish] = useState(false);
  const [hasVisitedProcessStages, setHasVisitedProcessStages] = useState(false);
  const prevActiveStepRef = useRef(activeStep);
  const { enqueueSnackbar } = useHuSnackbar();
  const navigate = useNavigate();

  const {
    form: generalConfigForm,
    onSave: onSaveGeneralConfig,
    isLoading: isLoadingGeneralConfig,
    hiringReasons,
    jobId,
  } = useGeneralConfigSection();

  const {
    form: processStagesForm,
    onSave: onSaveProcessStages,
    isLoading: isLoadingProcessStages,
    backendHiringPipeline,
    isLoadingBackendHiringPipeline,
  } = useProcessStagesSection(jobId);

  const { hasJobBoards, jobBoardId } = useJobBoards();

  const { publicDescription, isFetching: isFetchingPublicDescription } =
    useJobPublicDescription(jobId);
  const jobName = (generalConfigForm.watch('name') as string | undefined) || '';

  const publishForm = usePublishForm({
    initialValues: publicDescription || {
      title: jobName,
      description: '',
    },
  });

  useEffect(() => {
    if (publicDescription) {
      publishForm.reset(publicDescription, {
        keepDirty: false,
        keepSubmitCount: true,
        keepIsSubmitted: true,
      });
    }
  }, [publicDescription, publishForm.reset]);

  useEffect(() => {
    if (
      publishForm.formState.isSubmitted ||
      publishForm.formState.isDirty ||
      !jobName
    ) {
      return;
    }
    if (publishForm.getValues('title') !== jobName) {
      publishForm.setValue('title', jobName, {
        shouldDirty: false,
        shouldValidate: false,
      });
    }
  }, [jobName, publishForm]);

  const {
    onSave: onSavePublicDescription,
    isLoading: isLoadingPublicDescription,
  } = useJobPublicDescriptionSection({
    jobId,
    publishForm,
    publicDescription: publicDescription ?? undefined,
  });

  const { jobApplicationForm, isFetching: isFetchingApplicationForm } =
    useJobApplicationForm(jobId);

  const {
    applicationFormChanges,
    onApplicationFormChange,
    resetApplicationFormChanges,
  } = useApplicationFormChanges();

  const {
    onSave: onSaveApplicationForm,
    isLoading: isLoadingApplicationForm,
    isApplicationFormDirty,
  } = useJobApplicationFormSection({
    jobId,
    changes: applicationFormChanges,
    onSuccess: resetApplicationFormChanges,
  });

  const { mutate: openJobMutate, isLoading: isLoadingJobStatus } = useMutation(
    (_: boolean) => {
      if (!jobId) {
        throw new Error('Job ID is required');
      }
      return openJobOffer({ jobOfferId: jobId });
    },
    {
      onSuccess: (_, shouldPublish) => {
        if (shouldPublish) {
          publishJobOfferMutate();
        } else {
          queryClient.invalidateQueries(jobKeys.detail(jobId));
          queryClient.invalidateQueries(jobKeys.all());
          queryClient.invalidateQueries(jobKeys.publicDescription(jobId));
          handleSuccessRedirect({
            message: t('job_offers.alerts.job_open.success'),
            notify: true,
          });
        }
      },
    },
  );

  const {
    mutate: publishJobOfferMutate,
    isLoading: isLoadingPublishJobStatus,
  } = useMutation(
    () => {
      if (!jobId) {
        throw new Error('Job ID is required');
      }
      return createJobPosting({ jobOfferId: jobId, jobBoardId });
    },
    {
      onSuccess: () => {
        queryClient.invalidateQueries(jobKeys.detail(jobId));
        queryClient.invalidateQueries(jobKeys.all());
        queryClient.invalidateQueries(jobKeys.publicDescription(jobId));
        handleSuccessRedirect({
          message: t('job_offers.new.publish.actions.success'),
          notify: true,
        });
      },
      onError: () => {
        enqueueSnackbar({
          variant: 'error',
          title: t('job_offers.new.publish.actions.error'),
        });
      },
    },
  );

  const isLoadingSave =
    isLoadingGeneralConfig ||
    isLoadingProcessStages ||
    isLoadingJobStatus ||
    isLoadingPublishJobStatus ||
    isLoadingPublicDescription ||
    isFetchingPublicDescription ||
    isLoadingApplicationForm ||
    isFetchingApplicationForm;

  const getSaveEnabled = useCallback(
    (force = false) => {
      if (activeStep === Steps.REVIEW) {
        if (!hasJobBoards || !publicDescription) {
          return force ?? false;
        }
        return (publishForm.formState.isValid || force) && !isLoadingSave;
      }
      if (activeStep === Steps.PUBLISH) {
        return publishForm.formState.isValid && !isLoadingSave;
      }
      if (activeStep === Steps.PROCESS_STAGES) {
        return processStagesForm.formState.isValid && !isLoadingSave;
      }
      return generalConfigForm.formState.isValid && !isLoadingSave;
    },
    [
      activeStep,
      generalConfigForm.formState.isValid,
      processStagesForm.formState.isValid,
      isLoadingSave,
      publishForm.formState.isValid,
      hasJobBoards,
      publicDescription,
    ],
  );

  const handleSuccessRedirect = ({ message = '', notify = false }) => {
    if (message || notify) {
      enqueueSnackbar({ variant: 'success', title: message });
    }
    navigate(recruitingRoutes.jobOffer(jobId));
  };

  useEffect(() => {
    if (
      prevActiveStepRef.current === Steps.PUBLISH &&
      activeStep !== Steps.PUBLISH
    ) {
      setHasVisitedPublish(true);
    }
    if (
      prevActiveStepRef.current === Steps.PROCESS_STAGES &&
      activeStep !== Steps.PROCESS_STAGES
    ) {
      setHasVisitedProcessStages(true);
    }
    prevActiveStepRef.current = activeStep;
  }, [activeStep]);

  const onSave = (cb?: (showAlert: boolean) => void) => {
    if (activeStep === Steps.GENERAL_CONFIG) {
      return onSaveGeneralConfig(cb);
    }
    if (activeStep === Steps.PROCESS_STAGES) {
      return onSaveProcessStages(cb);
    }
    if (activeStep === Steps.PUBLISH) {
      // Chain: save application form first, then public description
      const chainedCb = (showAlertApp: boolean) => {
        onSavePublicDescription((showAlertPub: boolean) => {
          cb?.(showAlertPub || showAlertApp);
        })();
      };
      return onSaveApplicationForm(chainedCb);
    }
    // REVIEW step — persist any pending app-form visibility changes before
    // publishing; otherwise they'd be silently dropped when the user jumps
    // straight here via the sidebar.
    return onSaveApplicationForm(cb);
  };

  const generalConfigCompletionStatus = (() => {
    const { submitCount, isDirty } = generalConfigForm.formState;
    const wasSaved = submitCount > 0 || !!jobId;
    if (!wasSaved) return null;
    if (isDirty) return StepCompletionStatus.MODIFIED;
    return StepCompletionStatus.DONE;
  })();

  const processStagesCompletionStatus = (() => {
    const { isDirty } = processStagesForm.formState;
    if (!hasVisitedProcessStages) return null;
    if (isDirty) return StepCompletionStatus.MODIFIED;
    return StepCompletionStatus.DONE;
  })();

  const isPublicDescriptionSaved = !!publicDescription;

  const publishCompletionStatus = (() => {
    if (!hasVisitedPublish && !isPublicDescriptionSaved) return null;
    if (isPublicDescriptionSaved) return StepCompletionStatus.DONE;
    return StepCompletionStatus.IN_PROGRESS;
  })();

  const steps = useMemo(
    () => [
      {
        id: 0,
        disabled: isLoadingSave,
        label: t('job_offers.new.sidebar.general_config'),
        completionStatus: generalConfigCompletionStatus,
      },
      {
        id: 1,
        disabled: !jobId || isLoadingSave,
        label: t('job_offers.new.sidebar.stages'),
        completionStatus: processStagesCompletionStatus,
      },
      {
        id: 2,
        disabled: !jobId || isLoadingSave,
        label: t('job_offers.new.sidebar.publish'),
        completionStatus: publishCompletionStatus,
      },
      {
        id: 3,
        disabled: !jobId || isLoadingSave,
        label: t('job_offers.new.sidebar.review'),
        completionStatus: null,
      },
    ],
    [
      t,
      isLoadingSave,
      jobId,
      generalConfigCompletionStatus,
      processStagesCompletionStatus,
      publishCompletionStatus,
    ],
  );

  const onNextStep = () => {
    onSave((showAlert: boolean) => {
      if (activeStep === Steps.REVIEW) {
        const shouldPublishAfterOpen = hasJobBoards && !!publicDescription;
        openJobMutate(shouldPublishAfterOpen);
      }
      if (showAlert && activeStep !== Steps.REVIEW) {
        enqueueSnackbar({
          variant: 'success',
          title: t('job_offers.alerts.saved_changes'),
        });
      }
      setActiveStep(prev => {
        if (prev === steps.length - 1) return prev;
        return prev + 1;
      });
    })();
  };

  const getNextLabel = () => {
    if (activeStep === Steps.GENERAL_CONFIG && !jobId) {
      return t('common.create_and_continue');
    }
    if (activeStep === Steps.REVIEW) {
      return hasJobBoards ? t('common.publish') : t('general:finish');
    }
    return t('general:next');
  };

  const getFooter: () => FooterProps = () => {
    return {
      ...(activeStep > Steps.GENERAL_CONFIG && {
        back: {
          label: t('general:back_alt'),
          onClick: () =>
            setActiveStep(prev => {
              if (prev === 0) return prev;
              return prev - 1;
            }),
          disabled: hasJobBoards
            ? !getSaveEnabled(true) && activeStep !== Steps.PUBLISH
            : false,
        },
      }),
      ...(activeStep === Steps.REVIEW && {
        draft: {
          label: t('common.open_without_publish'),
          onClick: () => {
            onSave(() => {
              openJobMutate(false);
            })();
          },
          disabled:
            isLoadingSave || !hasJobBoards
              ? !generalConfigForm.formState.isValid
              : !getSaveEnabled(true),
          isLoading: isLoadingSave,
        },
      }),
      ...(activeStep === Steps.PUBLISH && {
        draft: publicDescription
          ? undefined
          : {
              label: hasJobBoards ? t('common.skip_step') : t('general:next'),
              variant: !hasJobBoards ? 'primary' : 'secondary',
              onClick: () => {
                setActiveStep(prev => {
                  if (prev === 0) return prev;
                  return prev + 1;
                });
              },
              disabled: false,
            },
        ...(hasJobBoards &&
          !!publicDescription && {
            next: {
              label: t('common.skip_step'),
              variant: 'primary' as ButtonProps['variant'],
              onClick: () => {
                onNextStep();
              },
            },
          }),
      }),
      ...(((activeStep === Steps.PUBLISH && hasJobBoards) ||
        activeStep !== Steps.PUBLISH) && {
        next: {
          label: getNextLabel(),
          onClick: () => {
            onNextStep();
          },
          disabled: !getSaveEnabled(!!publicDescription),
          isLoading: isLoadingSave,
        },
      }),
    };
  };

  return {
    steps,
    generalConfigForm,
    processStagesForm,
    footer: getFooter(),
    activeStep,
    setActiveStep,
    isLoadingSave,
    onSave,
    jobId,
    hiringReasons,
    isLoadingBackendHiringPipeline,
    backendHiringPipeline,
    publishForm,
    hasJobBoards,
    jobBoardId,
    isJobPublicDescriptionSaved: !!publicDescription,
    jobName,
    jobApplicationForm,
    isFetchingApplicationForm,
    applicationFormChanges,
    onApplicationFormChange,
    isApplicationFormDirty,
  };
};
