import React, { useEffect, useState } from 'react';
import { LoginComponentProps } from './types';
import { getTranslations } from '../../shared/utils/localization-util';
import { newPassword } from './login-services';
import { jwtDecode } from 'jwt-decode';

interface TouchedFields {
  password?: boolean;
  repeatPassword?: boolean;
}

interface FormFields {
  password: string;
  repeatPassword: string;
}

const ResetPasswordComponent: React.FC<LoginComponentProps> = ({ tideClientConfig, languageCode, handleBackToLogin }) => {
  const [passwordSet, setPasswordSet] = useState<boolean>(false);
  const [touched, setTouched] = useState<TouchedFields>({
    password: false,
    repeatPassword: false
  });
  const [formValues, setFormValues] = useState<FormFields>({
    password: '',
    repeatPassword: ''
  });
  const [submitted, setSubmitted] = useState<boolean>(false);
  const [errors, setErrors] = useState({} as any);
  const [token, setToken] = useState<string | null>(null);
  const [invalidToken, setInvalidToken] = useState<boolean>(false);

  const translations = getTranslations(languageCode ?? 'en-GB');

  useEffect(() => {
    if (typeof window !== 'undefined') {
      const rawToken = new URLSearchParams(window.location.search).get('token');
      setToken(rawToken);

      if (rawToken) {
        try {
          const decoded = jwtDecode(rawToken);

          if (!decoded.exp || decoded.exp * 1000 < Date.now()) {
            setInvalidToken(true);
          }
        } catch (e) {
          setInvalidToken(true);
        }
      } else {
        setInvalidToken(true);
      }
    }
  }, []);

  const handleBlur = (event: React.ChangeEvent<HTMLInputElement>) => {
    setTouched((prev) => ({
      ...prev,
      [event.target.name]: true
    }));
    validate();
  };

  const onChange = (event: React.ChangeEvent<HTMLInputElement>) => {
    setFormValues({ ...formValues, [event.target.name]: event.target.value });

    validate();
  };

  const validate = () => {
    const validationErrors: any = {};
    const { password, repeatPassword } = formValues;

    // Validate password
    if (!password) {
      validationErrors.password = 'required';
    } else if (touched.password || submitted) {
      const hasNumber = /\d/.test(password);
      const hasCapital = /[A-Z]/.test(password);

      if (!hasNumber || !hasCapital) {
        validationErrors.passwordComplexity = 'invalid';
      }
    }

    // Validate repeat password
    if (!repeatPassword) {
      validationErrors.repeatPassword = 'required';
    } else if ((touched.repeatPassword || submitted) && password && repeatPassword !== password) {
      validationErrors.matchPassword = 'mismatch';
    }

    setErrors(validationErrors);
    return Object.keys(validationErrors).length === 0;
  };

  const handleResetPassword = async (e: React.MouseEvent<HTMLButtonElement>) => {
    e.preventDefault();
    setSubmitted(true);
    setTouched({ password: true, repeatPassword: true });

    const isValid = validate();

    if (!isValid) return;

    if (token) {
      try {
        const response = await newPassword(token, formValues.password, tideClientConfig);
        if (response) {
          setPasswordSet(true);
        }
      } catch {
        setErrors((prevErrors: any) => ({
          ...prevErrors,
          api: true
        }));
        setInvalidToken(true);
      }
    }
  };

  useEffect(() => {
    validate();
  }, [formValues, token]);

  return (
    <>
      {!passwordSet && !invalidToken && (
        <>
          <h4 className="login__card__title">{translations.LOGIN.RESET_PASSWORD_TITLE}</h4>

          <form className="login__form" onSubmit={(e) => e.preventDefault()} noValidate>
            <div className="login__form__group">
              <label htmlFor="password">{translations.LOGIN.RESET_PASSWORD_LABEL}</label>
              <input type="password" id="password" name="password" value={formValues.password} onChange={onChange} onBlur={handleBlur} required />
              {(touched.password || submitted) && (errors.password || errors.passwordComplexity) && (
                <div id="username-error" className="login__error">
                  {errors.password === 'required' && translations.LOGIN.PASSWORD_REQUIRED}
                  {errors.passwordComplexity === 'invalid' && translations.LOGIN.PASSWORD_COMPLEXITY}
                </div>
              )}
            </div>
            <div className="login__form__group">
              <label htmlFor="repeatPassword">{translations.LOGIN.RESET_REPEAT_PASSWORD_LABEL}</label>
              <input
                type="password"
                id="repeatPassword"
                name="repeatPassword"
                value={formValues.repeatPassword}
                onChange={onChange}
                onBlur={handleBlur}
                required
              />
              {(touched.repeatPassword || submitted) && (errors.repeatPassword || errors.matchPassword) && (
                <div id="username-error" className="login__error">
                  {errors.repeatPassword === 'required' && translations.LOGIN.REPEAT_PASSWORD_REQUIRED}
                  {errors.matchPassword === 'mismatch' && translations.LOGIN.PASSWORDS_DO_NOT_MATCH}
                </div>
              )}
            </div>

            <button type="button" className="cta cta--primary" onClick={handleResetPassword}>
              {translations.LOGIN.RESET_PASSWORD_SUBMIT_LABEL}
            </button>
          </form>
        </>
      )}

      {passwordSet && (
        <div className="login__welcome">
          <h3 className="login__card__title">{translations.LOGIN.RESET_PASSWORD_TITLE}</h3>
          <p>{translations.LOGIN.RESET_PASSWORD_SUCCESSFUL_MESSAGE}</p>
          <button className="cta cta--primary" onClick={handleBackToLogin}>
            {translations.LOGIN.BACK_TO_LOGIN}
          </button>
        </div>
      )}

      {invalidToken && (
        <div className="login__welcome">
          <h3 className="login__card__title">{translations.LOGIN.RESET_PASSWORD_INVALID_TOKEN_TITLE}</h3>
          <p>{translations.LOGIN.RESET_PASSWORD_INVALID_TOKEN_DESCRIPTION}</p>
          <button className="cta cta--primary" onClick={handleBackToLogin}>
            {translations.LOGIN.BACK_TO_LOGIN}
          </button>
        </div>
      )}
    </>
  );
};

export default ResetPasswordComponent;
