import axios from "axios";
import {
  getToken,
  getRefreshToken,
  setToken,
  setRefreshToken,
  removeToken,
  removeRefreshToken,
} from "./func";
import type {
  ApiResponse,
  RefreshTokenResponse,
} from "../pages/auth/types/AuthTypes";
import { refreshToken } from "../pages/auth/service/AuthService";

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

const axiosInstance = axios.create({
  baseURL: import.meta.env.VITE_BASE_URL,
});

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

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

      originalRequest._retry = true;
      window.isRefreshingToken = true;

      try {
        const refreshTokenValue = await getRefreshToken();
        if (!refreshTokenValue) {
          await removeRefreshToken();
          await removeToken();
          window.location.href = `/`;
          return;
        }
        const data: ApiResponse<RefreshTokenResponse> = await refreshToken({
          token: refreshTokenValue,
        });

        if (data?.results?.data?.accessToken?.token) {
          await setToken(data?.results?.data?.accessToken?.token);
          if (data?.results?.data?.refreshToken?.token) {
            await setRefreshToken(data?.results?.data?.refreshToken?.token);
          }

          originalRequest.headers.Authorization = `Bearer ${data.results.data.accessToken.token}`;
          return axiosInstance(originalRequest);
        } else {
          await removeRefreshToken();
          await removeToken();
          window.location.href = `/`;
          return;
        }
      } catch (refreshError) {
        console.error("Token refresh failed:", refreshError);
        await removeToken();
        await removeRefreshToken();
        // window.location.href = `/`;
        return Promise.reject(refreshError);
      } finally {
        window.isRefreshingToken = false;
      }
    }
    return Promise.reject(error);
  }
);

axiosInstance.interceptors.request.use(async function (config) {
  const tokenValue = await getToken();
  const token = tokenValue ? tokenValue : "";
  config.headers.Authorization = "Bearer " + token;
  return config;
});

export default axiosInstance;
