import axios, { AxiosError, InternalAxiosRequestConfig } from "axios";
import { router } from "expo-router";

interface RetryableRequestConfig extends InternalAxiosRequestConfig {
  _retry?: boolean;
}

interface QueueItem {
  resolve: (value?: any) => void;
  reject: (reason?: any) => void;
}

const apiClient = axios.create({
  baseURL: "https://api.plania.ir",
  timeout: 15000,
  withCredentials: true,
});

let isRefreshing = false;
let failedQueue: QueueItem[] = []; 

const processQueue = (error: AxiosError | null, token: string | null = null) => {
  failedQueue.forEach((prom) => {
    if (error) {
      prom.reject(error);
    } else {
      prom.resolve(token);
    }
  });
  failedQueue = [];
};

apiClient.interceptors.response.use(
  (response) => response,
  async (error: AxiosError) => {
    const originalRequest = error.config as RetryableRequestConfig;

    if (error.response?.status !== 401 || originalRequest._retry) {
      return Promise.reject(error);
    }

    originalRequest._retry = true;

    if (!isRefreshing) {
      isRefreshing = true;
      try {
        await apiClient.get("/api/auth/token/refresh/");
        processQueue(null);
        return apiClient(originalRequest);
      } catch (refreshError) {
        console.log("asdf")
        processQueue(refreshError as AxiosError);
        if (router && typeof router.push === "function") {
          router.push("/(auth)/login");
        }
        return Promise.reject(refreshError);
      } finally {
        isRefreshing = false;
      }
    } else {
      return new Promise((resolve, reject) => {
        failedQueue.push({ resolve, reject });
      })
        .then(() => apiClient(originalRequest))
        .catch((err) => Promise.reject(err));
    }
  }
);

export default apiClient;