/*
User login and logout controller

@copyright (c) Copyright 2013-2016 Dorian Pula
@license AGPL v3
@author Dorian Pula [dorian.pula@amber-penguin-software.ca]
*/


import React from "react";
import {Modal, Button, Alert, FormControl, Form, ControlLabel, FormGroup, Col} from "react-bootstrap";
import FontAwesome from "react-fontawesome";
import {connect} from "react-redux";

import {loginUser, logoutUser} from "../actions";
import {appStore} from "../stores";


export class UserLoginView extends React.Component {
    static get propTypes() {
        return {
            isUserLoggedIn: React.PropTypes.bool,
            fullName: React.PropTypes.string,
            externalError: React.PropTypes.string,
        };
    }

    constructor(props) {
        super(props);
        this.state = {
            username: "",
            password: "",
            errorMessage: "",
            displayLoginModal: false
        };
        this.handleLoginAttempt = this.handleLoginAttempt.bind(this);
        this.updateErrorMessage = this.updateErrorMessage.bind(this);
        this.handleShowLoginModal = this.handleShowLoginModal.bind(this);
        this.handleHideLoginModal = this.handleHideLoginModal.bind(this);
        this.handleLogoutUser = this.handleLogoutUser.bind(this);
        this.handleUsernameUpdate = this.handleUsernameUpdate.bind(this);
        this.handlePasswordUpdate = this.handlePasswordUpdate.bind(this);
        this.handleKeyboardLogin = this.handleKeyboardLogin.bind(this);
    }

    componentWillReceiveProps(nextProps) {
        // TODO: Fix the transitions up, maybe have the login state as part of the app itself.
        if (nextProps.externalError !== "") {
            this.updateErrorMessage(nextProps.externalError);
        }

        if (nextProps.isUserLoggedIn === true) {
            this.handleHideLoginModal();
        }
    }

    handleLoginAttempt() {
        if (this.state.username === "" || this.state.password === "") {
            this.updateErrorMessage("Enter a username and password to login in...");
            return;
        }
       appStore.dispatch(loginUser(this.state.username, this.state.password));
    }

    updateErrorMessage(errorMessage="") {
        this.setState({errorMessage: errorMessage});
    }

    handleShowLoginModal() {
        this.setState({displayLoginModal: true});
    }

    handleHideLoginModal() {
        this.setState({username: "", password: "", errorMessage: "", displayLoginModal: false});
    }

    handleLogoutUser() {
        appStore.dispatch(logoutUser());
    }

    handleUsernameUpdate(event) {
        this.setState({username: event.target.value});
    }

    handlePasswordUpdate(event) {
        this.setState({password: event.target.value});
    }

    handleKeyboardLogin(event) {
        if (!this.state.displayLoginModal || event.key !== "Enter") {
            return;
        }

        if (this.state.username === "" || this.state.password === "") {
            this.updateErrorMessage("Enter a username and password to login in...");
            return;
        }
        appStore.dispatch(loginUser(this.state.username, this.state.password));
    }

    render() {
        let loggedIn = this.props.isUserLoggedIn;
        let loginMessage = loggedIn ? "logout" : "login";
        let loginIcon = loggedIn ? (<FontAwesome name="sign-in"/>) : (<FontAwesome name="sign-out"/>);
        let loginOperation = loggedIn ? this.handleLogoutUser : this.handleShowLoginModal;

        let errorDisplay = "";
        if (this.state.errorMessage !== undefined && this.state.errorMessage !== "") {
            errorDisplay = (<Alert bsStyle="danger">{ this.state.errorMessage }</Alert>);
        }

        let loginButtonDisabled = this.state.username === "" || this.state.password === "";

        return (
            <div>
                <div className="text-center muted hoverable" onClick={ loginOperation }>
                    <FontAwesome name="user"/>
                    &nbsp;
                    Hello { this.props.fullName }!
                    &ensp;
                    { loginIcon }
                    &nbsp;
                    Do you want to { loginMessage }?
                </div>
                <Modal show={ this.state.displayLoginModal } onHide={ this.handleHideLoginModal } onKeyPress={ this.handleKeyboardLogin }>
                    <Modal.Header closeButton>
                        <Modal.Title>User Login</Modal.Title>
                    </Modal.Header>

                    <Modal.Body>
                        {errorDisplay}
                        <Form horizontal>
                            <FormGroup controlId="username">
                                <Col xs={ 2 }>
                                    <ControlLabel>Username</ControlLabel>
                                </Col>
                                <Col xs={ 10 }>
                                    <FormControl type="text" placeholder="Username"
                                        value={ this.state.username } onChange={ this.handleUsernameUpdate } />
                                </Col>
                            </FormGroup>
                            <FormGroup controlId="password">
                                <Col xs={ 2 }>
                                    <ControlLabel>Password</ControlLabel>
                                </Col>
                                <Col xs={ 10 }>
                                    <FormControl type="password" placeholder="***"
                                        value={ this.state.password } onChange={ this.handlePasswordUpdate } />
                                </Col>
                            </FormGroup>
                        </Form>
                    </Modal.Body>

                    <Modal.Footer>
                        <Button bsStyle="warning" onClick={ this.handleHideLoginModal }>Cancel</Button>
                        <Button onClick={ this.handleLoginAttempt } disabled={ loginButtonDisabled }>Login</Button>
                    </Modal.Footer>
                </Modal>
            </div>
        );
    }
}


export const ConnectedUserLogin = connect(
    (state) => {
        return {
            "fullName": state.user.fullName,
            "isUserLoggedIn": state.user.token !== "",
            "externalError": state.user.accountState
        }
    }
)(UserLoginView);
