import { useState } from 'react';
import { Helmet } from 'react-helmet-async';
import { FormProvider, useForm, useWatch } from 'react-hook-form';
import { useMutation, useQuery } from 'react-query';
import { useLocation, useNavigate, useParams } from 'react-router';

import Container from '@material-hu/mui/Container';
import Stack from '@material-hu/mui/Stack';
import { colorPalette } from '@material-hu/theme/hugo/colors';

import HuTaskFocusHeader from '@material-hu/components/design-system/Header/TaskFocus';
import useHuSnackbar from '@material-hu/components/design-system/Snackbar';
import HuStepper from '@material-hu/components/design-system/Stepper';
import { type StepConfig } from '@material-hu/components/design-system/Stepper/types';

import useHuGoTheme from 'src/hooks/useHuGoTheme';
import useUnsavedWarning from 'src/hooks/useUnsavedWarning';
import useGoalCyclesConfiguration from 'src/pages/dashboard/Goals/hooks/useGoalCyclesConfiguration';
import useGoalFormulasAvailable from 'src/pages/dashboard/Goals/hooks/useGoalFormulasAvailable';
import * as goalsService from 'src/services/goalsService';
import { type GoalCycle, GoalCycleStatuses } from 'src/types/goals';
import { formatTitle } from 'src/utils/helmetUtils';
import { useLokaliseTranslation } from 'src/utils/i18n';
import { LogEvents, logEvent } from 'src/utils/logging';
import {
  distanceInDays,
  simpleDateStringToLocalDate,
} from 'src/utils/timeUtils';

import CenteredCircularProgress from 'src/components/CircularProgress';

import { goalsKeys } from '../../../queries';
import { goalRoutes } from '../../../routes';
import { isLockedCycle } from '../../../utils';
import {
  CYCLE_EDIT_STEPS,
  DEFAULT_PROGRESS_CONTROL_CONFIG,
} from '../../constants';
import FeaturesStep from '../CycleSteps/FeaturesStep';
import SettingsStep from '../CycleSteps/SettingsStep';
import ValidationStep from '../CycleSteps/ValidationStep';

import CycleEditFooter from './components/CycleEditFooter';

const defaultValues = (cycle: GoalCycle) => ({
  name: cycle.name,
  startDate: simpleDateStringToLocalDate(cycle.startDate),
  endDate: simpleDateStringToLocalDate(cycle.endDate),
  status: cycle.status,
  hasFormulas: cycle.hasFormulas || false,
  enforceGoalCountBounds: cycle.enforceGoalCountBounds || false,
  minGoalsPerOwner: cycle.minGoalsPerOwner || 0,
  maxGoalsPerOwner: cycle.maxGoalsPerOwner || 10,
  progressControlConfig:
    cycle.progressControlConfig || DEFAULT_PROGRESS_CONTROL_CONFIG,
});

