var u = Object.defineProperty, f = (n, e, t) => e in n ? u(n, e, { enumerable: !0, configurable: !0, writable: !0, value: t }) : n[e] = t, d = (n, e, t) => f(n, typeof e != "symbol" ? e + "" : e, t);
class p {
  constructor(e) {
    d(this, "config"), d(this, "requestInterceptors", []), d(this, "responseInterceptors", []), d(this, "errorHandlers", []), this.config = e;
  }
  // Configuration methods
  setConfig(e) {
    this.config = { ...this.config, ...e };
  }
  setOrganizationContext(e) {
    this.config.organizationId = e;
  }
  clearOrganizationContext() {
    delete this.config.organizationId;
  }
  // Interceptor methods
  addRequestInterceptor(e) {
    this.requestInterceptors.push(e);
  }
  addResponseInterceptor(e) {
    this.responseInterceptors.push(e);
  }
  addErrorHandler(e) {
    this.errorHandlers.push(e);
  }
  // Main request method
  async request(e, t = {}) {
    const s = this.buildUrl(e, t.params);
    let r = this.buildRequestConfig(t);
    for (const o of this.requestInterceptors)
      r = await o(r);
    try {
      let i = await this.executeRequest(s, r);
      for (const a of this.responseInterceptors)
        i = await a(i);
      return await this.parseResponse(i);
    } catch (o) {
      const i = this.createAPIError(o);
      for (const a of this.errorHandlers)
        a(i);
      throw i;
    }
  }
  // Convenience methods
  async get(e, t) {
    return this.request(e, { ...t, method: "GET" });
  }
  async post(e, t, s) {
    return this.request(e, { ...s, method: "POST", body: t });
  }
  async put(e, t, s) {
    return this.request(e, { ...s, method: "PUT", body: t });
  }
  async patch(e, t, s) {
    return this.request(e, { ...s, method: "PATCH", body: t });
  }
  async delete(e, t) {
    return this.request(e, { ...t, method: "DELETE" });
  }
  // Private helper methods
  buildUrl(e, t) {
    const s = new URL(e, this.config.baseUrl);
    if (t)
      for (const [r, o] of Object.entries(t))
        o != null && s.searchParams.set(r, String(o));
    return s.toString();
  }
  buildRequestConfig(e) {
    const t = {
      "Content-Type": "application/json",
      ...this.config.headers,
      ...e.headers
    };
    return this.config.apiKey ? t.Authorization = `Bearer ${this.config.apiKey}` : this.config.publishableKey && (t["X-Publishable-Key"] = this.config.publishableKey), (e.organizationId || this.config.organizationId) && (t["X-Organization-Id"] = e.organizationId || this.config.organizationId), {
      method: "GET",
      timeout: this.config.timeout || 3e4,
      retries: this.config.retries || 3,
      ...e,
      headers: t
    };
  }
  async executeRequest(e, t) {
    const s = new AbortController(), r = t.timeout ? setTimeout(() => s.abort(), t.timeout) : null;
    try {
      const o = {
        method: t.method,
        headers: t.headers,
        signal: s.signal
      };
      t.body && t.method !== "GET" && (o.body = typeof t.body == "string" ? t.body : JSON.stringify(t.body));
      const i = await fetch(e, o);
      return r && clearTimeout(r), i;
    } catch (o) {
      throw r && clearTimeout(r), o;
    }
  }
  async parseResponse(e) {
    const t = e.headers.get("Content-Type") || "";
    let s;
    if (t.includes("application/json") ? s = await e.json() : s = await e.text(), !e.ok)
      throw new Error(`HTTP ${e.status}: ${e.statusText}`, {
        cause: { status: e.status, data: s }
      });
    return s && typeof s == "object" && "success" in s ? s : {
      success: !0,
      data: s
    };
  }
  createAPIError(e) {
    if (e.cause && typeof e.cause == "object") {
      const { status: t, data: s } = e.cause;
      if (s && typeof s == "object" && "errors" in s)
        return {
          code: s.code || `HTTP_${t}`,
          message: s.message || e.message,
          details: s.details
        };
    }
    return {
      code: "UNKNOWN_ERROR",
      message: e.message || "An unknown error occurred",
      details: { originalError: e }
    };
  }
}
const w = (n) => new p(n), g = (n) => n && typeof n == "object" && "code" in n && "message" in n, m = (n) => g(n) ? n : {
  code: "UNKNOWN_ERROR",
  message: n?.message || "An unknown error occurred",
  details: { originalError: n }
}, b = async (n, e = 3, t = 1e3) => {
  let s;
  for (let r = 1; r <= e; r++)
    try {
      return await n();
    } catch (o) {
      if (s = o, r === e) break;
      const i = t * Math.pow(2, r - 1);
      await new Promise((a) => setTimeout(a, i));
    }
  throw s;
}, y = (n, e, t = 3e5) => {
  const s = /* @__PURE__ */ new Map();
  return (async () => {
    const r = s.get(e);
    if (r && r.expires > Date.now())
      return r.data;
    const o = await n();
    return s.set(e, { data: o, expires: Date.now() + t }), o;
  })();
}, R = async (n, e = 5, t = 100) => {
  const s = [];
  for (let r = 0; r < n.length; r += e) {
    const o = n.slice(r, r + e), i = await Promise.all(o.map((a) => a()));
    s.push(...i), r + e < n.length && t > 0 && await new Promise((a) => setTimeout(a, t));
  }
  return s;
}, E = async (n, e, t, s = {}) => {
  const r = new FormData();
  if (r.append("file", t), s.additionalData)
    for (const [o, i] of Object.entries(s.additionalData))
      r.append(o, String(i));
  return new Promise((o, i) => {
    const a = new XMLHttpRequest();
    s.onProgress && a.upload.addEventListener("progress", (c) => {
      if (c.lengthComputable) {
        const h = c.loaded / c.total * 100;
        s.onProgress(h);
      }
    }), s.abortSignal && s.abortSignal.addEventListener("abort", () => {
      a.abort(), i(new Error("Upload aborted"));
    }), a.addEventListener("load", async () => {
      try {
        const c = JSON.parse(a.responseText);
        a.status >= 200 && a.status < 300 ? o(c) : i(new Error(`Upload failed: ${c.message || a.statusText}`));
      } catch {
        i(new Error("Failed to parse upload response"));
      }
    }), a.addEventListener("error", () => {
      i(new Error("Upload failed"));
    }), a.open("POST", `${n.config.baseUrl}${e}`);
    const l = n.buildRequestConfig({}).headers || {};
    for (const [c, h] of Object.entries(l))
      c.toLowerCase() !== "content-type" && a.setRequestHeader(c, h);
    a.send(r);
  });
}, P = async (n, e, t, s = {}) => {
  const r = await fetch(`${n.config.baseUrl}${e}`, {
    headers: n.buildRequestConfig({}).headers,
    signal: s.abortSignal
  });
  if (!r.ok)
    throw new Error(`Download failed: ${r.statusText}`);
  const o = await r.blob(), i = window.URL.createObjectURL(o), a = document.createElement("a");
  a.style.display = "none", a.href = i, a.download = t || "download", document.body.appendChild(a), a.click(), window.URL.revokeObjectURL(i), document.body.removeChild(a);
};
class I {
  constructor(e, t = {}) {
    this.url = e, this.config = t, d(this, "ws", null), d(this, "reconnectAttempts", 0), d(this, "maxReconnectAttempts", 5), d(this, "reconnectDelay", 1e3), d(this, "messageQueue", []), d(this, "eventHandlers", /* @__PURE__ */ new Map());
  }
  connect() {
    return new Promise((e, t) => {
      try {
        const s = new URL(this.url);
        this.config.token && s.searchParams.set("token", this.config.token), this.config.organizationId && s.searchParams.set("organizationId", this.config.organizationId), this.ws = new WebSocket(s.toString()), this.ws.onopen = () => {
          for (this.reconnectAttempts = 0; this.messageQueue.length > 0; ) {
            const r = this.messageQueue.shift();
            this.ws.send(JSON.stringify(r));
          }
          e();
        }, this.ws.onmessage = (r) => {
          try {
            const o = JSON.parse(r.data);
            this.handleMessage(o);
          } catch (o) {
            console.error("Failed to parse WebSocket message:", o);
          }
        }, this.ws.onclose = () => {
          this.ws = null, this.config.autoReconnect !== !1 && this.reconnectAttempts < this.maxReconnectAttempts && setTimeout(() => {
            this.reconnectAttempts++, this.connect();
          }, this.reconnectDelay * Math.pow(2, this.reconnectAttempts));
        }, this.ws.onerror = (r) => {
          t(r);
        };
      } catch (s) {
        t(s);
      }
    });
  }
  disconnect() {
    this.ws && (this.ws.close(), this.ws = null);
  }
  send(e) {
    this.ws && this.ws.readyState === WebSocket.OPEN ? this.ws.send(JSON.stringify(e)) : this.messageQueue.push(e);
  }
  on(e, t) {
    return this.eventHandlers.has(e) || this.eventHandlers.set(e, /* @__PURE__ */ new Set()), this.eventHandlers.get(e).add(t), () => {
      this.eventHandlers.get(e)?.delete(t);
    };
  }
  handleMessage(e) {
    const { type: t, payload: s } = e;
    if (this.eventHandlers.has(t))
      for (const r of this.eventHandlers.get(t))
        r(s);
  }
}
export {
  p as APIClient,
  I as APIWebSocket,
  R as batchRequests,
  w as createAPIClient,
  P as downloadFile,
  m as handleAPIError,
  g as isAPIError,
  b as retryRequest,
  E as uploadFile,
  y as withCache
};
//# sourceMappingURL=api.js.map
