import axios from "axios";
import Cookies from "js-cookie";
import { getEnvUrl } from "@/shared/config/env";
import { getRefreshToken } from "../utils/refreshTokenHandler";
import {
  getRememberMePreference,
  setAuthCookies,
} from "../utils/authPersistence";
import { handleSessionExpiry } from "./sessionExpiry";

// Record backend is optional in this deployment — no warning when unset; the
// module's screens are simply non-functional without it.
const recordAxiosInstance = axios.create({
  baseURL: getEnvUrl("VITE_RECORD_API_URL", false),
});

// Attach auth token and CSRF defence header to every request
recordAxiosInstance.interceptors.request.use((config) => {
  const token = Cookies.get("auth-token");
  if (token) {
    config.headers["Authorization"] = `Bearer ${token}`;
  }
  config.headers["X-Requested-With"] = "XMLHttpRequest";
  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/refresh-token",
  "auth/me",
];

recordAxiosInstance.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);
    }

    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 recordAxiosInstance(originalRequest);
          })
          .catch((err) => Promise.reject(err));
      }

      originalRequest._retry = true;
      isRefreshing = true;

      try {
        const refreshToken = Cookies.get("refresh-token");
        if (!refreshToken) {
          throw new Error("missing-refresh-token");
        }
        const rememberMe = getRememberMePreference();

        const newToken = await getRefreshToken(refreshToken);
        const updatedToken = newToken.data.token;
        const updatedRefreshToken = newToken.data.refreshToken;
        processQueue(null, newToken.data.token);
        setAuthCookies({
          token: updatedToken,
          refreshToken: updatedRefreshToken,
          rememberMe,
        });
        originalRequest.headers["Authorization"] = `Bearer ${updatedToken}`;
        return recordAxiosInstance(originalRequest);
      } catch (err) {
        processQueue(err, null);
        handleSessionExpiry();
        return Promise.reject(err);
      } finally {
        isRefreshing = false;
      }
    }

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

export default recordAxiosInstance;