const CycleEdit = () => {
  const { t } = useLokaliseTranslation(['goals', 'performance']);
  const navigate = useNavigate();
  const { id } = useParams();
  const cycleId = parseInt(id || '0');
  const HuGoThemeProvider = useHuGoTheme();

  const { enqueueSnackbar } = useHuSnackbar();

  const { state } = useLocation() as { state: { backLink: string } };
  const handleGoBack = () =>
    navigate(state?.backLink || goalRoutes.cyclesBase());

  const form = useForm<GoalCycle>({
    defaultValues: {
      name: t('performance:new_cycle'),
      startDate: new Date(),
      endDate: new Date(),
      status: GoalCycleStatuses.DRAFT,
      hasFormulas: false,
      enforceGoalCountBounds: false,
      minGoalsPerOwner: 1,
      maxGoalsPerOwner: 10,
      progressControlConfig: DEFAULT_PROGRESS_CONTROL_CONFIG,
    },
    mode: 'onChange',
  });

  const { mathFormulasEnabled } = useGoalCyclesConfiguration();
  const { formulasCount } = useGoalFormulasAvailable(mathFormulasEnabled);

  const name = useWatch({ control: form.control, name: 'name' });
  const status = useWatch({ control: form.control, name: 'status' });
  const hasFormulas = useWatch({ control: form.control, name: 'hasFormulas' });
  const isLockedCycleStatus = isLockedCycle(status);

  const isFormulasBlocked =
    hasFormulas && mathFormulasEnabled && formulasCount === 0;
  const {
    formState: { isDirty, isValid },
  } = form;

  const steps: StepConfig[] = [
    {
      id: CYCLE_EDIT_STEPS.SETTINGS.toString(),
      title: t('general:settings'),
    },
    {
      id: CYCLE_EDIT_STEPS.FEATURES.toString(),
      title: t('cycle_steps.features.title'),
    },
    {
      id: CYCLE_EDIT_STEPS.VALIDATION.toString(),
      title: t('general:validation'),
    },
  ];

  const [activeStep, setActiveStep] = useState(0);
  const isValidationStep = activeStep === steps.length - 1;

  const nextStep = () => setActiveStep(prev => prev + 1);
  const previousStep = () => setActiveStep(prev => prev - 1);

  const { isLoading: cycleLoading } = useQuery(
    goalsKeys.cycle(cycleId, false),
    () => goalsService.getGoalCycle(cycleId),
    {
      select: r => r.data,
      enabled: !!cycleId,
      onSuccess: data => {
        form.reset({
          ...defaultValues(data),
        });
      },
    },
  );

  const startCycleMutation = useMutation(
    () => goalsService.startCycle(cycleId),
    {
      onSuccess: r => {
        logEvent(LogEvents.GOAL_CYCLE_CREATED, {
          cycleId,
          length: distanceInDays(r.data.endDate, r.data.startDate),
        });
        enqueueSnackbar({
          title: t('performance:cycles.created'),
          variant: 'success',
        });
        navigate(goalRoutes.cycle(cycleId));
      },
    },
  );

  const updateCycleMutation = useMutation(
    (updatedCycle: any) => goalsService.updateCycle(cycleId, updatedCycle),
    {
      onSuccess: () => {
        if (isValidationStep) {
          const shouldStartCycle = status === GoalCycleStatuses.DRAFT;

          if (shouldStartCycle) {
            startCycleMutation.mutate();
          } else {
            enqueueSnackbar({
              title: t('cycle_edit_success'),
              variant: 'success',
            });
            navigate(goalRoutes.cycle(cycleId));
          }
          return;
        }
        nextStep();
      },
    },
  );

  const handleContinue = () => {
    const formValues = form.getValues();
    const isDraft = formValues.status === GoalCycleStatuses.DRAFT;
    const isLockedCycleOnSubmit = isLockedCycle(formValues.status);

    const basePayload = {
      name: formValues.name,
      startDate: formValues.startDate,
      endDate: formValues.endDate,
      isForIndividuals: true,
      status:
        isValidationStep && isDraft
          ? GoalCycleStatuses.PENDING
          : formValues.status,
    };
    const updatedCycle = isLockedCycleOnSubmit
      ? basePayload
      : {
          ...basePayload,
          hasFormulas: isFormulasBlocked ? false : formValues.hasFormulas,
          enforceGoalCountBounds: formValues.enforceGoalCountBounds,
          minGoalsPerOwner: formValues.minGoalsPerOwner,
          maxGoalsPerOwner: formValues.maxGoalsPerOwner,
          progressControlConfig: formValues.progressControlConfig,
        };

    updateCycleMutation.mutate(updatedCycle);
  };

  const { modal } = useUnsavedWarning(
    undefined,
    !isDirty || startCycleMutation.isLoading || updateCycleMutation.isLoading,
  );

  if (cycleLoading) return <CenteredCircularProgress centered />;

  return (
    <HuGoThemeProvider>
      <Stack
        sx={{
          height: `100vh`,
          backgroundColor: colorPalette.hugoBackground.neutralBg,
        }}
      >
        {modal}
        <Stack
          sx={{
            flex: 1,
            backgroundColor: colorPalette.hugoBackground.neutralBg,
          }}
        >
          <Helmet>
            <title>
              {formatTitle(t('performance:cycles.new_cycle_short'))}
            </title>
          </Helmet>
          <Stack sx={{ position: 'sticky', top: 0, zIndex: 10 }}>
            <HuTaskFocusHeader
              title={name}
              onClose={() => navigate(goalRoutes.cyclesBase())}
              onBack={handleGoBack}
            />
          </Stack>

          <Container
            maxWidth="md"
            sx={{
              flex: 1,
              overflow: 'auto',
            }}
          >
            <FormProvider {...form}>
              <Stack
                direction="row"
                gap={4}
                sx={{
                  p: 3,
                }}
              >
                <Stack
                  sx={{ flex: 1, justifyContent: 'space-between', gap: 3 }}
                >
                  <HuStepper
                    steps={steps}
                    currentStep={activeStep}
                  />
                  {activeStep === CYCLE_EDIT_STEPS.SETTINGS && <SettingsStep />}
                  {activeStep === CYCLE_EDIT_STEPS.FEATURES && (
                    <FeaturesStep isActiveCycle={isLockedCycleStatus} />
                  )}
                  {activeStep === CYCLE_EDIT_STEPS.VALIDATION && (
                    <ValidationStep />
                  )}
                </Stack>
              </Stack>
            </FormProvider>
          </Container>
        </Stack>
        <CycleEditFooter
          isDirty={isDirty}
          isValidationStep={isValidationStep}
          isValid={isValid}
          showGoBackButton={activeStep > 0}
          onGoBack={previousStep}
          onSave={handleContinue}
        />
      </Stack>
    </HuGoThemeProvider>
  );
};

export default CycleEdit;
