import {
  Alert,
  Box,
  Button,
  CircularProgress,
  TextField,
  Typography,
} from "@mui/material";
import React from "react";
import { ServerApi } from "../../api/ServerApi";
import { Link } from "react-router-dom";
import { AuthSingleMessage } from "../../widgets/AuthSingleMessage";
import { AuthApi, CreateAccountResult } from "../../api/AuthApi";

export function NewAccountRoute(): React.ReactElement {
  const [mail, setMail] = React.useState("");
  const [name, setName] = React.useState("");

  const [showErrors, setShowErrors] = React.useState(false);
  const [loading, setLoading] = React.useState(false);
  const [error, setError] = React.useState<string | null>(null);
  const [success, setSuccess] = React.useState(false);

  const nameLen = ServerApi.Config.constraints.user_name_len;
  const mailLen = ServerApi.Config.constraints.mail_len;

  const mailValid = mail.length >= mailLen.min && mail.length <= mailLen.max;
  const nameValid = name.length >= nameLen.min && name.length <= nameLen.max;
  const canSubmit = mailValid && nameValid;

  const handleSubmit = async (event: React.FormEvent<HTMLFormElement>) => {
    event.preventDefault();
    setShowErrors(true);
    if (!canSubmit) return;
    setLoading(true);
    try {
      const res = await AuthApi.CreateAccount(name, mail);
      switch (res) {
        case CreateAccountResult.Success:
          setSuccess(true);
          break;

        case CreateAccountResult.TooManyRequests:
          setError("Trop de tentatives. Veuillez réessayer ultérieurement.");
          break;

        case CreateAccountResult.MailAlreadyExists:
          setError(
            "Cette adresse mail est associée à un compte existant. Veuillez essayer de vous connecter ou de réinitialiser votre mot de passe."
          );
          break;

        case CreateAccountResult.BadInputData:
          setError("Les données saisies sont invalides !");
          break;

        case CreateAccountResult.Error:
          setError("Une erreur a survenue lors de la création du compte !");
          break;
      }
    } catch (e) {
      console.error(e);
      setError(
        "Une erreur a survenue lors de la tentative de création de compte !"
      );
    }

    setLoading(false);
  };

  if (loading)
    return (
      <>
        <CircularProgress />
      </>
    );

  if (success)
    return (
      <AuthSingleMessage
        message={
          "Votre demande a bien été enregistrée ! Pour terminer la création de votre compte, veuillez consulter votre messagerie et ouvrir le mail qui vous a été envoyé."
        }
      />
    );

  return (
    <>
      {error && (
        <Alert style={{ width: "100%" }} severity="error">
          {error}
        </Alert>
      )}

      <Typography component="h2" variant="body1">
        Nouveau compte
      </Typography>

      <Box
        component="form"
        noValidate
        onSubmit={handleSubmit}
        sx={{ mt: 1 }}
        style={{ width: "100%" }}
      >
        <TextField
          margin="normal"
          required
          error={showErrors && !nameValid}
          fullWidth
          value={name}
          onChange={(v) => setName(v.target.value)}
          id="name"
          label="Nom"
          autoComplete="name"
          autoFocus
          inputProps={{
            maxLength: nameLen.max,
          }}
          helperText={`Saisissez votre nom (entre ${nameLen.min} et ${nameLen.max} caractères)`}
        />
        <TextField
          margin="normal"
          required
          error={showErrors && !mailValid}
          fullWidth
          value={mail}
          onChange={(v) => setMail(v.target.value)}
          label="Adresse mail"
          autoComplete="email"
          autoFocus
          inputProps={{ maxLength: mailLen.max }}
          helperText={`Saisissez votre adresse mail (entre ${mailLen.min} et ${mailLen.max} caractères)`}
        />

        <Button
          type="submit"
          fullWidth
          variant="contained"
          sx={{ mt: 3, mb: 2 }}
        >
          Créer le compte
        </Button>
      </Box>

      <Typography variant="body2" color={"primary"}>
        <Link
          to="/"
          style={{ color: "inherit", textDecorationColor: "inherit" }}
        >
          Retour au formulaire de connexion
        </Link>
      </Typography>
    </>
  );
}
