import React, { useEffect, useState } from "react";
import { useRouter } from "next/router";
import { setCookie } from "cookies-next";
import { useSnackbar } from "notistack";
import Grid from "@mui/material/Grid";
import LoadingButton from "@mui/lab/LoadingButton";
import IconButton from "@mui/material/IconButton";
import { Typography } from "@mui/material";
import { Box } from "@mui/system";
import TextField from "@mui/material/TextField";
import InputAdornment from "@mui/material/InputAdornment";
import Button from "@mui/material/Button";
import Visibility from "@mui/icons-material/Visibility";
import VisibilityOff from "@mui/icons-material/VisibilityOff";
import styles from "./signinform.module.css";
import Fetcher from "services/Fetcher";
import { useUserProfile } from "contexts/userProfileContext";

const SignInForm = () => {
  const { state, dispatch } = useUserProfile();

  // Define and initialize state variables
  const [formValues, setFormValues] = useState({
    email: "",
    password: "",
  });
  const [errorHandlers, setErrorHandlers] = useState({
    email: false,
    password: false,
  });
  const [loading, setLoading] = useState(false);
  const [errMsg, setErrMsg] = useState("");

  // Create instances of external services
  const api = new Fetcher();
  const router = useRouter();

  // Access the Snackbar notification function
  const { enqueueSnackbar } = useSnackbar();

  // Handle changes in the input fields
  const handleChange = (event) => {
    setFormValues({ ...formValues, [event.target.name]: event.target.value });
  };

  // Handle form submission
  const handleSubmit = async (event) => {
    event.preventDefault();

    const { email, password } = formValues;

    // Validate the form fields
    if (email === "" && password === "") {
      setErrorHandlers({ ...errorHandlers, email: true, password: true });
      setErrMsg("all fields are required");
      setTimeout(() => {
        setErrorHandlers({ ...errorHandlers, email: false, password: false });
        setErrMsg("");
      }, 2000);
      return;
    } else if (email === "") {
      setErrorHandlers({ ...errorHandlers, email: true });
      setErrMsg("email field is required");
      setTimeout(() => {
        setErrorHandlers({ ...errorHandlers, email: false });
        setErrMsg("");
      }, 2000);
      return;
    } else if (password === "") {
      setErrorHandlers({ ...errorHandlers, password: true });
      setErrMsg("password field is required");
      setTimeout(() => {
        setErrorHandlers({ ...errorHandlers, password: false });
        setErrMsg("");
      }, 2000);
      return;
    }

    // Initiate the login process
    setLoading(true);
    try {
      // Prepare the login request data
      const data = {
        username: email,
        password,
      };

      // Send the login request to the server
      const res = await api.login(data);

      if (res.status === 204 || res.length === 0) {
        // Handle login failure
        enqueueSnackbar("Wrong Credentials", {
          variant: "error",
        });
        setLoading(false);
        return;
      }

      // Store the token in cookies
      // Calculate the expiration time in 24 hours
      const expirationDate = new Date();
      expirationDate.setTime(expirationDate.getTime() + 24 * 60 * 60 * 1000); // 24 hours in milliseconds

      const cookieOptions = {
        expires: expirationDate,
        httpOnly: true, // Make the cookie accessible only via HTTP (recommended for security)
      };

      
      // Set the login token in a cookie
      await setCookie("cmc-token", res.token);

      const userProfileData = res.profile;
      dispatch({ type: 'SET_USER_PROFILE', payload: userProfileData });

      enqueueSnackbar("Login Successful", {
        variant: "success",
        autoHideDuration: 4000,
      });

      // Redirect the user to a new page after successful login
      router.push("/");

      console.log(res);
    } catch (error) {
      // Handle any errors that occur during login
      setLoading(false);
      console.log(error);
    } finally {
      // Ensure that the loading indicator is cleared after a short delay
      setTimeout(() => {
        setLoading(false);
      }, 5000);
    }
  };

  // Define and initialize the state variable for toggling password visibility
  const [showPassword, setShowPassword] = useState(false);

  // Toggle password visibility
  const handleTogglePassword = () => {
    setShowPassword(!showPassword);
  };

  useEffect(() => {
    // Prefetch the dashboard page to optimize navigation
    router.prefetch("/");
  });

  return (
    <>
      <div className={styles.authenticationBox}>
        <Box
          component="main"
          sx={{
            maxWidth: "510px",
            ml: "auto",
            mr: "auto",
            padding: "50px 0 100px",
            paddingInline: { sm: "10px", lg: "0" },
            zIndex: "999",
            position: "relative",
          }}
        >
          <Grid item xs={12} md={12} lg={12} xl={12}>
            <Box>
              <Box
                display="flex"
                alignItems="center"
                justifyContent="center"
                mb="70px"
              >
                <img
                  src="/images/logos/android-chrome-512x512.png"
                  alt="logo"
                  className={styles.favicon}
                />
              </Box>

              <Box component="form" noValidate onSubmit={handleSubmit}>
                <Box
                  sx={{
                    background: "#fff",
                    padding: "30px 20px",
                    borderRadius: "10px",
                    mb: "20px",
                  }}
                  className="bg-black"
                >
                  <Grid container alignItems="center" spacing={2}>
                    <Grid item xs={12}>
                      <TextField
                        required
                        fullWidth
                        id="email"
                        label={
                          errorHandlers.email && errMsg !== ""
                            ? errMsg
                            : "Email Address"
                        }
                        value={formValues.email}
                        onChange={handleChange}
                        name="email"
                        autoComplete="email"
                        InputProps={{
                          style: { borderRadius: 8 },
                        }}
                        sx={textFieldStyles}
                        error={errorHandlers.email}
                      />
                    </Grid>

                    <Grid item xs={12}>
                      <TextField
                        required
                        fullWidth
                        name="password"
                        label={
                          errorHandlers.password && errMsg !== ""
                            ? errMsg
                            : "Password"
                        }
                        value={formValues.password}
                        type={showPassword ? "text" : "password"}
                        id="password"
                        autoComplete="new-password"
                        onChange={handleChange}
                        error={errorHandlers.password}
                        InputProps={{
                          style: { borderRadius: 8 },
                          endAdornment: (
                            <InputAdornment position="end">
                              <IconButton
                                onClick={handleTogglePassword}
                                sx={{
                                  color: "#4687BA",
                                  "&:hover": {
                                    color: "#4687BA",
                                  },
                                }}
                              >
                                {showPassword ? (
                                  <VisibilityOff />
                                ) : (
                                  <Visibility />
                                )}
                              </IconButton>
                            </InputAdornment>
                          ),
                        }}
                        sx={textFieldStyles}
                      />
                    </Grid>
                  </Grid>
                </Box>

                <Box sx={{ backgroundColor: "#4687BA" }}>
                  <LoadingButton
                    type="submit"
                    fullWidth
                    variant="contained"
                    loading={loading}
                    disabled={loading}
                    loadingIndicator="Signing in…"
                    sx={{
                      backgroundColor: "#4687BA",
                      textTransform: "capitalize",
                      borderRadius: "8px",
                      fontWeight: "500",
                      fontSize: "16px",
                      padding: "12px 10px",
                      color: "#fff !important",
                      "&:hover": {
                        backgroundColor: "rgba(70, 135, 186, 0.8)",
                      },
                    }}
                  >
                    <span>{loading ? "Signing in…" : "Sign In"}</span>
                  </LoadingButton>
                </Box>
              </Box>
            </Box>
          </Grid>
        </Box>
      </div>
    </>
  );
};

export default SignInForm;

// Custom styles for text fields in sign up
const textFieldStyles = {
  "& .MuiOutlinedInput-root": {
    "& fieldset": {
      borderColor: "#4687BA",
      "&:hover": {
        borderColor: "#4687BA",
      },
    },
    "&.Mui-focused fieldset": {
      borderColor: "#4687BA",
    },
  },
  "& .MuiInputAdornment-positionEnd": {
    cursor: "pointer",
  },
  "& .MuiFormLabel-root": {
    color: "#4687BA",
  },
  "&:hover .MuiFormLabel-root": {
    color: "#4687BA",
  },
  "&.Mui-focused .MuiFormLabel-root": {
    color: "#4687BA",
  },
  "& .MuiInputBase-input": {
    color: "#4687BA",
  },
  "&:hover .MuiInputBase-input": {
    color: "#4687BA",
  },
  "&.Mui-focused .MuiInputBase-input": {
    color: "#4687BA",
  },
};
