import { Helmet } from 'react-helmet-async';
import { FormProvider, useForm, useWatch } from 'react-hook-form';
import { useMutation, useQuery } from 'react-query';
import { Navigate, useNavigate, useSearchParams } from 'react-router-dom';

import { changeLanguage } from 'i18next';
import Stack from '@material-hu/mui/Stack';

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

import useGeneralError from 'src/hooks/useGeneralError';
import useHuGoTheme from 'src/hooks/useHuGoTheme';
import useRules from 'src/hooks/useRules';
import { getInstanceForRegisterUser } from 'src/services/authService';
import { signUpWithInvite } from 'src/services/users';
import { type SignUpWithInviteData } from 'src/types/user';
import { formatTitle } from 'src/utils/helmetUtils';
import { useLokaliseTranslation } from 'src/utils/i18n';
import { getNavigatorLanguage } from 'src/utils/languages';
import { redirectToApp } from 'src/utils/registerUser';
import { checkPasswordType } from 'src/utils/validation';

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

import RegistrationLayout from './components/RegistrationLayout';
import { registrationKeys } from './queries';

const RegisterUser = () => {
  const navigate = useNavigate();
  const { t } = useLokaliseTranslation('authentication');
  const { enqueueSnackbar } = useHuSnackbar();
  const showGeneralError = useGeneralError();
  const [searchParams] = useSearchParams();
  const HugoThemeProvider = useHuGoTheme();

  const registerMutation = useMutation(signUpWithInvite, {
    onSuccess: () => {
      redirectToApp(navigate);
      enqueueSnackbar({
        title: t('SUCCESS_REGISTER_USER'),
        variant: 'success',
      });
    },
    onError: (err: any) => showGeneralError(err, t('ERROR_REGISTER_USER')),
  });

  const orgName = searchParams.get('orgName');
  const firstName = searchParams.get('firstName');
  const lastName = searchParams.get('lastName');
  const code = searchParams.get('code');

  const { data: instance } = useQuery(
    registrationKeys.instance(),
    () => getInstanceForRegisterUser(code!),
    {
      enabled: !!code,
      onSuccess: data => {
        changeLanguage(data.data.language);
      },
    },
  );

  const form = useForm<SignUpWithInviteData>({
    defaultValues: {
      inviteCode: code!,
      orgName: orgName!,
      firstName: firstName!,
      lastName: lastName!,
      language: getNavigatorLanguage(),
      passwordInput: '',
      repeatPasswordInput: '',
    },
  });

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

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

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

  const firstNameRules = useRules({
    requiredWithMessage: true,
  });

  const lastNameRules = useRules({
    requiredWithMessage: true,
  });

  const formInputs = [
    {
      name: 'firstName',
      id: 'firstNameInput',
      label: `${t('FIRST_NAME')}*`,
      autoFocus: true,
      autoComplete: 'firstName',
      rules: firstNameRules,
    },
    {
      name: 'lastName',
      id: 'lastNameInput',
      label: `${t('USER_LAST_NAME')}*`,
      autoFocus: false,
      autoComplete: 'lastName',
      rules: lastNameRules,
    },
  ];

  const submit = (values: SignUpWithInviteData) => {
    registerMutation.mutate(values);
  };

  if (!code || !orgName) {
    return <Navigate to="/" />;
  }

  const isLoading = isSubmitting || registerMutation.isLoading;

  return (
    <>
      <Helmet>
        <title>{formatTitle(t('REGISTER_USER'))}</title>
      </Helmet>
      <HugoThemeProvider>
        <RegistrationLayout
          title={t('SIGN_UP_DESCRIPTION')}
          sx={{ pt: 2 }}
        >
          <FormProvider {...form}>
            <form
              noValidate
              onSubmit={handleSubmit(submit)}
            >
              <Stack sx={{ gap: 4 }}>
                {formInputs.map(input => (
                  <HuFormInputClassic
                    key={input.id}
                    name={input.name}
                    inputProps={{
                      id: input.id,
                      label: input.label,
                      autoFocus: input.autoFocus,
                      disabled: isSubmitting,
                      hasCounter: false,
                      autoComplete: input.autoComplete,
                    }}
                    rules={input.rules}
                  />
                ))}
                <HuFormStrongPassword
                  passwordType={instance?.data?.passwordType!}
                />
                <Button
                  type="submit"
                  variant="primary"
                  size="large"
                  loading={isLoading}
                  disabled={
                    isLoading ||
                    Object.keys(errors).length > 0 ||
                    !allPasswordRulesValid
                  }
                  sx={{ width: '100%' }}
                >
                  {t('SING_UP')}
                </Button>
              </Stack>
            </form>
          </FormProvider>
        </RegistrationLayout>
      </HugoThemeProvider>
    </>
  );
};

export default RegisterUser;
