import FormBox from "../../../components/form-box/form-box.component";
import FormInput from "../../../components/form-input/form-input.component";
import { useTranslation } from "react-i18next";
import Icons from "../../../assets/icons";
import * as yup from "yup";
import { useState } from "react";
import {
  Alert,
  Box,
  Collapse,
  IconButton,
  useTheme,
} from "@mui/material";
import { EMAIL_LOGIN_MUTATION } from "../../../api/queries/auth.queries";
import Toaster from "../../../components/toaster/toaster.component";
import { useDispatch } from "react-redux";
import { login, logout } from "../../../store/slices/authSlice";
import * as ROUTES from "../../../constants/routes";
import { useFormik } from "formik";
import { useMutation as useApolloMutation } from "@apollo/client";
import { useMutation as useReactQueryMutation } from "react-query";
import { VERIFY_TOKEN, REFRESH_TOKEN } from "../../../api/services/jwt.service";
import { useNavigate } from "react-router-dom";
import Loader from "../../../components/loader/Loader";

const EmailLogin = () => {
  const { t, i18n } = useTranslation("common");
  const theme = useTheme();
  const dispatch = useDispatch();
  const navigate = useNavigate();
  const [loading, setLoading] = useState(false)
  const [openSuccess, setOpenSuccess] = useState(false);
  const [openAlert, setOpenAlert] = useState(true);
  const [errorMessage, setErrorMessage] = useState("");
  const EmailLoginSchema = yup.object().shape({
    email: yup
      .string()
      .email(t("authentication.login.email_format"))
      .required(t("authentication.login.email_required")),
    password: yup
      .string()
      .required(t("authentication.login.password_required")),
  });
  const [emailLoginMutation] = useApolloMutation(EMAIL_LOGIN_MUTATION);
  const onSubmitEmailLogin = async (event) => {
    event.preventDefault();
    try {
      const { password, email } = formik.values;
      formik.setTouched({ email: true, password: true });
      EmailLoginSchema.validateSync({ email, password }, { abortEarly: false });
      let type = "email";
      let loginId = email;
      const response = await emailLoginMutation({
        variables: { password, email, type, loginId },
      });
      setLoading(true);
      localStorage.setItem(
        "userData",
        JSON.stringify(response?.data?.login?.user)
      );
      localStorage.setItem("isLoggedIn", true);
      localStorage.setItem("token", response?.data?.login?.token);
      localStorage.setItem(
        "refreshToken",
        response?.data?.login?.refresh_token
      );

      verifyToken.mutate(response.data?.login.token);
    } catch (error) {
      if (error.name === "ValidationError") {
        const validationErrors = {};
        error.inner.forEach((validationError) => {
          validationErrors[validationError.path] = validationError.message;
        });
        formik.setErrors(validationErrors);
      } else {
        const { message } = error;
        setErrorMessage(message);
        setOpenAlert(true);
      }
    }
  };
  const verifyToken = useReactQueryMutation(VERIFY_TOKEN, {
    async onSuccess(token) {
      if (token["verified"]) {
        setLoading(false);
        setOpenSuccess(true);
        setTimeout(() => dispatch(login()), 2000);
      
        formik.resetForm();
        formik.submitForm();
        setTimeout(() => navigate(ROUTES.HOME), 2000);
      } else {
        const rToken = localStorage.getItem("refreshToken");
        refreshToken.mutate(rToken);
      }
    },
    onError(error) {
      console.log(error);
    },
  });
  const refreshToken = useReactQueryMutation(REFRESH_TOKEN, {
    async onSuccess(response) {
      if (response.data === "Invalid Token") {
        setTimeout(() => dispatch(logout()), 2000);
        localStorage.clear();
        navigate(ROUTES.LOGIN_METHODS);
      } else {
        localStorage.setItem("token", response.data.token);
        localStorage.setItem("refreshToken", response.data.refresh_token);
      }
    },
    onError(error) {
      console.log(error);
    },
  });
  const handleCloseSuccess = () => {
    setOpenSuccess(false);
  };
  const handleClose = () => {
    setOpenAlert(false);
  };
  const formik = useFormik({
    initialValues: {
      email: "",
      password: "",
    },
    validationSchema: EmailLoginSchema,
    onSubmit: async (values, { setSubmitting }) => {
      try {
        await onSubmitEmailLogin(values);
        localStorage.setItem("isLoggedIn", true);
        setSubmitting(false);
      } catch (error) {
        setSubmitting(false);
      }
    },
    enableReinitialize: true,
    validateOnChange: true,
    validateOnBlur: false,
  });
  return (
    <>
      {errorMessage && (
        <Collapse in={openAlert}>
          <Alert
            severity="error"
            action={
              <IconButton
                aria-label="close"
                color="inherit"
                size="small"
                onClick={handleClose}
              >
                <Icons.CLOSE />
              </IconButton>
            }
          >
            {errorMessage}
          </Alert>
        </Collapse>
      )}
      <FormBox
        onSubmit={(event) => onSubmitEmailLogin(event)}
        sx={{ display: "grid" }}
        submitValue={t("authentication.login.login")}
        submitStyle={{
          borderRadius: "8px",
          border: `1px solid ${theme.palette.primary.main}`,
          background: theme.palette.primary.orange,
          color: theme.palette.secondary.main,
          textTransform: "capitalize",
          margin: "25px 0",
        }}
      >
        <Box margin={"10px 0"}>
          <FormInput
            {...formik.getFieldProps("email")}
            name="email"
            required
            fullWidth
            placeholder={t("authentication.login.social.email")}
            type="email"
            error={formik.touched["email"] && Boolean(formik.errors["email"])}
            helperText={formik.touched["email"] && formik.errors["email"]}
            label={t('authentication.login.email-label')}
            value={
              formik.values && formik.values["email"]
                ? formik.values["email"]
                : ""
            }
            icon={<Icons.MAIL style={{ margin: "0px 5px" }} />}
          />
        </Box>
        <Box margin={"10px 0"}>
          <FormInput
            {...formik.getFieldProps("password")}
            name="password"
            required
            fullWidth
            placeholder={t("authentication.login.password")}
            type="password"
            error={
              formik.touched["password"] && Boolean(formik.errors["password"])
            }
            helperText={formik.touched["password"] && formik.errors["password"]}
            label={t('authentication.login.password-label')}
            value={
              formik.values && formik.values["password"]
                ? formik.values["password"]
                : ""
            }
            icon={<Icons.LOCK style={{ margin: "0px 5px" }} />}
          />
        </Box>
      </FormBox>

      {
        loading && (
          <div>
          <Loader/>
          </div>
        )
      }
      <Toaster
        open={openSuccess}
        title={`${t("common.congratulations")}!`}
        description={t("authentication.login.login_success")}
        handleClose={handleCloseSuccess}
        icon={<Icons.SUCCESS style={{ margin: "15px 0" }} />}
      />
    </>
  );
};
export default EmailLogin;
