// src/services/api/.ts
import axios from "axios";
import Cookies from "js-cookie";
import { toast } from "sonner";
import { getEnvUrl } from "@/shared/config/env";
import { getRefreshToken } from "../utils/refreshTokenHandler";
import { withHeaders } from "@/record-management/services/api/withHeaders";

const objectiveInstance = axios.create({
  baseURL: getEnvUrl("VITE_OBJECTIVE_API_URL"),
});

// Add auth token and acting-as position context to every OKR request
objectiveInstance.interceptors.request.use((config) => {
  const token = Cookies.get("auth-token");
  if (token) {
    config.headers["Authorization"] = `Bearer ${token}`;
  }

  const contextHeaders = withHeaders();
  Object.entries(contextHeaders).forEach(([key, value]) => {
    config.headers[key] = value;
  });

  return config;
});

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

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

const skipRefreshUrls = ["/auth/login", "/auth/refresh", "auth/me"]; // Add all URLs to skip

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

    // 🔒 Skip refresh logic for specific URLs
    const shouldSkip = skipRefreshUrls.some((url) =>
      originalRequest.url?.includes(url),
    );

    if (shouldSkip) {
      return Promise.reject(error);
    }
    const rememberMe = JSON.parse(
      localStorage.getItem("rememberMe") || "false",
    );

    if (error.response?.status === 401 && !originalRequest._retry) {
      if (isRefreshing) {
        return new Promise(function (resolve, reject) {
          failedQueue.push({ resolve, reject });
        })
          .then((token) => {
            originalRequest.headers["Authorization"] = "Bearer " + token;
            return objectiveInstance(originalRequest);
          })
          .catch((err) => Promise.reject(err));
      }

      originalRequest._retry = true;
      isRefreshing = true;
      try {
        const refreshToken = Cookies.get("refresh-token") as string;

        const newToken = await getRefreshToken(refreshToken);
        const updatedToken = newToken.data.token;
        const updatedRefreshToken = newToken.data.refreshToken;
        processQueue(null, newToken.data.token);
        Cookies.set("auth-token", updatedToken);
        Cookies.set("refresh-token", updatedRefreshToken);
        originalRequest.headers["Authorization"] = `Bearer ${newToken}`;
        return objectiveInstance(originalRequest);
      } catch (err) {
        processQueue(err, null);
        if (rememberMe) {
          toast.error("Session expired", {
            description: "Please log in again.",
            duration: 4000,
          });
        }
        Cookies.remove("auth-token");
        Cookies.remove("refresh-token");
        Cookies.remove("auth-user");

        toast.error("Session expired", {
          description: "Please log in again.",
          duration: 4000,
        });

        setTimeout(() => {
          window.location.href = "/";
        }, 3000);

        return Promise.reject(err);
      } finally {
        isRefreshing = false;
      }
    }

    return Promise.reject(error);
  },
);

export default objectiveInstance;
