import VisibilityIcon from "@mui/icons-material/Visibility";
import VisibilityOffIcon from "@mui/icons-material/VisibilityOff";
import {
  Alert,
  CircularProgress,
  FormControl,
  IconButton,
  InputAdornment,
  InputLabel,
  OutlinedInput,
  Tooltip,
} from "@mui/material";
import Box from "@mui/material/Box";
import Button from "@mui/material/Button";
import TextField from "@mui/material/TextField";
import Typography from "@mui/material/Typography";
import * as React from "react";
import { useNavigate } from "react-router-dom";
import { useAuth } from "../../App";
import { AuthApi } from "../../api/AuthApi";
import { ServerApi } from "../../api/ServerApi";

/**
 * Login form
 */
export function LoginRoute(): React.ReactElement {
  const [loading, setLoading] = React.useState(false);
  const [error, setError] = React.useState<string | null>(null);

  const auth = useAuth();
  const navigate = useNavigate();

  const [username, setUsername] = React.useState("");
  const [password, setPassword] = React.useState("");

  const canSubmit = username.length > 0 && password.length > 0;

  const [showPassword, setShowPassword] = React.useState(false);
  const handleClickShowPassword = () => {
    setShowPassword((show) => !show);
  };

  const handleMouseDownPassword = (
    event: React.MouseEvent<HTMLButtonElement>
  ) => {
    event.preventDefault();
  };

  const handleLoginSubmit = async (event: React.FormEvent<HTMLFormElement>) => {
    event.preventDefault();
    if (!canSubmit) return;

    try {
      await AuthApi.LoginWithPassword(username, password);

      navigate("/");
      auth.setSignedIn(true);
    } catch (e) {
      console.error(e);
      setError("Auth failed!");
    }
    setLoading(false);
  };

  const authWithOpenID = async () => {
    try {
      setLoading(true);

      const res = await AuthApi.StartOpenIDLogin();
      window.location.href = res.url;
    } catch (e) {
      console.error(e);
      setError("Failed to initialize OpenID login");
    }
  };

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

  return (
    <>
      {error && (
        <Alert style={{ width: "100%" }} severity="error">
          {error}
        </Alert>
      )}
      {ServerApi.Config.local_auth_enabled && (
        <>
          <Typography component="h2" variant="body1">
            Local authentication
          </Typography>
          <Box
            component="form"
            noValidate
            onSubmit={handleLoginSubmit}
            sx={{ mt: 1 }}
          >
            <TextField
              margin="normal"
              required
              fullWidth
              id="username"
              label="Username"
              name="username"
              value={username}
              onChange={(e) => {
                setUsername(e.target.value);
              }}
              autoComplete="username"
              autoFocus
            />

            <FormControl required fullWidth variant="outlined">
              <InputLabel htmlFor="password">Password</InputLabel>
              <OutlinedInput
                required
                fullWidth
                name="password"
                label="Password"
                type={showPassword ? "text" : "password"}
                id="password"
                value={password}
                onChange={(e) => {
                  setPassword(e.target.value);
                }}
                autoComplete="current-password"
                endAdornment={
                  <InputAdornment position="end">
                    <Tooltip title="Show password">
                      <IconButton
                        aria-label="toggle password visibility"
                        onClick={handleClickShowPassword}
                        onMouseDown={handleMouseDownPassword}
                        edge="end"
                      >
                        {showPassword ? (
                          <VisibilityOffIcon />
                        ) : (
                          <VisibilityIcon />
                        )}
                      </IconButton>
                    </Tooltip>
                  </InputAdornment>
                }
              />
            </FormControl>

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

      <div>
        {ServerApi.Config.oidc_auth_enabled && (
          <Button
            style={{ textAlign: "center", width: "100%", marginTop: "20px" }}
            onClick={() => authWithOpenID()}
          >
            Authenticate using OpenID
          </Button>
        )}
      </div>
    </>
  );
}
