import {
	Table,
	TableHead,
	TableRow,
	TableCell,
	TableBody,
	IconButton,
	Divider,
	Button,
} from "@material-ui/core";
import { Delete } from "@material-ui/icons";
import React from "react";
import { AdminAccount, AccountHelper } from "../../helpers/AccountHelper";
import { AdminAccountKey, AdminKeyHelper } from "../../helpers/AdminKeyHelper";
import { CopyToClipboard } from "../../utils/ClipboardUtils";
import { AsyncWidget } from "../widgets/AsyncWidget";
import {
	matConfirm,
	snackbar,
	matAlert,
	input,
} from "../widgets/DialogsProvider";
import { TimestampWidget } from "../widgets/TimestampWidget";
import { SettingsSection } from "./SettingsSection";

export class KeySettingsSection extends React.Component<
	{ admin: AdminAccount },
	{ keys: AdminAccountKey[]; counter: number }
> {
	constructor(props: any) {
		super(props);

		this.state = {
			keys: [],
			counter: 1,
		};

		this.load = this.load.bind(this);
		this.build = this.build.bind(this);
		this.generateResetToken = this.generateResetToken.bind(this);
		this.registerNewKey = this.registerNewKey.bind(this);
		this.deleteKey = this.deleteKey.bind(this);
	}

	async load() {
		const keys = await AdminKeyHelper.GetAdminKeys(this.props.admin.id);

		this.setState({ keys: keys });
	}

	async generateResetToken() {
		try {
			if (
				!(await matConfirm(
					"Do you really want to generate a reset token for this account?"
				))
			)
				return;

			const token = await AccountHelper.GenerateResetToken(
				this.props.admin.id
			);

			CopyToClipboard(token.token);
			snackbar("Reset token was successfully copied to the clipboard!");
		} catch (e) {
			console.error(e);
			matAlert("Failed to generate a token!");
		}
	}

	async registerNewKey() {
		try {
			const challenge =
				await AdminKeyHelper.GetKeyRegistrationChallenge();
			const credential = await navigator.credentials.create(challenge);

			if (credential == null) throw new Error("Operation aborted!");

			const name = await input({
				label: "Key name",
				maxLength: 40,
				minLength: 2,
			});

			await AdminKeyHelper.RegisterKey(name, credential);

			snackbar("Successfully enrolled a new key!");

			this.setState({ counter: this.state.counter + 1 });
		} catch (e) {
			console.error(e);
			matAlert("Failed to register a new key!");
		}
	}

	async deleteKey(key: AdminAccountKey) {
		try {
			if (
				!(await matConfirm(
					"Do you really want to delete the key '" + key.name + "' ?"
				))
			)
				return;

			await AdminKeyHelper.DeleteAuthKey(this.props.admin.id, key.id);

			snackbar("The key was successfully deleted!");
			this.setState({ counter: this.state.counter + 1 });
		} catch (e) {
			console.error(e);
			matAlert("Failed to delete key!");
		}
	}

	render() {
		return (
			<AsyncWidget
				errorMessage="Failed to load admin keys!"
				load={this.load}
				onBuild={this.build}
				key={this.props.admin.id + "-" + this.state.counter}
			></AsyncWidget>
		);
	}

	build() {
		return (
			<SettingsSection title="Security keys">
				<Table aria-label="simple table">
					<TableHead>
						<TableRow>
							<TableCell>Key name</TableCell>
							<TableCell align="right">Date added</TableCell>
							<TableCell align="right"></TableCell>
						</TableRow>
					</TableHead>
					<TableBody>
						{this.state.keys.map((key) => (
							<TableRow key={key.id}>
								<TableCell component="th" scope="row">
									{key.name}
								</TableCell>
								<TableCell align="right">
									<TimestampWidget time={key.time_add} />
								</TableCell>
								<TableCell align="right">
									<IconButton
										aria-label="delete"
										size="small"
										onClick={() => this.deleteKey(key)}
									>
										<Delete />
									</IconButton>
								</TableCell>
							</TableRow>
						))}
					</TableBody>
				</Table>

				<Divider />

				{/* Action buttons */}
				<div
					style={{
						textAlign: "right",
						margin: "5px 10px",
					}}
				>
					<Button onClick={this.generateResetToken}>
						New reset token
					</Button>
					<Button
						disabled={
							this.props.admin.id !==
							AccountHelper.currentAccount.id
						}
						onClick={this.registerNewKey}
					>
						Register a new key
					</Button>
				</div>
			</SettingsSection>
		);
	}
}
