import axios, { AxiosError } from "axios";
import { API_URL } from "@/constants";
import { ServerErrorsObject } from "@/types";

let isRefreshing = false;
let failedQueue: {
  resolve: (value?: unknown) => void;
  reject: (reason?: unknown) => void;
}[] = [];

const processQueue = (error: unknown) => {
  failedQueue.forEach((promise) => {
    if (error) promise.reject(error);
    else promise.resolve(null);
  });
  failedQueue = [];
};

const privateAxios = axios.create({
  baseURL: API_URL,
  withCredentials: true,
});
privateAxios.interceptors.response.use(
  (response) => response,
  async (error) => {

      const err = error as AxiosError<ServerErrorsObject>;

    const originalRequest = error.config;

    if (err.response?.status !== 401 || (err?.response?.data?.status ===403 && err?.response?.data?.error?.message ==="denied") || originalRequest?._retry) {
      return Promise.reject(error);
    }

    if (isRefreshing) {
      return new Promise((resolve, reject) => {
        failedQueue.push({ resolve, reject });
      }).then(() => privateAxios(originalRequest));
    }

    originalRequest._retry = true;
    isRefreshing = true;

    try {
      await axios.post(
        `${API_URL}/auth/refresh-token`,
        {},
        { withCredentials: true }
      );

      processQueue(null);
      return privateAxios(originalRequest);
    } catch (err) {
      processQueue(err);
      window.location.href = "/login";
      return Promise.reject(err);
    } finally {
      isRefreshing = false;
    }
  }
);

export default privateAxios;
