import React, { useState } from 'react';
import { LoginComponentProps } from './types';
import { getTranslations } from '../../shared/utils/localization-util';
import { useFormik } from 'formik';
import * as Yup from 'yup';
import { decodeTokenToMemberInfo, loginMember, passwordForgotten } from './login-services';

const LoginComponent: React.FC<LoginComponentProps> = ({ tideClientConfig, portalId, languageCode, member, setMember, handleBackToHome }) => {
  const [isLoggedIn, setIsLoggedIn] = useState<boolean>(false);
  const [showPassword, setShowPassword] = useState(false);
  const [isForgotPassword, setIsForgotPassword] = useState<boolean>(false);
  const [newPasswordRequested, setNewPasswordRequested] = useState<boolean>(false);

  const [apiError, setApiError] = useState(false);

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

  const formik = useFormik({
    initialValues: {
      username: '',
      password: ''
    },
    validationSchema: Yup.object({
      username: Yup.string().email(translations.LOGIN.EMAIL_INVALID).required(translations.LOGIN.EMAIL_REQUIRED),
      password: Yup.string().required(translations.LOGIN.PASSWORD_REQUIRED)
    }),
    onSubmit: async (values) => {
      try {
        const response = await loginMember(values.username, values.password, tideClientConfig, portalId);
        const member = decodeTokenToMemberInfo(response.token);
        if (member && member.id !== 0) {
          setMember(member);
          localStorage.setItem('token', response.token);
          setIsLoggedIn(true);
        }
      } catch (error) {
        setApiError(true);
      }
    }
  });

  const handleForgotPasswordClick = async (e: React.MouseEvent<HTMLButtonElement>) => {
    e.preventDefault();
    formik.setTouched({ username: true }, true);
    const errors = await formik.validateForm();

    if (!errors.username) {
      handleForgotPassword();
    }
  };

  const handleForgotPassword = async () => {
    try {
      const response = await passwordForgotten(formik.values.username, tideClientConfig, portalId);
      if (response) {
        setNewPasswordRequested(true);
      }
    } catch (error) {
      setApiError(true);
    }
  };

  return (
    <>
      {!isLoggedIn && !isForgotPassword && (
        <>
          <h4 className="login__card__title">{translations.LOGIN.LOGIN_INTO}</h4>

          <form className="login__form" onSubmit={formik.handleSubmit} noValidate>
            <div className="login__form__group">
              <label htmlFor="email">{translations.LOGIN.EMAIL}</label>
              <input type="text" id="username" placeholder={translations.LOGIN.ENTER_YOUR_EMAIL} {...formik.getFieldProps('username')} />
              {formik.touched.username && formik.errors.username && (
                <div id="username-error" className="login__error">
                  {formik.errors.username}
                </div>
              )}
            </div>

            <div className="login__form__group">
              <label htmlFor="password">{translations.LOGIN.PASSWORD}</label>
              <input
                type={showPassword ? 'text' : 'password'}
                id="password"
                placeholder={translations.LOGIN.ENTER_YOUR_PASSWORD}
                {...formik.getFieldProps('password')}
                required
              />
              {(formik.touched.password || formik.submitCount > 0) && formik.errors.password && (
                <div id="password-error" className="login__error">
                  {formik.values.password === '' ? translations.LOGIN.PASSWORD_REQUIRED : formik.errors.password}
                </div>
              )}
            </div>

            {!formik.errors.password && apiError && <div className="login__error">{translations.LOGIN.INVALID_CREDENTIALS}</div>}

            <button type="submit" className="cta cta--primary">
              {translations.LOGIN.LOGIN}
            </button>

            <button
              type="button"
              className="login__forgot"
              onClick={() => {
                formik.setFieldValue('password', '');
                formik.setFieldTouched('password', false, false);
                formik.setFieldError('password', undefined);

                setApiError(false);

                setIsForgotPassword(true);
              }}>
              {translations.LOGIN.FORGOT_PASSWORD}
            </button>
          </form>
        </>
      )}

      {isLoggedIn && member && !isForgotPassword && (
        <div className="login__welcome">
          <h3 className="login__card__title">
            {translations.LOGIN.WELCOME_X}
            {member?.name}
          </h3>
          <button className="cta cta--primary" onClick={handleBackToHome}>
            {translations.LOGIN.BACK_TO_HOMEPAGE}
          </button>
        </div>
      )}

      {isForgotPassword && !newPasswordRequested && (
        <>
          <h4 className="login__card__title">{translations.LOGIN.FORGOT_PASSWORD}</h4>

          <form className="login__form" noValidate>
            <div className="login__form__group">
              <label htmlFor="email">{translations.LOGIN.EMAIL}</label>
              <input type="text" id="username" placeholder={translations.LOGIN.ENTER_YOUR_EMAIL} {...formik.getFieldProps('username')} required />
              {(((formik.submitCount > 0 || formik.touched.username) && formik.errors.username) || apiError) && (
                <div id="username-error" className="login__error">
                  {translations.LOGIN.EMAIL_REQUIRED}
                </div>
              )}
            </div>

            <button className="cta cta--primary" onClick={handleForgotPasswordClick}>
              {translations.LOGIN.FORGOT_PASSWORD_EMAIL_SUBMIT_LABEL}
            </button>
          </form>
        </>
      )}

      {newPasswordRequested && <h4 className="login__card__title">{translations.LOGIN.RESET_REQUESTED}</h4>}
    </>
  );
};

export default LoginComponent;
