import axios, { type AxiosRequestConfig } from "axios";
import { AUTH_FLAG } from "@/hooks/useAuth";

export const privateApi = axios.create({
  withCredentials: true,
  baseURL: '',
});

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

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

privateApi.interceptors.response.use(
  (res) => res,
  async (error) => {
    const original = error.config;

    if (error.response?.status === 400 && error.response?.data) {
      const data = error.response.data;
      if (typeof data === 'object' && !Array.isArray(data)) {
        const firstKey = Object.keys(data)[0];
        if (firstKey && Array.isArray(data[firstKey]) && data[firstKey].length > 0) {
          error.message = data[firstKey][0];
        }
      }
    }

    if ((error.response?.status === 401 || error.response?.status === 403) && !original._retry) {
      if (original.url?.includes("/api/account/logout/")) {
        return Promise.reject(error);
      }

      if (error.response?.data?.code === "user_not_found") {
        processQueue(error);
        isRefreshing = false;
        localStorage.removeItem(AUTH_FLAG);
        window.location.href = "/social/login";
        return Promise.reject(error);
      }

      if (original.url?.includes("/api/account/token/refresh/")) {
        processQueue(error);
        isRefreshing = false;
        localStorage.removeItem(AUTH_FLAG);
        try {
          await privateApi.post("/api/account/logout/");
        } catch {
          // cookies may already be expired
        }
        window.location.href = "/social/login";
        return Promise.reject(error);
      }

      if (isRefreshing) {
        return new Promise((resolve, reject) => {
          failedQueue.push({ resolve, reject });
        })
          .then(() => privateApi(original))
          .catch((err) => Promise.reject(err));
      }

      original._retry = true;
      isRefreshing = true;

      try {
        await privateApi.post("/api/account/token/refresh/");
        processQueue();
        return privateApi(original);
      } catch (refreshError: any) {
        processQueue(refreshError);
        // Refresh failed for any reason (400 missing cookie, 401 expired) — clear auth and redirect
        localStorage.removeItem(AUTH_FLAG);
        window.location.href = "/social/login";
        return Promise.reject(refreshError);
      } finally {
        isRefreshing = false;
      }
    }

    return Promise.reject(error);
  }
);

export const privateMutator = async <T>(config: AxiosRequestConfig): Promise<T> => {
  if (config.data instanceof FormData) {
    delete config.headers?.['Content-Type'];
  }
  const response = await privateApi.request<T>(config);
  return response.data;
};
