import {
  Button,
  Dialog,
  DialogActions,
  DialogContent,
  DialogTitle,
  Tooltip,
} from "@mui/material";
import React from "react";
import { ServerApi } from "../api/ServerApi";
import { NewToken, TokenWithSecret, TokensApi } from "../api/TokensApi";
import { useAlert } from "../hooks/context_providers/AlertDialogProvider";
import { useLoadingMessage } from "../hooks/context_providers/LoadingMessageProvider";
import { checkConstraint } from "../utils/FormUtils";
import { CheckboxInput } from "../widgets/forms/CheckboxInput";
import { TextInput } from "../widgets/forms/TextInput";

const SECS_IN_DAY = 3600 * 24;

export function CreateTokenDialog(p: {
  open: boolean;
  onClose: () => void;
  onCreated: (t: TokenWithSecret) => void;
}): React.ReactElement {
  const alert = useAlert();
  const loadingMessage = useLoadingMessage();

  const [newTokenUndef, setNewToken] = React.useState<NewToken | undefined>();
  const newToken = newTokenUndef ?? {
    name: "",
    ip_net: undefined,
    max_inactivity: 3600 * 24 * 90,
    read_only: false,
    right_account: false,
    right_file: false,
    right_auth: false,
    right_inbox: false,
    right_movement: false,
    right_stats: false,
    right_backup: false,
  };

  const clearForm = () => {
    setNewToken(undefined);
  };

  const cancel = () => {
    p.onClose();
    clearForm();
  };

  const nameErr = checkConstraint(
    ServerApi.Config.constraints.token_name,
    newToken.name
  );
  const isValid = nameErr === undefined;

  const submit = async () => {
    try {
      loadingMessage.show("Creating token...");
      const token = await TokensApi.Create(newToken);

      clearForm();
      p.onCreated(token);
    } catch (e) {
      console.error(e);
      alert(`Failed to create token ! ${e}`);
    } finally {
      loadingMessage.hide();
    }
  };

  const updateRightsForMobileApp = () => {
    setNewToken({
      ...newToken,
      read_only: false,
      right_account: false,
      right_movement: false,
      right_file: true,
      right_auth: true,
      right_inbox: true,
      right_stats: false,
      right_backup: false,
    });
  };

  return (
    <Dialog open={p.open} onClose={cancel}>
      <DialogTitle>New token</DialogTitle>
      <DialogContent>
        <TextInput
          editable
          label="Token name"
          value={newToken.name}
          onValueChange={(v) => {
            setNewToken({
              ...newToken,
              name: v ?? "",
            });
          }}
          size={ServerApi.Config.constraints.token_name}
        />
        <TextInput
          editable
          label="IP Network (optional)"
          value={newToken.ip_net}
          onValueChange={(v) => {
            setNewToken({
              ...newToken,
              ip_net: v ?? "",
            });
          }}
          size={ServerApi.Config.constraints.token_ip_net}
        />
        <TextInput
          editable
          label="Max inactivity period (days)"
          type="number"
          value={(newToken.max_inactivity / SECS_IN_DAY).toString()}
          onValueChange={(i) => {
            setNewToken({
              ...newToken,
              max_inactivity: Number(i) * SECS_IN_DAY,
            });
          }}
          size={{
            min:
              ServerApi.Config.constraints.token_max_inactivity.min /
              SECS_IN_DAY,
            max:
              ServerApi.Config.constraints.token_max_inactivity.max /
              SECS_IN_DAY,
          }}
        />
        <CheckboxInput
          editable
          label="Read only"
          checked={newToken.read_only}
          onValueChange={(v) => {
            setNewToken({
              ...newToken,
              read_only: v,
            });
          }}
        />
        <Tooltip title="Tailor the rights for the mobile application">
          <Button onClick={updateRightsForMobileApp}>For mobile app</Button>
        </Tooltip>
        <br />
        <CheckboxInput
          editable
          label="Right: account routes"
          checked={newToken.right_account}
          onValueChange={(v) => {
            setNewToken({
              ...newToken,
              right_account: v,
            });
          }}
        />
        <br />
        <CheckboxInput
          editable
          label="Right: movement routes"
          checked={newToken.right_movement}
          onValueChange={(v) => {
            setNewToken({
              ...newToken,
              right_movement: v,
            });
          }}
        />
        <br />
        <CheckboxInput
          editable
          label="Right: inbox routes"
          checked={newToken.right_inbox}
          onValueChange={(v) => {
            setNewToken({
              ...newToken,
              right_inbox: v,
            });
          }}
        />
        <br />
        <CheckboxInput
          editable
          label="Right: file routes"
          checked={newToken.right_file}
          onValueChange={(v) => {
            setNewToken({
              ...newToken,
              right_file: v,
            });
          }}
        />
        <br />
        <CheckboxInput
          editable
          label="Right: auth routes"
          checked={newToken.right_auth}
          onValueChange={(v) => {
            setNewToken({
              ...newToken,
              right_auth: v,
            });
          }}
        />
        <br />
        <CheckboxInput
          editable
          label="Right: statistics routes"
          checked={newToken.right_stats}
          onValueChange={(v) => {
            setNewToken({
              ...newToken,
              right_stats: v,
            });
          }}
        />
        <br />
        <CheckboxInput
          editable
          label="Right: backup routes"
          checked={newToken.right_backup}
          onValueChange={(v) => {
            setNewToken({
              ...newToken,
              right_backup: v,
            });
          }}
        />
      </DialogContent>
      <DialogActions>
        <Button onClick={cancel}>Cancel</Button>
        <Button onClick={submit} autoFocus disabled={!isValid}>
          Create
        </Button>
      </DialogActions>
    </Dialog>
  );
}
