// frontend/js/services/api.js
var APIClientError = class extends Error {
  constructor(message, status, code, rawMessageFromServer) {
    super(message);
    this.name = "APIClientError";
    this.status = status;
    this.code = code;
    this.rawMessageFromServer = rawMessageFromServer;
  }
};
var apiPromiseCache = /* @__PURE__ */ new Map();
async function apiFetch(url, options = {}) {
  const isGetRequest = !options.method || options.method.toUpperCase() === "GET";
  const cacheKey = isGetRequest && !options.noCache ? url : null;
  if (cacheKey && apiPromiseCache.has(cacheKey)) {
    return apiPromiseCache.get(cacheKey);
  }
  const token = localStorage.getItem("bearerToken");
  const headers = {
    "Content-Type": "application/json",
    ...options.headers
  };
  if (token) {
    headers["Authorization"] = `Bearer ${token}`;
  }
  const requestPromise = (async () => {
    try {
      const response = await fetch(url, { ...options, headers });
      if (response.status === 401) {
        if (cacheKey) apiPromiseCache.delete(cacheKey);
        localStorage.removeItem("bearerToken");
        if (window.location.pathname !== "/login") {
          window.location.href = "/login?error=\u4F1A\u8BDD\u5DF2\u8FC7\u671F\uFF0C\u8BF7\u91CD\u65B0\u767B\u5F55\u3002";
        }
        throw new APIClientError("Unauthorized", 401, "UNAUTHORIZED", "Session expired or token is invalid.");
      }
      if (!response.ok) {
        let errorData = null;
        let rawMessage = "";
        try {
          rawMessage = await response.text();
          if (rawMessage) {
            errorData = JSON.parse(rawMessage);
          }
        } catch (e) {
          errorData = { error: { code: "UNKNOWN_FORMAT", message: rawMessage || response.statusText } };
        }
        const code = errorData?.error?.code || "UNKNOWN_ERROR";
        const messageFromServer = errorData?.error?.message || rawMessage || "No message provided by server.";
        const error = new APIClientError(
          `API request failed: ${response.status}`,
          response.status,
          code,
          messageFromServer
        );
        throw error;
      }
      return response;
    } catch (error) {
      if (cacheKey) apiPromiseCache.delete(cacheKey);
      throw error;
    }
  })();
  if (cacheKey) {
    apiPromiseCache.set(cacheKey, requestPromise);
  }
  return requestPromise;
}
async function apiFetchJson(url, options = {}) {
  try {
    const response = await apiFetch(url, options);
    const clonedResponse = response.clone();
    const jsonData = await clonedResponse.json();
    return jsonData;
  } catch (error) {
    throw error;
  }
}

export {
  apiFetch,
  apiFetchJson
};
