import { FormProvider, useForm } from 'react-hook-form';
import { useMutation } from 'react-query';
import { useOutletContext, useParams } from 'react-router';

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

import Button from '@material-hu/components/design-system/Buttons/Button';
import useSnackbar from '@material-hu/components/design-system/Snackbar';

import { queryClient } from 'src/config/react-query';
import useGeneralError from 'src/hooks/useGeneralError';
import useHugoUnsavedWarning from 'src/hooks/useUnsavedWarning/altHugo';
import * as regionService from 'src/services/regionsService';
import { RegionParam } from 'src/types/regions';
import { getDirtyValues } from 'src/utils/formUtils';
import { useLokaliseTranslation } from 'src/utils/i18n';

import DetailsStep from '../components/DetailsStep';
import { RegionOutletContext } from '../constants';
import { regionKeys } from '../queries';

function RegionGeneral() {
  const { t } = useLokaliseTranslation('regions');
  const { regionData } = useOutletContext<RegionOutletContext>();
  const { enqueueSnackbar } = useSnackbar();
  const showGeneralError = useGeneralError();

  const form = useForm({
    defaultValues: {
      title: regionData.title || '',
      body: regionData.body || '',
    },
    mode: 'onChange',
  });

  const {
    formState: { isValid, isDirty, dirtyFields },
  } = form;
  const regionId = parseInt(useParams().id || '0');

  const editRegionMutation = useMutation(
    (formValues: Pick<RegionParam, 'title' | 'body'>) =>
      regionService.updateRegion(regionData.id, { ...formValues }),
    {
      onSuccess: response => {
        const { title: responseTitle, body: responseBody } = response.data;
        enqueueSnackbar({
          title: t('edit_success'),
          variant: 'success',
        });
        queryClient.setQueryData(regionKeys.region(regionId), response);
        form.reset({ title: responseTitle, body: responseBody ?? '' });
      },
      onError: err => {
        showGeneralError(err, t('edit_error'));
      },
    },
  );

  const handleSubmit = () => {
    const updatedValues = form.getValues();
    const valuesToSubmit: Partial<Pick<RegionParam, 'title' | 'body'>> = {
      ...updatedValues,
    };
    if (valuesToSubmit.body?.length === 0) {
      delete valuesToSubmit.body;
    }
    editRegionMutation.mutate(
      getDirtyValues(
        dirtyFields,
        valuesToSubmit as Pick<RegionParam, 'title' | 'body'>,
      ),
    );
  };

  const { modal: UnsavedChangesModal, blocker } = useHugoUnsavedWarning({
    modalProps: {
      title: t('regions:wish_save_changes_title'),
      body: t('regions:wish_save_changes_body'),
      primaryButtonProps: {
        children: t('general:save'),
        onClick: () => {
          blocker?.reset?.();
          UnsavedChangesModal?.closeModal();
          handleSubmit();
        },
      },
      secondaryButtonProps: {
        children: t('regions:quit_without_saving'),
        onClick: () => {
          UnsavedChangesModal?.closeModal();
          blocker?.proceed?.();
        },
      },
    },
    shouldBlock: isDirty,
  });

  return (
    <>
      {UnsavedChangesModal.modal}
      <FormProvider {...form}>
        <Stack
          sx={{
            flex: 1,
            justifyContent: 'space-between',
          }}
        >
          <DetailsStep isRegion />
        </Stack>
        <Stack
          sx={{
            position: 'fixed',
            bottom: 0,
            left: 0,
            right: 0,
            flexDirection: 'row',
            justifyContent: 'end',
            backgroundColor: theme => theme.palette.background.paper,
            boxShadow: theme => theme.shadows[2],
            py: 2,
            px: '18%',
            width: '100%',
            zIndex: 1000,
          }}
        >
          <Button
            variant="primary"
            size="large"
            disabled={!isDirty || !isValid || editRegionMutation.isLoading}
            onClick={handleSubmit}
          >
            {t('general:save')}
          </Button>
        </Stack>
      </FormProvider>
    </>
  );
}

export default RegionGeneral;
