import axios from "axios";
import {
  getToken,
  getRefreshToken,
  setToken,
  setRefreshToken,
  removeToken,
  removeRefreshToken,
} from "./func";
import { refreshToken } from "@/pages/auth/service/AuthService";

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

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

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

    if (error?.response?.status === 401 && !originalRequest._retry) {
      // اگر refresh token منقضی شده باشد، دیگر تلاش نکن
      if (window.isRefreshTokenExpired) {
        return Promise.reject(error);
      }

      // بررسی کن که آیا خطا از refresh endpoint است
      const isRefreshEndpoint = originalRequest?.url?.includes(
        "/admin/auth/refresh",
      );

      // اگر خطا از refresh endpoint است، refresh token منقضی شده
      if (isRefreshEndpoint) {
        window.isRefreshTokenExpired = true;
        await removeToken();
        await removeRefreshToken();
        window.location.href = `/`;
        return Promise.reject(error);
      }

      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) {
          window.isRefreshTokenExpired = true;
          await removeRefreshToken();
          await removeToken();
          window.location.href = `/`;
          return Promise.reject(error);
        }
        const data = await refreshToken({
          refreshToken: refreshTokenValue,
        });

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

          // Reset expired flag if refresh was successful
          window.isRefreshTokenExpired = false;

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

        // بررسی کن که آیا خطا از refresh endpoint است
        const isRefreshError = (refreshError as {
          response?: { config?: { url?: string }; status?: number };
        })?.response?.config?.url?.includes("/admin/auth/refresh");
        const is401Error =
          (refreshError as { response?: { status?: number } })?.response
            ?.status === 401;

        // اگر refresh token خودش 401 خورده، آن را منقضی شده علامت بزن
        if (isRefreshError || is401Error) {
          window.isRefreshTokenExpired = true;
        }

        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;
