import React, { useState } from "react";
import PropTypes from "prop-types";
import { createContext, useEffect, useReducer } from "react";
import axios from "axios";
// import { useMutation } from "@tanstack/react-query";
// third-party
import { Chance } from "chance";
import jwtDecode from "jwt-decode";
import { enqueueSnackbar } from "notistack";
import { useSelector } from "react-redux";

// reducer - state management
import { LOGIN, LOGOUT } from "store/reducers/actions";
import authReducer from "store/reducers/auth";

// project import
import Loader from "components/Loader";
// import axios from 'utils/axios';

const chance = new Chance();

// constant
const initialState = {
  // isLoggedIn: false,
  // isInitialized: false,
  // user: null
  isLoggedIn: true,
  isInitialized: true,
  user: {
    firstname: "",
    lastname: "",
  },
};

// const verifyToken = (serviceToken) => {
//   if (!serviceToken) {
//     return false;
//   }
//   const decoded = jwtDecode(serviceToken);
//   /**
//    * Property 'exp' does not exist on type '<T = unknown>(token: string, options?: JwtDecodeOptions | undefined) => T'.
//    */
//   return decoded.exp > Date.now() / 1000;
// };

const setSession = (serviceToken) => {
  if (serviceToken) {
    localStorage.setItem("serviceToken", serviceToken);
    axios.defaults.headers.common.Authorization = `Bearer ${serviceToken}`;
  } else {
    localStorage.removeItem("serviceToken");
    delete axios.defaults.headers.common.Authorization;
  }
};

// ==============================|| JWT CONTEXT & PROVIDER ||============================== //

const JWTContext = createContext(null);

export const JWTProvider = ({ children }) => {
  // console.log("children", children);
  const [state, dispatch] = useReducer(authReducer, initialState);
  const [email, setEmail] = useState("");
  const [password, setPassword] = useState("");
  const fcmtoken = useSelector((state) => state.fcm);

  useEffect(() => {
    const init = async () => {
      try {
        let name = window.localStorage.getItem("ne-user");
        // const serviceToken = window.localStorage.getItem('serviceToken');
        //     if (serviceToken && verifyToken(serviceToken)) {
        //       setSession(serviceToken);
        //       const response = await axios.get('/api/account/me');
        //       const { user } = response.data;
        //       dispatch({
        //         type: LOGIN,
        //         payload: {
        //           isLoggedIn: true,
        //           user
        //         }
        //       });
        //     } else {
        //       dispatch({
        //         type: LOGOUT
        //       });
        //     }
        if (name) {
          dispatch({
            type: LOGIN,
            payload: {
              isLoggedIn: true,
              user: {
                firstname: "",
                lastname: "",
                name: "name",
              },
            },
          });
        } else {
          dispatch({
            type: LOGOUT,
          });
        }
      } catch (err) {
        console.error(err);
        dispatch({
          type: LOGOUT,
        });
      }
    };

    init();
  }, []);

  const login = async (email, password) => {
    // const response = await axios.post('/api/account/login', { email, password });
    // const { serviceToken, user } = response.data;
    // setSession(serviceToken);

    await axios
      // .post(`https://jupiter.nearle.app/live/api/v1/users/admin/login`, {
      .post(`${process.env.REACT_APP_URL}/users/admin/login`, {
        authname: email,
        password: password,
        configid: 3,
        userfcmtoken: fcmtoken?.token,
      })
      .then((res) => {
        console.log(res.data);
        if (res.data.status) {
          // localStorage.setItem("user", res.data.userinfo.firstname);
          enqueueSnackbar("Login Successful", {
            variant: "success",
            anchorOrigin: { vertical: "top", horizontal: "right" },
            autoHideDuration: 1000,
          });

          dispatch({
            type: LOGIN,
            payload: {
              isLoggedIn: true,
              user: {
                firstname: "first",
                lastname: "name",
                name: res.data.details.username,
              },
            },
          });
          window.localStorage.setItem("ne-user", res.data.details.firstname);
          window.localStorage.setItem("ne-userid", res.data.details.userid);
          window.localStorage.setItem("ne-roleid", res.data.details.roleid);
          window.localStorage.setItem("ne-configid", res.data.details.configid);
          window.localStorage.setItem(
            "ne-appId",
            res.data.details.applocationid
          );
        } else {
          enqueueSnackbar("No user found", {
            variant: "error",
            anchorOrigin: { vertical: "top", horizontal: "right" },
            autoHideDuration: 1000,
          });
        }
      })
      .catch((err) => {
        console.log(err);
        if (err.response.data.message == "No user found") {
          enqueueSnackbar("No user found", {
            variant: "error",
            anchorOrigin: { vertical: "top", horizontal: "right" },
            autoHideDuration: 1000,
          });
        }
      });
  };

  const register = async (email, password, firstName, lastName) => {
    // todo: this flow need to be recode as it not verified
    const id = chance.bb_pin();
    const response = await axios.post("/api/account/register", {
      id,
      email,
      password,
      firstName,
      lastName,
    });
    let users = response.data;

    if (
      window.localStorage.getItem("users") !== undefined &&
      window.localStorage.getItem("users") !== null
    ) {
      const localUsers = window.localStorage.getItem("users");
      users = [
        ...JSON.parse(localUsers),
        {
          id,
          email,
          password,
          name: `${firstName} ${lastName}`,
        },
      ];
    }

    window.localStorage.setItem("users", JSON.stringify(users));
  };

  const logout = () => {
    localStorage.clear();
    setSession(null);
    dispatch({ type: LOGOUT });
  };

  const resetPassword = async () => {};

  const updateProfile = () => {};

  if (state.isInitialized !== undefined && !state.isInitialized) {
    return <Loader />;
  }

  return (
    <JWTContext.Provider
      value={{
        ...state,
        login,
        logout,
        register,
        resetPassword,
        updateProfile,
      }}
    >
      {children}
    </JWTContext.Provider>
  );
};

JWTProvider.propTypes = {
  children: PropTypes.node,
};

export default JWTContext;
