// services/auth/Axiosinstance.js
import axios from "axios";
import { useAuthStore } from "../../store/authstore";

export const Axiosinstance = axios.create({
  baseURL: "https://netnest.org/api/",
  withCredentials: false,
  // ✅ مهم: Content-Type را اینجا قفل نکن
  // headers: { "Content-Type": "application/json" },
});

// ----------------- کنترل رفرش همزمان -----------------
let isRefreshing = false;
let failedQueue = [];

const processQueue = (error, newAccessToken = null) => {
  failedQueue.forEach((prom) => {
    if (error) prom.reject(error);
    else prom.resolve(newAccessToken);
  });
  failedQueue = [];
};

const isAuthRelatedUrl = (url = "") => {
  return url.includes("auth/token/refresh/") || url.includes("accounts/logout/");
};

const isFormData = (v) => {
  if (!v) return false;
  // FormData در مرورگر
  if (typeof FormData !== "undefined" && v instanceof FormData) return true;
  // fallback
  return typeof v?.append === "function" && String(v?.[Symbol.toStringTag] || "").toLowerCase() === "formdata";
};

// ----------------- Request Interceptor -----------------
Axiosinstance.interceptors.request.use(
  (config) => {
    const token = useAuthStore.getState().accessToken;

    config.headers = config.headers || {};

    // ✅ Auth header
    if (token) config.headers.Authorization = `Bearer ${token}`;
    else delete config.headers.Authorization;

    // ✅ اگر FormData بود، Content-Type رو حذف کن تا Axios خودش boundary درست بذاره
    if (isFormData(config.data)) {
      delete config.headers["Content-Type"];
      delete config.headers["content-type"];
      // بهتر: Accept رو بگذار
      config.headers["Accept"] = "application/json";
    } else {
      // ✅ برای JSON درخواست‌ها Content-Type رو ست کن
      // (فقط وقتی کاربر خودش چیز دیگری نگذاشته)
      if (!config.headers["Content-Type"] && !config.headers["content-type"]) {
        config.headers["Content-Type"] = "application/json";
      }
      config.headers["Accept"] = config.headers["Accept"] || "application/json";
    }

    return config;
  },
  (error) => Promise.reject(error)
);

// ----------------- Response Interceptor -----------------
Axiosinstance.interceptors.response.use(
  (response) => response,
  async (error) => {
    const originalRequest = error?.config || {};
    const status = error?.response?.status;
    const url = originalRequest?.url || "";

    // اگر اصلاً response نداریم (network/cors/timeout) → رفرش نزن
    if (!error?.response) return Promise.reject(error);

    // روی refresh/logout اصلاً کاری نکن
    if (isAuthRelatedUrl(url)) return Promise.reject(error);

    // فقط وقتی Authorization وجود داشته
    const hadAuthHeader =
      !!originalRequest?.headers?.Authorization ||
      !!Axiosinstance.defaults?.headers?.common?.Authorization;

    const shouldTryRefresh = status === 401 && hadAuthHeader && !originalRequest._retry;
    if (!shouldTryRefresh) return Promise.reject(error);

    if (isRefreshing) {
      return new Promise((resolve, reject) => {
        failedQueue.push({ resolve, reject });
      })
        .then((newAccessToken) => {
          if (newAccessToken) {
            originalRequest.headers = originalRequest.headers || {};
            originalRequest.headers.Authorization = `Bearer ${newAccessToken}`;
          }
          return Axiosinstance(originalRequest);
        })
        .catch((err) => Promise.reject(err));
    }

    originalRequest._retry = true;
    isRefreshing = true;

    const { refreshToken, setTokens, clearTokens } = useAuthStore.getState();

    if (!refreshToken) {
      clearTokens();
      isRefreshing = false;
      processQueue(null, null);
      return Promise.reject(error);
    }

    try {
      // refresh را با axios خام بزن
      const refreshResponse = await axios.post(
        "https://netnest.org/api/auth/token/refresh/",
        { refresh: refreshToken },
        { headers: { "Content-Type": "application/json", Accept: "application/json" } }
      );

      const newAccess = refreshResponse?.data?.access;
      const newRefresh = refreshResponse?.data?.refresh ?? refreshToken;

      if (!newAccess) throw new Error("No access token in refresh response");

      setTokens({ accessToken: newAccess, refreshToken: newRefresh });

      Axiosinstance.defaults.headers.common.Authorization = `Bearer ${newAccess}`;

      processQueue(null, newAccess);

      originalRequest.headers = originalRequest.headers || {};
      originalRequest.headers.Authorization = `Bearer ${newAccess}`;
      return Axiosinstance(originalRequest);
    } catch (refreshError) {
      processQueue(refreshError, null);
      clearTokens();
      return Promise.reject(refreshError);
    } finally {
      isRefreshing = false;
    }
  }
);
