import { AxiosError, AxiosInstance, InternalAxiosRequestConfig } from "axios";

/**
 * Configura interceptores para una instancia de Axios.
 *
 * @param axiosInstance - Instancia de Axios que será modificada.
 * @param getAccessToken - Función que devuelve el token JWT actual.
 * @param onAuthError - Función opcional que se ejecuta ante errores de autenticación (status 401).
 */
export const setupInterceptors = (
  axiosInstance: AxiosInstance,
  getAccessToken: () => string | null,
  onAuthError?: () => void
) => {
  axiosInstance.interceptors.request.use(
    (config: InternalAxiosRequestConfig) => {
      const token = getAccessToken();
      if (token && config.headers) {
        config.headers.Authorization = `Bearer ${token}`;
      }
      return config;
    },
    (error: unknown) => {
      return Promise.reject(error);
    }
  );

  axiosInstance.interceptors.response.use(
    (response) => response,
    (error: AxiosError) => {
      // 🔴 Transformamos SIEMPRE el error antes de propagarlo
      const normalized = normalizeAxiosError(error);
      return Promise.reject(normalized);

      /*if (error.response?.status === 401 && onAuthError) {
        onAuthError();
      } */
    }
  );

  return axiosInstance;
};

/**
 * Normaliza errores de Axios en un objeto estándar de Error
 * con propiedades extra opcionales (status, raw).
 */
function normalizeAxiosError(error: AxiosError): Error {
  let normalizedError: Error;

  if (error.response?.data) {
    const data: any = error.response.data;

    // Intentamos localizar mensaje en campos comunes
    const msg =
      data.message ??
      (Array.isArray(data.errors) && data.errors[0]?.msg) ??
      error.message ??
      "Unknown server error";

    normalizedError = new Error(msg);

    // Añadimos metadatos útiles
    (normalizedError as any).status = error.response.status;
    (normalizedError as any).raw = data;
  } else {
    normalizedError = new Error(error.message || "Unknown network error");
    (normalizedError as any).status = error.response?.status ?? 0;
  }

  return normalizedError;
}
