import { type MutableRefObject } from 'react';
import { useFormContext, useWatch } from 'react-hook-form';
import { useMatch } from 'react-router';

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

import useUnsavedWarning from 'src/hooks/useUnsavedWarning';
import { LogEvents, logEvent, NewExitAction } from 'src/utils/logging';

import { LearningUnsavedDialog } from '../../../common/components/LearningUnsavedDialog';
import useCreateSession from '../../hooks/useCreateSession';
import { useNewSessionStepper } from '../../hooks/useNewSessionStepper';
import { sessionsRoutes } from '../../routes';
import { type NewSessionFormValues } from '../../types';

import SessionNewFooter from './SessionNewFooter';
import SessionNewHeader from './SessionNewHeader';
import SessionNewMain from './SessionNewMain';

type SessionFormProps = {
  sessionRef: MutableRefObject<NewSessionFormValues | undefined>;
  loadingSession: boolean;
};

const SessionForm = ({ sessionRef, loadingSession }: SessionFormProps) => {
  const { control, formState } = useFormContext<NewSessionFormValues>();
  const { currentStep } = useNewSessionStepper();
  const isNew = !!useMatch(sessionsRoutes.new());

  const sessionId =
    useWatch({ control, name: 'basic_information.id' }) ?? undefined;

  const { handleNextStep, isLoading, publishSessionDialog, handleSaveOnClose } =
    useCreateSession(sessionId, sessionRef);

  const { modal: unsavedWarningModal } = useUnsavedWarning(
    props => (
      <LearningUnsavedDialog
        {...props}
        loading={isLoading}
        onSave={handleSaveOnClose}
        onExit={() => {
          logEvent(LogEvents.NEW_SESSION_EXIT, {
            sessionId,
            sessionStep: currentStep.id,
            sessionFunnel: isNew
              ? NewExitAction.creation
              : NewExitAction.edition,
          });
        }}
      />
    ),
    !formState.isDirty || formState.isSubmitted,
  );

  return (
    <Stack
      sx={{ height: '100vh' }}
      component="form"
    >
      {unsavedWarningModal}
      {publishSessionDialog}
      <SessionNewHeader />
      <SessionNewMain loadingSession={loadingSession} />
      <SessionNewFooter
        loading={isLoading}
        onNextStep={handleNextStep}
      />
    </Stack>
  );
};

export default SessionForm;
