import React, { Component, useEffect } from "react";
import styled, { css } from "styled-components";
import { withTranslation } from "react-i18next";
import PropTypes from "prop-types";
import { withRouter } from "react-router";
import Box from "@appserver/components/box";
import Button from "@appserver/components/button";
import Text from "@appserver/components/text";
import TextInput from "@appserver/components/text-input";
import Link from "@appserver/components/link";
import toastr from "@appserver/components/toast/toastr";
import Checkbox from "@appserver/components/checkbox";
//import HelpButton from "@appserver/components/help-button";
import PasswordInput from "@appserver/components/password-input";
import FieldContainer from "@appserver/components/field-container";
import PageLayout from "@appserver/common/PageLayout";
import ForgotPasswordModalDialog from "./sub-components/forgot-password-modal-dialog";
import Register from "./sub-components/register-container";
import { checkPwd } from "@appserver/common/desktop";
import { sendInstructionsToChangePassword } from "@appserver/common/api/people";
import { createPasswordHash, tryRedirectTo } from "@appserver/common/utils";
import { inject, observer } from "mobx-react";
import "./i18n";

const LoginContainer = styled.div`
  display: flex;
  flex-direction: column;
  align-items: center;
  margin: 120px auto 0 auto;
  max-width: 960px;

  @media (max-width: 768px) {
    padding: 0 16px;
    max-width: 475px;
  }
  @media (max-width: 375px) {
    margin: 72px auto 0 auto;
    max-width: 311px;
  }

  .greeting-title {
    width: 100%;

    @media (max-width: 768px) {
      text-align: left;
    }
    @media (max-width: 375px) {
      font-size: 23px;
    }
  }

  .auth-form-container {
    margin: 32px 213px 0 213px;
    width: 311px;

    @media (max-width: 768px) {
      margin: 32px 0 0 0;
      width: 100%;
    }
    @media (max-width: 375px) {
      margin: 32px 0 0 0;
      width: 100%;
    }

    .login-forgot-wrapper {
      height: 36px;
      padding: 14px 0;

      .login-checkbox-wrapper {
        display: flex;

        .login-checkbox {
          float: left;
          span {
            font-size: 12px;
          }
        }
      }

      .login-link {
        line-height: 18px;
        margin-left: auto;
      }
    }

    .login-button {
      margin-bottom: 16px;
    }

    .login-button-dialog {
      margin-right: 8px;
    }

    .login-bottom-border {
      width: 100%;
      height: 1px;
      background: #eceef1;
    }

    .login-bottom-text {
      margin: 0 8px;
    }
  }
`;

const LoginFormWrapper = styled.div`
  display: grid;
  grid-template-rows: ${(props) =>
    props.enabledJoin
      ? props.isDesktop
        ? css`1fr 10px`
        : css`1fr 66px`
      : css`1fr`};
  width: 100%;
  height: calc(100vh-56px);
`;

class Form extends Component {
  constructor(props) {
    super(props);

    this.state = {
      identifierValid: true,
      identifier: "",
      isLoading: false,
      isDisabled: false,
      passwordValid: true,
      password: "",
      isChecked: false,
      openDialog: false,
      email: "",
      emailError: false,
      errorText: "",
      socialButtons: [],
    };
  }

  onChangeLogin = (event) => {
    this.setState({ identifier: event.target.value });
    !this.state.identifierValid && this.setState({ identifierValid: true });
    this.state.errorText && this.setState({ errorText: "" });
  };

  onChangePassword = (event) => {
    this.setState({ password: event.target.value });
    !this.state.passwordValid && this.setState({ passwordValid: true });
    this.state.errorText && this.setState({ errorText: "" });
  };

  onChangeEmail = (event) => {
    this.setState({ email: event.target.value, emailError: false });
  };

  onChangeCheckbox = () => this.setState({ isChecked: !this.state.isChecked });

  onClick = () => {
    this.setState({
      openDialog: true,
      isDisabled: true,
      email: this.state.identifier,
    });
  };

