import { useEffect } from 'react';
import { FormProvider, useForm, useWatch } from 'react-hook-form';
import { useLocation, useNavigate } from 'react-router-dom';

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

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

import { useAuth } from 'src/contexts/JWTContext';
import useGeneralError from 'src/hooks/useGeneralError';
import { type CommunityFeature } from 'src/types/communityFeatures';
import { type FeatureFlag } from 'src/types/featureFlags';
import { type Instance } from 'src/types/instance';
import { type User } from 'src/types/user';
import { useLokaliseTranslation } from 'src/utils/i18n';
import { checkPasswordType } from 'src/utils/validation';

import HuFormStrongPassword from 'src/components/FormInputs/HuFormStrongPassword';

type LocationState = {
  accessToken: string;
  refreshToken: string;
  user: User;
  instance: Instance;
  featureFlags: FeatureFlag | null;
  communityFeatures: CommunityFeature[] | null;
};

const FormUpdatePassword = () => {
  const { t } = useLokaliseTranslation('authentication');
  const { enqueueSnackbar } = useHuSnackbar();
  const showGeneralError = useGeneralError();
  const { updatePassword } = useAuth();
  const navigate = useNavigate();
  const { state } = useLocation();

  const stateLocation = state as LocationState;

  useEffect(() => {
    if (!stateLocation) {
      navigate('/', { replace: true });
    }
  }, [stateLocation, navigate]);

  const form = useForm({
    defaultValues: {
      passwordInput: '',
      repeatPasswordInput: '',
    },
  });

  const {
    handleSubmit,
    formState: { isSubmitting },
    control,
  } = form;

  const password = useWatch({ control, name: 'passwordInput' });

  const passwordValidation = checkPasswordType(
    stateLocation?.instance?.passwordType ?? { validateMinLength: true },
    t,
    password,
  );
  const allPasswordRulesValid =
    password.length > 0 && passwordValidation.every(rule => rule.isValid);

  const submit = async () => {
    try {
      const { user, accessToken, refreshToken } = stateLocation;

      await updatePassword?.(user, password, accessToken, refreshToken);

      enqueueSnackbar({
        title: t('SUCCESS_UPDATE_PASSWORD'),
        variant: 'success',
      });
    } catch (err) {
      showGeneralError(err, t('ERROR_UPDATE_PASSWORD'));
    }
  };

  return (
    <FormProvider {...form}>
      <form
        noValidate
        onSubmit={handleSubmit(submit)}
      >
        <Stack sx={{ alignItems: 'center', gap: 4 }}>
          <HuFormStrongPassword
            passwordType={stateLocation?.instance?.passwordType}
          />
          <Button
            type="submit"
            variant="primary"
            size="large"
            disabled={isSubmitting || !allPasswordRulesValid}
            sx={{ width: '100%' }}
          >
            {t('UPDATE.SUBMIT')}
          </Button>
        </Stack>
      </form>
    </FormProvider>
  );
};

export default FormUpdatePassword;
