// Copyright (c) 2015 Mattermost, Inc. All Rights Reserved.
// See License.txt for license information.

import LoginMfa from './components/login_mfa.jsx';
import ErrorBar from 'components/error_bar.jsx';
import FormError from 'components/form_error.jsx';

import * as GlobalActions from 'action_creators/global_actions.jsx';
import UserStore from 'stores/user_store.jsx';

import Client from 'utils/web_client.jsx';
import * as TextFormatting from 'utils/text_formatting.jsx';

import * as Utils from 'utils/utils.jsx';
import Constants from 'utils/constants.jsx';

import {FormattedMessage} from 'react-intl';
import {browserHistory, Link} from 'react-router';

import React from 'react';
import logoImage from 'images/logo.png';

export default class Login extends React.Component {
    constructor(props) {
        super(props);

        this.preSubmit = this.preSubmit.bind(this);
        this.submit = this.submit.bind(this);
        this.finishSignin = this.finishSignin.bind(this);

        this.handleLoginIdChange = this.handleLoginIdChange.bind(this);
        this.handlePasswordChange = this.handlePasswordChange.bind(this);

        this.state = {
            loginId: '', // the browser will set a default for this
            password: '',
            showMfa: false
        };
    }

    componentDidMount() {
        document.title = global.window.mm_config.SiteName;

        if (UserStore.getCurrentUser()) {
            browserHistory.push('/select_team');
        }
    }

    preSubmit(e) {
        e.preventDefault();

        const loginId = this.state.loginId.trim();
        if (!loginId) {
            const ldapEnabled = global.window.mm_config.EnableLdap === 'true';
            const usernameSigninEnabled = global.window.mm_config.EnableSignInWithUsername === 'true';
            const emailSigninEnabled = global.window.mm_config.EnableSignInWithEmail === 'true';

            this.setState({
                serverError: (
                    <FormattedMessage
                        id='login.loginIdRequired'
                        defaultMessage='A {type} is required'
                        values={{
                            type: this.createLoginPlaceholder(emailSigninEnabled, usernameSigninEnabled, ldapEnabled)
                        }}
                    />
                )
            });

            return;
        }

        const password = this.state.password.trim();
        if (!password) {
            this.setState({
                serverError: (
                    <FormattedMessage
                        id='login.passwordRequired'
                        defaultMessage='A password is required'
                    />
                )
            });

            return;
        }

        if (global.window.mm_config.EnableMultifactorAuthentication !== 'true') {
            this.submit(loginId, password, '');
            return;
        }

        Client.checkMfa(
            loginId,
            (data) => {
                if (data.mfa_required === 'true') {
                    this.setState({showMfa: true});
                } else {
                    this.submit(loginId, password, '');
                }
            },
            (err) => {
                this.setState({serverError: err.message});
            }
        );
    }

    submit(loginId, password, token) {
        this.setState({showMfa: false, serverError: null});

        Client.webLogin(
            loginId,
            password,
            token,
            () => {
                this.finishSignin();
            },
            (err) => {
                if (err.id === 'api.user.login.not_verified.app_error') {
                    browserHistory.push('/should_verify_email?&email=' + encodeURIComponent(loginId));
                    return;
                } else if (err.id === 'store.sql_user.get_for_login.app_error' ||
                    err.id === 'ent.ldap.do_login.user_not_registered.app_error' ||
                    err.id === 'ent.ldap.do_login.user_filtered.app_error') {
                    this.setState({
                        serverError: (
                            <FormattedMessage
                                id='login.userNotFound'
                                defaultMessage="We couldn't find an existing account matching your login credentials."
                            />
                        )
                    });
                } else {
                    this.setState({serverError: err.message});
                }
            }
        );
    }

    finishSignin() {
        GlobalActions.emitInitialLoad(
            () => {
                browserHistory.push('/select_team');
            }
        );
    }

    handleLoginIdChange(e) {
        this.setState({
            loginId: e.target.value
        });
    }

