"use client";

import { Visibility, VisibilityOff } from "@mui/icons-material";
import { FormHelperText, IconButton, InputAdornment, SxProps } from "@mui/material";
import Button from "@mui/material/Button";
import Stack from "@mui/material/Stack";
import TextField from "@mui/material/TextField";
import Typography from "@mui/material/Typography";
import { TFunction } from "i18next";
import { signIn } from "next-auth/react";
import { useRouter } from "next/navigation";
import { useState } from "react";
import { SubmitHandler, useForm } from "react-hook-form";
import { useTranslation } from "react-i18next";

type LoginFields = {
  username: string;
  password: string;
};

// Error codes in https://next-auth.js.org/configuration/pages#sign-in-page
const getHumanFriendlyErrorMessage = (
  t: TFunction,
  serverError: string,
): string => {
  switch (serverError) {
    case "CredentialsSignin":
      return t("Invalid username or password.");
    case "Default":
    default:
      return t("Something went wrong. Please try again later.");
  }
};

const LoginForm: React.FC<{ sx?: SxProps }> = ({ sx }) => {
  const { t } = useTranslation("login");
  const {
    register,
    handleSubmit,
    formState: { errors, isSubmitting },
  } = useForm<LoginFields>();

  const [serverError, setServerError] = useState<string>();

  const [showPassword, setShowPassword] = useState(false);
  const handleClickShowPassword = () => setShowPassword(!showPassword);
  const handleMouseDownPassword = () => setShowPassword(!showPassword);

  const router = useRouter();

  const onSubmit: SubmitHandler<LoginFields> = async (data) => {
    const res = await signIn("credentials", {
      redirect: false,
      ...data,
    });

    if (res?.error) {
      setServerError(res.error);
      return;
    }
    const callbackUrl =
      new URLSearchParams(window.location.search).get("callbackUrl") || "/";

    router.push(callbackUrl);
  };

  return (
    <Stack
      spacing={3}
      margin={5}
      component="form"
      onSubmit={handleSubmit(onSubmit)}
      sx={sx}
    >
      <Typography variant="h1">{t("Sign In")}</Typography>
      <TextField
        label={t("Username")}
        {...register("username", { required: t("Please enter a username") })}
        error={Boolean(errors.username)}
        helperText={errors.username?.message}
      />
      <TextField
        label={t("Password")}
        type={showPassword ? "text" : "password"}
        {...register("password", { required: t("Please enter a password") })}
        error={Boolean(errors.password)}
        helperText={errors.password?.message}
        InputProps={{
          endAdornment: (
            <InputAdornment position="end">
              <IconButton
                aria-label="toggle password visibility"
                onClick={handleClickShowPassword}
                onMouseDown={handleMouseDownPassword}
              >
                {showPassword ? <Visibility /> : <VisibilityOff />}
              </IconButton>
            </InputAdornment>
          ),
        }}
      />
      {serverError && (
        <FormHelperText error>
          {getHumanFriendlyErrorMessage(t, serverError)}
        </FormHelperText>
      )}
      <Button
        variant="contained"
        size="large"
        type="submit"
        disabled={isSubmitting}
      >
        {t("Login")}
      </Button>
    </Stack>
  );
};

export default LoginForm;
