import { useTranslation } from "react-i18next";
import * as yup from "yup";
import "yup-phone";
import { useState } from "react";
import FormBox from "../../../components/form-box/form-box.component";
import {
  Alert,
  Collapse,
  IconButton,
  useTheme,
} from "@mui/material";
import FormInput from "../../../components/form-input/form-input.component";
import Icons from "../../../assets/icons";
import { PHONE_NUMBER_LOGIN_MUTATION } from "../../../api/queries/auth.queries";
import CustomTelInput from "../../../components/tel-input/tel-Input.component";
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 PhoneNumberLogin = () => {
  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 PhoneNumberLoginSchema = yup.object().shape({
    phoneNumber: yup
      .string()
      .nullable()
      .test(
        "is-valid-phone",
        t("authentication.login.invalid_no_phone"),
        (value) => {
          if (value === null || value === "") {
            return true;
          }
          try {
            const phoneUtil =
              require("google-libphonenumber").PhoneNumberUtil.getInstance();
            const number = phoneUtil.parseAndKeepRawInput(value, "");
            return phoneUtil.isValidNumber(number);
          } catch (error) {
            return false;
          }
        }
      )
      .required(t("authentication.login.phone_no_required")),
    password: yup
      .string()
      .required(t("authentication.login.password_required")),
  });
  const [emailLoginMutation] = useApolloMutation(PHONE_NUMBER_LOGIN_MUTATION);
  const formik = useFormik({
    initialValues: {
      phoneNumber: "",
      password: "",
    },
    validationSchema: PhoneNumberLoginSchema,
    onSubmit: async (values, { setSubmitting }) => {
      try {
        await onSubmitPhoneNumberLogin(values);
        setSubmitting(false);
      } catch (error) {
        setSubmitting(false);
      }
    },
    enableReinitialize: true,
    validateOnChange: true,
    validateOnBlur: false,
  });
  const onSubmitPhoneNumberLogin = async (event) => {
    event.preventDefault();
    try {
      const { password } = formik.values;
      const phoneNumber = formik.values.phoneNumber.replace(/\s/g, "");
      formik.setTouched({ phoneNumber: true, password: true });
      PhoneNumberLoginSchema.validateSync(
        { phoneNumber, password },
        { abortEarly: false }
      );
      let type = "phone";
      let loginId = phoneNumber
      const response = await emailLoginMutation({
        variables: { password, phoneNumber, type, loginId},
      });
      setLoading(true);
      localStorage.setItem(
        "userData",
        JSON.stringify(response?.data?.login?.user)
      );
      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();
      } 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);
  };
  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) => onSubmitPhoneNumberLogin(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",
        }}
      >
        <CustomTelInput
          {...formik.getFieldProps("phoneNumber")}
          name={"phoneNumber"}
          label={t('authentication.login.phone-label')}
          error={
            formik.touched["phoneNumber"] &&
            Boolean(formik.errors["phoneNumber"])
          }
          helperText={
            formik.touched["phoneNumber"] && formik.errors["phoneNumber"]
          }
          value={formik.values["phoneNumber"]}
          onChange={(value) => formik.setFieldValue("phoneNumber", value)}
        />
        <FormInput
          {...formik.getFieldProps("password")}
          name="password"
          required
          fullWidth
          label={t("authentication.login.password")}
          type="password"
          error={
            formik.touched["password"] && Boolean(formik.errors["password"])
          }
          helperText={formik.touched["password"] && formik.errors["password"]}
          value={
            formik.values && formik.values["password"]
              ? formik.values["password"]
              : ""
          }
          icon={<Icons.LOCK style={{ margin: "0px 5px" }} />}
        />
 
      </FormBox>

      {
        loading && (
          <div>
          <Loader/>
          </div>
        )
      }
      <Toaster
        open={openSuccess}
        title={"Congratulations!"}
        description={"You’ve logged in successfully"}
        handleClose={handleCloseSuccess}
        icon={<Icons.SUCCESS style={{ margin: "15px 0" }} />}
      />
    </>
  );
};
export default PhoneNumberLogin;