    handlePasswordChange(e) {
        this.setState({
            password: e.target.value
        });
    }

    createCustomLogin() {
        if (global.window.mm_license.IsLicensed === 'true' &&
                global.window.mm_license.CustomBrand === 'true' &&
                global.window.mm_config.EnableCustomBrand === 'true') {
            const text = global.window.mm_config.CustomBrandText || '';

            return (
                <div>
                    <img
                        src={Client.getAdminRoute() + '/get_brand_image'}
                    />
                    <p dangerouslySetInnerHTML={{__html: TextFormatting.formatText(text)}}/>
                </div>
            );
        }

        return null;
    }

    createLoginPlaceholder(emailSigninEnabled, usernameSigninEnabled, ldapEnabled) {
        const loginPlaceholders = [];
        if (emailSigninEnabled) {
            loginPlaceholders.push(Utils.localizeMessage('login.email', 'Email'));
        }

        if (usernameSigninEnabled) {
            loginPlaceholders.push(Utils.localizeMessage('login.username', 'Username'));
        }

        if (ldapEnabled) {
            if (global.window.mm_config.LdapLoginFieldName) {
                loginPlaceholders.push(global.window.mm_config.LdapLoginFieldName);
            } else {
                loginPlaceholders.push(Utils.localizeMessage('login.ldap_username', 'LDAP Username'));
            }
        }

        if (loginPlaceholders.length >= 2) {
            return loginPlaceholders.slice(0, loginPlaceholders.length - 1).join(', ') +
                Utils.localizeMessage('login.placeholderOr', ' or ') +
                loginPlaceholders[loginPlaceholders.length - 1];
        } else if (loginPlaceholders.length === 1) {
            return loginPlaceholders[0];
        }

        return '';
    }