  onKeyPress = (event) => {
    if (event.key === "Enter") {
      !this.state.isDisabled
        ? this.onSubmit()
        : this.onSendPasswordInstructions();
    }
  };

  onSendPasswordInstructions = () => {
    if (!this.state.email.trim()) {
      this.setState({ emailError: true });
    } else {
      this.setState({ isLoading: true });
      sendInstructionsToChangePassword(this.state.email)
        .then(
          (res) => toastr.success(res),
          (message) => toastr.error(message)
        )
        .finally(this.onDialogClose());
    }
  };

  onDialogClose = () => {
    this.setState({
      openDialog: false,
      isDisabled: false,
      isLoading: false,
      email: "",
      emailError: false,
    });
  };

  onSubmit = () => {
    const { errorText, identifier, password } = this.state;
    const { login, hashSettings, isDesktop, defaultPage } = this.props;

    errorText && this.setState({ errorText: "" });
    let hasError = false;

    const userName = identifier.trim();

    if (!userName) {
      hasError = true;
      this.setState({ identifierValid: !hasError });
    }

    const pass = password.trim();

    if (!pass) {
      hasError = true;
      this.setState({ passwordValid: !hasError });
    }

    if (hasError) return false;

    this.setState({ isLoading: true });
    const hash = createPasswordHash(pass, hashSettings);

    isDesktop && checkPwd();

    login(userName, hash)
      .then(() => tryRedirectTo(defaultPage))
      .catch((error) => {
        this.setState({
          errorText: error,
          identifierValid: !error,
          passwordValid: !error,
          isLoading: false,
        });
      });
  };

  componentDidMount() {
    const { match, t, organizationName } = this.props;
    const { error, confirmedEmail } = match.params;

    document.title = `${t("Authorization")} – ${organizationName}`; //TODO: implement the setDocumentTitle() utility in ASC.Web.Common

    error && this.setState({ errorText: error });
    confirmedEmail && this.setState({ identifier: confirmedEmail });
    window.addEventListener("keyup", this.onKeyPress);
  }

  componentWillUnmount() {
    window.removeEventListener("keyup", this.onKeyPress);
  }

  settings = {
    minLength: 6,
    upperCase: false,
    digits: false,
    specSymbols: false,
  };

