import {
  Alert,
  Box,
  Button,
  CircularProgress,
  TextField,
  Typography,
} from "@mui/material";
import React, { useEffect, useRef, useState } from "react";
import { useLocation } from "react-router-dom";
import { AuthApi, CheckResetTokenResponse } from "../../api/AuthApi";
import { PasswordInput } from "../../widgets/PasswordInput";
import { AuthSingleMessage } from "../../widgets/AuthSingleMessage";
import { ServerApi } from "../../api/ServerApi";

export function ResetPasswordRoute(): React.ReactElement {
  const [error, setError] = React.useState<string | null>(null);

  const { hash } = useLocation();
  const token = hash.substring(1);

  const [info, setInfo] = React.useState<null | CheckResetTokenResponse>(null);
  const checkedToken = useRef<null | string>(null);

  useEffect(() => {
    (async () => {
      if (token === checkedToken.current) return;
      checkedToken.current = token;

      try {
        setError(null);
        const info = await AuthApi.CheckResetPasswordToken(token);
        setInfo(info);
      } catch (e) {
        console.error(e);
        setError(
          "Echec de validation du jeton de réinitialisation de mot de passe!"
        );
      }
    })();
  });

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

  if (info === null)
    return (
      <>
        <CircularProgress />
      </>
    );

  return <ResetPasswordForm token={token} info={info} />;
}

function ResetPasswordForm(p: {
  token: string;
  info: CheckResetTokenResponse;
}): React.ReactElement {
  const [error, setError] = React.useState<string | null>(null);
  const [loading, setLoading] = React.useState(false);
  const [success, setSuccess] = React.useState(false);

  const [password, setPassword] = useState("");
  const [confirmPassword, setConfirmPassword] = useState("");

  const canSubmit =
    ServerApi.CheckPassword(password) === null && password === confirmPassword;

  const handleSubmit = async (event: React.FormEvent<HTMLFormElement>) => {
    event.preventDefault();

    if (!canSubmit) return;

    setLoading(true);

    try {
      await AuthApi.ResetPassword(p.token, password);
      setSuccess(true);
    } catch (e) {
      console.error(e);
      setError("Echec de la réinitialisation du mot de passe !");
    }

    setLoading(false);
  };

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

  if (success)
    return (
      <AuthSingleMessage message="Mot de passe réinitialisé avec succès. Vous pouvez dès à présent l'utiliser pour accéder à votre compte." />
    );

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

      <Typography
        component="h2"
        variant="body1"
        style={{ marginBottom: "15px" }}
      >
        Bonjour {p.info.name}, veuillez définir votre nouveau mot de passe :
      </Typography>
      <Box component="form" noValidate onSubmit={handleSubmit} sx={{ mt: 1 }}>
        <PasswordInput
          label="Nouveau mot de passe"
          value={password}
          onChange={(n) => {
            setPassword(n);
          }}
        />

        <TextField
          margin="normal"
          required
          fullWidth
          error={password !== confirmPassword}
          helperText={
            password !== confirmPassword
              ? "Les mots de passe saisis ne correspondent pas !"
              : null
          }
          value={confirmPassword}
          onChange={(e) => setConfirmPassword(e.target.value)}
          label="Confirmer le mot de passe"
          type="password"
          id="password"
          autoComplete="current-password"
        />

        <Button
          type="submit"
          fullWidth
          variant="contained"
          sx={{ mt: 3, mb: 2 }}
          disabled={!canSubmit}
        >
          Valider
        </Button>
      </Box>
    </>
  );
}
