import axios from "axios";
import {
  getToken,
  getRefreshToken,
  setToken,
  setRefreshToken,
  removeToken,
  removeRefreshToken,
} from "./func";
import { refreshToken } from "./auth/refresh-token";
import { API_BASE_URL } from "@/config/const";

declare global {
  interface Window {
    isRefreshingToken?: boolean;
  }
}

const axiosInstance = axios.create({
  baseURL: API_BASE_URL,
  headers: { "Content-Type": "application/json" },
});

axiosInstance.interceptors.response.use(
  (response) => response,
  async (error) => {
    const originalRequest = error.config;

    if (error?.response?.status === 401 && !originalRequest._retry) {
      if (typeof window !== "undefined" && window.isRefreshingToken) {
        // Wait for the refresh to complete
        await new Promise((resolve) => {
          const checkComplete = setInterval(() => {
            if (typeof window !== "undefined" && !window.isRefreshingToken) {
              clearInterval(checkComplete);
              resolve(true);
            }
          }, 100);
        });

        return axiosInstance(originalRequest);
      }

      originalRequest._retry = true;
      if (typeof window !== "undefined") {
        window.isRefreshingToken = true;
      }

      try {
        const refreshTokenValue = await getRefreshToken();

        if (!refreshTokenValue) {
          await removeRefreshToken();
          await removeToken();
          return;
        }

        const data = await refreshToken({
          token: refreshTokenValue,
        });

        const accessToken = data?.data?.accessToken?.token;
        const refreshTokenValueNew = data?.data?.refreshToken?.token;

        if (accessToken) {
          await setToken(accessToken);

          if (refreshTokenValueNew) {
            await setRefreshToken(refreshTokenValueNew);
          }

          originalRequest.headers.Authorization = `Bearer ${accessToken}`;
          return axiosInstance(originalRequest);
        } else {
          await removeRefreshToken();
          await removeToken();
          return;
        }
      } catch (refreshError) {
        console.error("Token refresh failed:", refreshError);
        await removeToken();
        await removeRefreshToken();
        if (typeof window !== "undefined") {
          // const pathname = window.location.pathname;
          // const slug = pathname.split("/")[1];
          // window.location.href = slug ? `/${slug}` : `/`;
        }
        return Promise.reject(refreshError);
      } finally {
        if (typeof window !== "undefined") {
          window.isRefreshingToken = false;
        }
      }
    }

    return Promise.reject(error);
  }
);

axiosInstance.interceptors.request.use(async function (config) {
  const tokenValue = await getToken();
  const token = tokenValue ? tokenValue : "";

  let slug = "dmenu";
  if (typeof window !== "undefined") {
    const pathname = window.location.pathname;
    const pathParts = pathname.split("/").filter(Boolean);
    if (pathParts.length > 0) {
      slug = pathParts[0];
    }
  }

  config.headers.Authorization = "Bearer " + token;
  config.headers["X-SLUG"] = slug;

  return config;
});

export { axiosInstance as api };
