import * as React from "react";

import Typography from "@material-ui/core/Typography";
import Paper from "@material-ui/core/Paper";
import TextField from "@material-ui/core/TextField";
import Grid from "@material-ui/core/Grid";
import Button from "@material-ui/core/Button";
import LinearProgress from "@material-ui/core/LinearProgress";
import Snackbar from "@material-ui/core/Snackbar";

import { withRouter, Link } from "react-router-dom";

import { IUser } from "../models/user";
import { IResponse } from "../models/server";

interface IProps {
    login: (username: string, password: string) => Promise<IUser | IResponse>;
    authenticated: boolean;
    history: any;

    didLogin: boolean;
    setLoading: (state: boolean) => void;
    setSnackbar: (state: boolean, msg: string) => void;
    loading: boolean;
    snackOpen: boolean;
    snackMsg: string;
}

const LoginPageWithRouter = withRouter(
    class LoginPage extends React.Component<IProps> {
        private usernameRef: any = undefined;
        private passwordRef: any = undefined;

        performLogin = () => {
            // Check if the inputs are even valid
            const username = this.usernameRef.value || "";
            const password = this.passwordRef.value || "";
            if (!username) {
                this.props.setSnackbar(true, "Ungültiger Nutzername");
                return;
            }
            if (!password) {
                this.props.setSnackbar(true, "Ungültiges Passwort");
                return;
            }

            this.props.setLoading(true);

            this.props.login(username, password).then((res: IUser) => {
                // Stop the loading animation
                this.props.setLoading(false);

                if (res.showWelcome) {
                    // If the user logs in for the first time, a welcome
                    // screen should be shown
                    this.props.history.push("/welcome");
                } else {
                    this.props.history.push("/dashboard");
                }
            }).catch((err: IResponse) => {
                this.props.setLoading(false);
                this.props.setSnackbar(true, "Failed to log in");
            });
        }

        componentDidMount() {
            // If we're already authenticated, we can skip the login page
            // NOTE: The '!this.props.didLogin' is here, as the Component gets
            //       remounted, when the auth status changes. Thus we would
            //       redirect to /dashboard, redirect back to /welcome
            //       (or /dashboard again) and cause mulitple API calls!
            if (this.props.authenticated && !this.props.didLogin) {
                this.props.history.push("/dashboard");
            }
        }

        render() {
            // Trigger a login when return is pressed
            const onEnter = (event: any) => {
                if (event.key === "Enter") {
                    this.performLogin();
                }
            };

            return <div>
                <Grid
                    container
                    spacing={0}
                    direction="column"
                    alignItems="center"
                    justify="center"
                    style={{ minHeight: '100vh' }}>
                    <Grid item xs={12}>
                        <Paper className="paper">
                            <Typography variant="title">Login</Typography>
                            <Grid container direction="column" spacing={8}>
                                <Grid item>
                                    <TextField
                                        label="Username"
                                        onKeyPress={onEnter}
                                        inputRef={node => this.usernameRef = node} />
                                </Grid>
                                <Grid item>
                                    <TextField
                                        label="Passwort"
                                        type="password"
                                        onKeyPress={onEnter}
                                        inputRef={node => this.passwordRef = node} />
                                </Grid>
                                <Grid item>
                                    <Button
                                        variant="contained"
                                        color="primary"
                                        className="login-btn"
                                        onClick={() => this.performLogin()}>
                                        Login
                                    </Button>
                                    <Link to="/register">
                                        Registrieren
                                    </Link>
                                    {
                                        this.props.loading ? (
                                            <LinearProgress />
                                        ) : undefined
                                    }
                                </Grid>
                            </Grid>
                        </Paper>
                    </Grid>
                </Grid>
                <Snackbar
                    open={this.props.snackOpen}
                    onClose={() => this.props.setSnackbar(false, "")}
                    message={this.props.snackMsg}
                    autoHideDuration={6000} />
            </div>;
        }
    }
);
export default LoginPageWithRouter;
