import { useId, useMemo, useState } from 'react';
import { FormProvider, useForm } from 'react-hook-form';
import { useMutation, useQueryClient } from 'react-query';
import { useNavigate } from 'react-router-dom';

import { cardContentClasses } from '@material-hu/mui/CardContent';
import Collapse from '@material-hu/mui/Collapse';
import Stack from '@material-hu/mui/Stack';
import Typography from '@material-hu/mui/Typography';

import HuCardContainer from '@material-hu/components/design-system/CardContainer';
import HuFormInputClassic from '@material-hu/components/design-system/Inputs/Classic/form';
import useHuSnackbar from '@material-hu/components/design-system/Snackbar';
import HuFormSwitcher from '@material-hu/components/design-system/Switcher/form';

import {
  createSurvey as createSurveyService,
  updateSurvey as updateSurveyService,
} from 'src/pages/dashboard/PeopleExperience/services';
import { type SurveyType } from 'src/types/peopleExperience';
import { useLokaliseTranslation } from 'src/utils/i18n';

import { MIN_ANONYMITY_THRESHOLD } from '../../constants';
import { pxKeys } from '../../queries';
import { pxRoutes } from '../../routes';
import AnonymityThresholdForm from '../../components/AnonymityThresholdForm';
import { MAX_CONTENT_WIDTH } from '../constants';
import { type GeneralStepFormValues, type GeneralStepProps } from '../types';
import { surveyFormResolver } from '../utils';

import StepLayout from './StepLayout';

const getRequestPayload = (data: GeneralStepFormValues, type?: SurveyType) => ({
  name: data.name,
  description: data.description,
  commentsAnonymityThreshold: Number(data.commentsAnonymityThreshold),
  anonymityThreshold: Number(data.resultsAnonymityThreshold),
  isAnonymized: data.isAnonymous,
  ...(type ? { type } : {}),
});

enum CreateSource {
  Draft = 'draft',
  Submit = 'submit',
}

const GeneralStep = ({
  onNext,
  initialValues,
  surveyId,
  surveyType,
}: GeneralStepProps) => {
  const { t } = useLokaliseTranslation('people_experience');
  const { enqueueSnackbar } = useHuSnackbar();
  const navigate = useNavigate();
  const [loadingSource, setLoadingSource] = useState<CreateSource | null>(null);
  const queryClient = useQueryClient();
  const formId = useId();

  const isEditing = !!initialValues;

  const { mutate: createSurvey } = useMutation({
    mutationFn: (data: GeneralStepFormValues & { source: CreateSource }) =>
      createSurveyService(getRequestPayload(data, surveyType)),
    onMutate: ({ source }) => {
      setLoadingSource(source);
    },
    onError: () => {
      enqueueSnackbar({
        title: t('survey.create_error'),
        variant: 'error',
      });
    },
    onSettled: () => {
      setLoadingSource(null);
    },
  });

  const { mutate: updateSurvey, isLoading: isUpdatingSurvey } = useMutation({
    mutationFn: (data: GeneralStepFormValues) =>
      updateSurveyService({
        surveyId: surveyId!,
        payload: getRequestPayload(data),
      }),
    onSuccess: () => {
      queryClient.invalidateQueries(pxKeys.surveyDetail(surveyId!));
      onNext();
    },
    onError: () => {
      enqueueSnackbar({
        title: t('survey.update_error'),
        variant: 'error',
      });
    },
  });

  const resolver = useMemo(() => surveyFormResolver(t), [t]);

  const form = useForm<GeneralStepFormValues>({
    defaultValues: initialValues ?? {
      name: '',
      description: '',
      isAnonymous: false,
      commentsAnonymityThreshold: MIN_ANONYMITY_THRESHOLD,
      resultsAnonymityThreshold: MIN_ANONYMITY_THRESHOLD,
    },
    resolver,
  });

  const {
    formState: { isValid, isSubmitted, isDirty },
  } = form;

  const handleSubmit = (data: GeneralStepFormValues) => {
    if (!isDirty) {
      onNext();
      return;
    }

    if (isEditing) {
      updateSurvey(data);
      return;
    }

    createSurvey(
      { ...data, source: CreateSource.Submit },
      {
        onSuccess: response => {
          navigate(pxRoutes.surveyEdit(response.data.id), {
            replace: true,
            state: { initialStep: 1 },
          });
        },
      },
    );
  };

  const handleSaveAsDraft = (data: GeneralStepFormValues) => {
    createSurvey(
      { ...data, source: CreateSource.Draft },
      {
        onSuccess: () => {
          navigate(pxRoutes.surveysBase());
          enqueueSnackbar({
            title: t('survey.create_success'),
            variant: 'success',
          });
        },
      },
    );
  };

  const isFormValid = isSubmitted ? isValid : true;

  return (
    <FormProvider {...form}>
      <StepLayout
        onNext={form.handleSubmit(handleSubmit)}
        onBack={isEditing ? undefined : form.handleSubmit(handleSaveAsDraft)}
        slotProps={{
          submitButton: {
            loading: loadingSource === CreateSource.Submit || isUpdatingSurvey,
            disabled: !isFormValid || loadingSource === CreateSource.Draft,
            type: 'submit',
            form: formId,
          },
          backButton: {
            loading: loadingSource === CreateSource.Draft,
            label: t('save_draft'),
            disabled: !isFormValid || loadingSource === CreateSource.Submit,
          },
        }}
      >
        <Stack sx={{ overflowY: 'auto', width: '100%', flex: 1, minHeight: 0 }}>
          <Stack
            sx={{
              width: '100%',
              maxWidth: MAX_CONTENT_WIDTH,
              mx: 'auto',
              alignItems: 'center',
              gap: 3,
              p: 4,
            }}
          >
            <HuCardContainer
              padding={24}
              sx={{
                flexShrink: 0,
              }}
              fullWidth
            >
              <HuFormInputClassic
                name="name"
                inputProps={{
                  placeholder: t('write_something'),
                  label: t('general:name'),
                }}
              />
              <HuFormInputClassic
                name="description"
                inputProps={{
                  placeholder: t('write_something'),
                  multiline: true,
                  label: t('optional_description'),
                  sx: {
                    mt: 3,
                  },
                }}
              />
            </HuCardContainer>
            <Collapse
              in={form.watch('isAnonymous')}
              collapsedSize={142}
              sx={{ width: '100%' }}
            >
              <HuCardContainer
                padding={24}
                sx={{
                  [`& .${cardContentClasses.root}`]: {
                    display: 'flex',
                    flexDirection: 'column',
                    gap: 3,
                  },
                }}
                fullWidth
              >
                <Typography
                  variant="globalM"
                  fontWeight="fontWeightSemiBold"
                >
                  {t('anonymity.title')}
                </Typography>
                <HuFormSwitcher
                  name="isAnonymous"
                  switcherProps={{
                    description: t('anonymous_survey_description'),
                    title: t('anonymous_survey'),
                  }}
                />
                {form.watch('isAnonymous') && (
                  <AnonymityThresholdForm
                    resultsName="resultsAnonymityThreshold"
                    commentName="commentsAnonymityThreshold"
                  />
                )}
              </HuCardContainer>
            </Collapse>
          </Stack>
        </Stack>
      </StepLayout>
    </FormProvider>
  );
};

export default GeneralStep;