  render() {
    const { greetingTitle, match, t } = this.props;

    const {
      identifierValid,
      identifier,
      isLoading,
      passwordValid,
      password,
      isChecked,
      openDialog,
      email,
      emailError,
      errorText,
      socialButtons,
    } = this.state;
    const { confirmedEmail } = match.params;

    //console.log("Login render");

    return (
      <>
        <LoginContainer>
          <Text
            fontSize="32px"
            fontWeight={600}
            textAlign="center"
            className="greeting-title"
          >
            {greetingTitle}
          </Text>

          <form className="auth-form-container">
            <FieldContainer
              isVertical={true}
              labelVisible={false}
              hasError={!identifierValid}
              errorMessage={errorText ? errorText : t("RequiredFieldMessage")} //TODO: Add wrong login server error
            >
              <TextInput
                id="login"
                name="login"
                hasError={!identifierValid}
                value={identifier}
                placeholder={t("RegistrationEmailWatermark")}
                size="large"
                scale={true}
                isAutoFocussed={true}
                tabIndex={1}
                isDisabled={isLoading}
                autoComplete="username"
                onChange={this.onChangeLogin}
                onKeyDown={this.onKeyPress}
              />
            </FieldContainer>
            <FieldContainer
              isVertical={true}
              labelVisible={false}
              hasError={!passwordValid}
              errorMessage={errorText ? "" : t("RequiredFieldMessage")} //TODO: Add wrong password server error
            >
              <PasswordInput
                simpleView={true}
                passwordSettings={this.settings}
                id="password"
                inputName="password"
                placeholder={t("Password")}
                type="password"
                hasError={!passwordValid}
                inputValue={password}
                size="large"
                scale={true}
                tabIndex={1}
                isDisabled={isLoading}
                autoComplete="current-password"
                onChange={this.onChangePassword}
                onKeyDown={this.onKeyPress}
              />
            </FieldContainer>
            <div className="login-forgot-wrapper">
              <div className="login-checkbox-wrapper">
                <Checkbox
                  className="login-checkbox"
                  isChecked={isChecked}
                  onChange={this.onChangeCheckbox}
                  label={<Text fontSize="13px">{t("Remember")}</Text>}
                />
                {/*<HelpButton
                  className="login-tooltip"
                  helpButtonHeaderContent={t("CookieSettingsTitle")}
                  tooltipContent={
                    <Text fontSize="12px">{t("RememberHelper")}</Text>
                  }
                />*/}
                <Link
                  fontSize="13px"
                  color="#316DAA"
                  className="login-link"
                  type="page"
                  isHovered={false}
                  onClick={this.onClick}
                >
                  {t("ForgotPassword")}
                </Link>
              </div>
            </div>

            {openDialog && (
              <ForgotPasswordModalDialog
                openDialog={openDialog}
                isLoading={isLoading}
                email={email}
                emailError={emailError}
                onChangeEmail={this.onChangeEmail}
                onSendPasswordInstructions={this.onSendPasswordInstructions}
                onDialogClose={this.onDialogClose}
                t={t}
              />
            )}

            <Button
              id="button"
              className="login-button"
              primary
              size="large"
              scale={true}
              label={isLoading ? t("LoadingProcessing") : t("LoginButton")}
              tabIndex={1}
              isDisabled={isLoading}
              isLoading={isLoading}
              onClick={this.onSubmit}
            />

            {confirmedEmail && (
              <Text isBold={true} fontSize="16px">
                {t("MessageEmailConfirmed")} {t("MessageAuthorize")}
              </Text>
            )}
            {/* TODO: old error indication
            
            <Text fontSize="14px" color="#c30">
              {errorText}
            </Text> */}

            {socialButtons.length ? (
              <Box displayProp="flex" alignItems="center">
                <div className="login-bottom-border"></div>
                <Text className="login-bottom-text" color="#A3A9AE">
                  {t("Or")}
                </Text>
                <div className="login-bottom-border"></div>
              </Box>
            ) : null}
          </form>
        </LoginContainer>
      </>
    );
  }
}

Form.propTypes = {
  login: PropTypes.func.isRequired,
  match: PropTypes.object.isRequired,
  hashSettings: PropTypes.object,
  greetingTitle: PropTypes.string.isRequired,
  t: PropTypes.func.isRequired,
  socialButtons: PropTypes.array,
  organizationName: PropTypes.string,
  homepage: PropTypes.string,
  defaultPage: PropTypes.string,
  isDesktop: PropTypes.bool,
};

Form.defaultProps = {
  identifier: "",
  password: "",
  email: "",
};

const FormWrapper = withTranslation()(Form);

//const RegisterWrapper = withTranslation()(Register);

const LoginForm = (props) => {
  const { enabledJoin, isDesktop } = props;

  return (
    <LoginFormWrapper enabledJoin={enabledJoin} isDesktop={isDesktop}>
      <PageLayout>
        <PageLayout.SectionBody>
          <FormWrapper {...props} />
        </PageLayout.SectionBody>
      </PageLayout>
      <Register />
    </LoginFormWrapper>
  );
};

LoginForm.propTypes = {
  isLoaded: PropTypes.bool,
  enabledJoin: PropTypes.bool,
  isDesktop: PropTypes.bool.isRequired,
};

export default inject(({ auth }) => {
  const { settingsStore, isAuthenticated, isLoaded, login } = auth;
  const {
    greetingSettings: greetingTitle,
    organizationName,
    hashSettings,
    enabledJoin,
    defaultPage,
    isDesktopClient: isDesktop,
  } = settingsStore;

  return {
    isAuthenticated,
    isLoaded,
    organizationName,
    greetingTitle,
    hashSettings,
    enabledJoin,
    defaultPage,
    isDesktop,
    login,
  };
})(withRouter(observer(LoginForm)));