    createLoginOptions() {
        const extraParam = Utils.getUrlParameter('extra');
        let extraBox = '';
        if (extraParam) {
            if (extraParam === Constants.SIGNIN_CHANGE) {
                extraBox = (
                    <div className='alert alert-success'>
                        <i className='fa fa-check'/>
                        <FormattedMessage
                            id='login.changed'
                            defaultMessage=' Sign-in method changed successfully'
                        />
                    </div>
                );
            } else if (extraParam === Constants.SIGNIN_VERIFIED) {
                extraBox = (
                    <div className='alert alert-success'>
                        <i className='fa fa-check'/>
                        <FormattedMessage
                            id='login.verified'
                            defaultMessage=' Email Verified'
                        />
                    </div>
                );
            } else if (extraParam === Constants.SESSION_EXPIRED) {
                extraBox = (
                    <div className='alert alert-warning'>
                        <i className='fa fa-exclamation-triangle'/>
                        <FormattedMessage
                            id='login.session_expired'
                            defaultMessage=' Your session has expired. Please login again.'
                        />
                    </div>
                );
            } else if (extraParam === Constants.PASSWORD_CHANGE) {
                extraBox = (
                    <div className='alert alert-success'>
                        <i className='fa fa-check'/>
                        <FormattedMessage
                            id='login.passwordChanged'
                            defaultMessage=' Password updated successfully'
                        />
                    </div>
                );
            }
        }

        const ldapEnabled = global.window.mm_config.EnableLdap === 'true';
        const gitlabSigninEnabled = global.window.mm_config.EnableSignUpWithGitLab === 'true';
        const googleSigninEnabled = global.window.mm_config.EnableSignUpWithGoogle === 'true';
        const usernameSigninEnabled = global.window.mm_config.EnableSignInWithUsername === 'true';
        const emailSigninEnabled = global.window.mm_config.EnableSignInWithEmail === 'true';

        const oauthLogins = [];
        if (gitlabSigninEnabled) {
            oauthLogins.push(
                <a
                    className='btn btn-custom-login gitlab'
                    key='gitlab'
                    href={Client.getOAuthRoute() + '/gitlab/login'}
                >
                    <span className='icon'/>
                    <span>
                        <FormattedMessage
                            id='login.gitlab'
                            defaultMessage='with GitLab'
                        />
                    </span>
                </a>
            );
        }

        if (googleSigninEnabled) {
            oauthLogins.push(
                <Link
                    className='btn btn-custom-login google'
                    key='google'
                    to={Client.getOAuthRoute() + '/google/login'}
                >
                    <span className='icon'/>
                    <span>
                        <FormattedMessage
                            id='login.google'
                            defaultMessage='with Google Apps'
                        />
                    </span>
                </Link>
            );
        }

        let login = null;
        if (emailSigninEnabled || usernameSigninEnabled || ldapEnabled) {
            let errorClass = '';
            if (this.state.serverError) {
                errorClass = ' has-error';
            }

            login = (
                <form onSubmit={this.preSubmit}>
                    <div className='signup__email-container'>
                        <FormError error={this.state.serverError}/>
                        <div className={'form-group' + errorClass}>
                            <input
                                className='form-control'
                                name='loginId'
                                value={this.state.loginId}
                                onChange={this.handleLoginIdChange}
                                placeholder={this.createLoginPlaceholder(emailSigninEnabled, usernameSigninEnabled, ldapEnabled)}
                                spellCheck='false'
                            />
                        </div>
                        <div className={'form-group' + errorClass}>
                            <input
                                type='password'
                                className='form-control'
                                name='password'
                                value={this.state.password}
                                onChange={this.handlePasswordChange}
                                placeholder={Utils.localizeMessage('login.password', 'Password')}
                                spellCheck='false'
                            />
                        </div>
                        <div className='form-group'>
                            <button
                                type='submit'
                                className='btn btn-primary'
                            >
                                <FormattedMessage
                                    id='login.signIn'
                                    defaultMessage='Sign in'
                                />
                            </button>
                        </div>
                    </div>
                </form>
            );
        }

        var userSignUp;
        if (global.window.mm_config.EnableOpenServer === 'true') {
            userSignUp = (
                <div>
                    <span>
                        <FormattedMessage
                            id='login.noAccount'
                            defaultMessage="Don't have an account? "
                        />
                        <Link
                            to={'/signup_user_complete'}
                            className='signup-team-login'
                        >
                            <FormattedMessage
                                id='login.create'
                                defaultMessage='Create one now'
                            />
                        </Link>
                    </span>
                </div>
            );
        }

        let forgotPassword;
        if (usernameSigninEnabled || emailSigninEnabled) {
            forgotPassword = (
                <div className='form-group'>
                    <Link to={'/reset_password'}>
                        <FormattedMessage
                            id='login.forgot'
                            defaultMessage='I forgot my password'
                        />
                    </Link>
                </div>
            );
        }

        return (
            <div>
                {extraBox}
                {oauthLogins}
                {login}
                {userSignUp}
                {forgotPassword}
            </div>
        );
    }

    render() {
        let content;
        let customContent;
        let customClass;
        if (this.state.showMfa) {
            content = (
                <LoginMfa
                    loginId={this.state.loginId}
                    password={this.state.password}
                    submit={this.submit}
                />
            );
        } else {
            content = this.createLoginOptions();
            customContent = this.createCustomLogin();
            if (customContent) {
                customClass = 'branded';
            }
        }

        return (
            <div>
                <ErrorBar/>
                <div className='col-sm-12'>
                    <div className={'signup-team__container ' + customClass}>
                        <div className='signup__markdown'>
                            {customContent}
                        </div>
                        <img
                            className='signup-team-logo'
                            src={logoImage}
                        />
                        <h1>{global.window.mm_config.SiteName}</h1>
                        <h4 className='color--light'>
                            <FormattedMessage
                                id='web.root.singup_info'
                            />
                        </h4>
                        <div className='signup__content'>
                            {content}
                        </div>
                    </div>
                </div>
            </div>
        );
    }
}

Login.defaultProps = {
};
Login.propTypes = {
    params: React.PropTypes.object.isRequired
};
