/**
 * Login route
 *
 * @author Pierre Hubert
 */

import {
	Avatar,
	Box,
	Button,
	Container,
	CssBaseline,
	List,
	ListItem,
	ListItemAvatar,
	ListItemText,
	Paper,
	TextField,
	Typography,
} from "@material-ui/core";
import { ErrorOutline, Lock, VpnKey } from "@material-ui/icons";
import LockOutlinedIcon from "@material-ui/icons/LockOutlined";
import React from "react";
import { AccountHelper, AuthOptions } from "../../helpers/AccountHelper";
import { input, matAlert } from "../widgets/DialogsProvider";

function ErrorGettingOptions() {
	return (
		<Paper
			style={{
				width: "100%",
				padding: "10px",
				marginTop: "10px",
				display: "flex",
				alignItems: "center",
			}}
		>
			<ErrorOutline></ErrorOutline>
			&nbsp; Could not get your auth options!
		</Paper>
	);
}

function Copyright() {
	return (
		<Typography variant="body2" color="textSecondary" align="center">
			{"Copyright © "}
			Comunic&nbsp;
			{new Date().getFullYear()}
			{"."}
		</Typography>
	);
}

interface LoginRouteState {
	currEmail: string;
	errorGettingAuthOptions: boolean;
	authOptions?: AuthOptions;
}

export class LoginRoute extends React.Component<{}, LoginRouteState> {
	constructor(props: any) {
		super(props);

		this.state = {
			currEmail: "",
			errorGettingAuthOptions: false,
			authOptions: undefined,
		};

		this.handleChangedEmail = this.handleChangedEmail.bind(this);
		this.handleSubmitEmail = this.handleSubmitEmail.bind(this);
	}

	get canSubmit(): boolean {
		return this.state.currEmail.length > 4;
	}

	handleChangedEmail(e: React.ChangeEvent<HTMLInputElement>) {
		this.setState({
			currEmail: e.target.value,
			errorGettingAuthOptions: false,
			authOptions: undefined,
		});
	}

	async handleSubmitEmail(e: React.ChangeEvent<any>) {
		try {
			e.preventDefault();

			if (!this.canSubmit) return;

			const options = await AccountHelper.getAuthOptions(
				this.state.currEmail
			);
			this.setState({
				errorGettingAuthOptions: false,
				authOptions: options,
			});
		} catch (e) {
			console.error("Failed to get auth options!", e);

			this.setState({ errorGettingAuthOptions: true });
		}
	}

	render() {
		return (
			<div
				style={{
					display: "flex",
					justifyContent: "center",
					alignItems: "center",
					height: "100%",
				}}
			>
				<Container component="main" maxWidth="xs">
					<CssBaseline />
					<div
						style={{
							marginTop: "8px",
							display: "flex",
							flexDirection: "column",
							alignItems: "center",
						}}
					>
						<Avatar
							style={{
								margin: "1px",
								backgroundColor: "pink",
							}}
						>
							<LockOutlinedIcon />
						</Avatar>
						<Typography
							component="h1"
							variant="h5"
							style={{ margin: "10px", marginBottom: "50px" }}
						>
							Comunic Console
						</Typography>
						<form
							style={{
								width: "100%", // Fix IE 11 issue.
								marginTop: "1px",
							}}
							noValidate
							onSubmit={this.handleSubmitEmail}
						>
							<TextField
								variant="outlined"
								margin="normal"
								required
								fullWidth
								id="email"
								label="Email Address"
								value={this.state.currEmail}
								autoComplete="email"
								onChange={this.handleChangedEmail}
								autoFocus
							/>

							<Button
								onClick={this.handleSubmitEmail}
								fullWidth
								variant="contained"
								color="primary"
								style={{
									margin: "10px 0px 2px 0px",
								}}
								disabled={!this.canSubmit}
							>
								Sign In
							</Button>
						</form>

						{/* Login error (if any) */}
						{this.state.errorGettingAuthOptions ? (
							ErrorGettingOptions()
						) : (
							<div></div>
						)}

						{/* Auth options */}
						{this.state.authOptions ? (
							<AuthOptionsWidget
								email={this.state.currEmail}
								options={this.state.authOptions}
							></AuthOptionsWidget>
						) : (
							<div></div>
						)}
					</div>
					<Box mt={8}>
						<Copyright />
					</Box>
				</Container>
			</div>
		);
	}
}

interface AuthOptionsWidgetProps {
	email: string;
	options: AuthOptions;
}

interface AuthOptionsWidgetState {}

class AuthOptionsWidget extends React.Component<
	AuthOptionsWidgetProps,
	AuthOptionsWidgetState
> {
	constructor(props: Readonly<AuthOptionsWidgetProps>) {
		super(props);

		this.state = {};

		this.loginWithResetToken = this.loginWithResetToken.bind(this);
		this.loginWithSecurityKey = this.loginWithSecurityKey.bind(this);
	}

	async loginWithResetToken() {
		try {
			const token = await input({
				label: "Reset token",
				message: "Please specify here your token:",
				minLength: 2,
				title: "Login using access token",
			});

			await AccountHelper.authWithResetToken(this.props.email, token);

			document.location.href = document.location.href + "";
		} catch (e) {
			console.error(e);
			matAlert("Authentication failed!");
		}
	}

	async loginWithSecurityKey(id: number) {
		console.info(id);
	}

	render() {
		return (
			<Paper style={{ width: "100%", marginTop: "10px" }}>
				<List style={{ width: "100%" }}>
					{/* Password reset token */}
					{this.props.options.reset_token ? (
						<ListItem button onClick={this.loginWithResetToken}>
							<ListItemAvatar>
								<Avatar>
									<Lock />
								</Avatar>
							</ListItemAvatar>
							<ListItemText
								primary="Reset token"
								secondary="Sign in using a reset token"
							/>
						</ListItem>
					) : (
						<span></span>
					)}

					{this.props.options.keys.map((key) => (
						<ListItem
							button
							onClick={() => this.loginWithSecurityKey(key.id)}
							key={key.id}
						>
							<ListItemAvatar>
								<Avatar>
									<VpnKey />
								</Avatar>
							</ListItemAvatar>
							<ListItemText
								primary={key.name}
								secondary="Sign in using this security key"
							/>
						</ListItem>
					))}
				</List>
			</Paper>
		);
	}
}
