var __defProp = Object.defineProperty;
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
var __getOwnPropNames = Object.getOwnPropertyNames;
var __hasOwnProp = Object.prototype.hasOwnProperty;
var __export = (target, all) => {
  for (var name in all)
    __defProp(target, name, { get: all[name], enumerable: true });
};
var __copyProps = (to, from, except, desc) => {
  if (from && typeof from === "object" || typeof from === "function") {
    for (let key of __getOwnPropNames(from))
      if (!__hasOwnProp.call(to, key) && key !== except)
        __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
  }
  return to;
};
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
var dist_exports = {};
__export(dist_exports, {
  GENERATION_JOB_ETA_BASELINE_SECONDS: () => GENERATION_JOB_ETA_BASELINE_SECONDS,
  createAiClient: () => createAiClient
});
module.exports = __toCommonJS(dist_exports);
const GENERATION_JOB_ETA_BASELINE_SECONDS = {
  IMAGE: 20,
  MUSIC: 40,
  SFX: 15,
  SPEECH: 15,
  VIDEO: 90,
  MODEL_3D: 420
};
const DEFAULT_LOCAL_BASE = "http://localhost:8083";
const CLIENT_HEADER_NAMES = {
  client: "x-playdrop-client",
  clientVersion: "x-playdrop-client-version",
  clientBuild: "x-playdrop-client-build",
  platform: "x-playdrop-platform",
  platformVersion: "x-playdrop-platform-version"
};
function stripTrailingSlash(value) {
  return value.endsWith("/") ? value.slice(0, -1) : value;
}
function normalizeProtocol(protocol) {
  if (!protocol) {
    return "http";
  }
  return protocol.replace(/:$/, "") || "http";
}
function isIpv4Hostname(hostname) {
  return /^\d{1,3}(?:\.\d{1,3}){3}$/.test(hostname);
}
function isLocalHostname(hostname) {
  if (!hostname) {
    return true;
  }
  const normalizedHostname = hostname.trim().toLowerCase();
  if (!normalizedHostname) {
    return true;
  }
  if (normalizedHostname === "localhost" || normalizedHostname === "0.0.0.0") {
    return true;
  }
  if (isIpv4Hostname(normalizedHostname)) {
    return true;
  }
  return normalizedHostname.includes(":");
}
function formatHostnameForUrl(hostname) {
  const normalizedHostname = hostname.trim();
  if (!normalizedHostname) {
    return "localhost";
  }
  if (normalizedHostname.includes(":") && !normalizedHostname.startsWith("[")) {
    return `[${normalizedHostname}]`;
  }
  return normalizedHostname;
}
function inferBaseFromHostname(hostname, protocol) {
  if (isLocalHostname(hostname)) {
    return `${protocol}://${formatHostnameForUrl(hostname)}:8083`;
  }
  if (hostname.includes(".")) {
    const domain = hostname.replace(/^www\./, "").replace(/^api\./, "").replace(/^play\./, "").replace(/^admin\./, "").replace(/^ai\./, "").replace(/^assets\./, "");
    return `${protocol}://ai.${domain}`;
  }
  const host = formatHostnameForUrl(hostname || "localhost");
  return `${protocol}://${host}:8083`;
}
function inferBaseUrl() {
  if (typeof process !== "undefined" && process.env.NEXT_PUBLIC_AI_BASE) {
    return process.env.NEXT_PUBLIC_AI_BASE;
  }
  if (typeof window !== "undefined" && window.location) {
    const { hostname, protocol } = window.location;
    return inferBaseFromHostname(hostname, normalizeProtocol(protocol));
  }
  return DEFAULT_LOCAL_BASE;
}
function resolveBrowserRequestCredentials() {
  if (typeof window === "undefined") {
    return void 0;
  }
  return "include";
}
function readBrowserRuntimeClientMeta() {
  if (typeof window === "undefined") {
    return null;
  }
  const raw = globalThis.__PLAYDROP_CLIENT_META;
  const version = typeof raw?.version === "string" ? raw.version.trim() : "";
  const build = typeof raw?.build === "string" ? raw.build.trim() : "";
  if (!version || !build) {
    return null;
  }
  return { version, build };
}
function normalizeBrowserPlatformName(raw) {
  const value = raw.trim().toLowerCase();
  if (value.includes("mac"))
    return "macos";
  if (value.includes("win"))
    return "windows";
  if (value.includes("linux"))
    return "linux";
  if (value.includes("ios") || value.includes("iphone") || value.includes("ipad"))
    return "ios";
  if (value.includes("android"))
    return "android";
  return value || "browser";
}
function resolveBrowserPlatform() {
  if (typeof window === "undefined") {
    return { name: "browser", version: "0.0.0" };
  }
  const envPlatform = (typeof process !== "undefined" ? process.env.NEXT_PUBLIC_PLAYDROP_PLATFORM : "")?.trim() ?? "";
  const envPlatformVersion = (typeof process !== "undefined" ? process.env.NEXT_PUBLIC_PLAYDROP_PLATFORM_VERSION : "")?.trim() ?? "";
  if (envPlatform && envPlatformVersion) {
    return { name: envPlatform.toLowerCase(), version: envPlatformVersion };
  }
  const nav = window.navigator;
  const userAgent = nav.userAgent || "";
  const data = nav.userAgentData;
  if (data?.platform) {
    const platformName = normalizeBrowserPlatformName(data.platform);
    const version = (data.platformVersion || "").replace(/_/g, ".").trim();
    if (version) {
      return { name: platformName, version };
    }
  }
  const macMatch = /Mac OS X ([0-9_]+(?:_[0-9_]+)*)/i.exec(userAgent);
  if (macMatch?.[1]) {
    return { name: "macos", version: macMatch[1].replace(/_/g, ".") };
  }
  const iosMatch = /(iPhone|iPad|iPod).*OS ([0-9_]+)/i.exec(userAgent);
  if (iosMatch?.[2]) {
    return { name: "ios", version: iosMatch[2].replace(/_/g, ".") };
  }
  const winMatch = /Windows NT ([0-9.]+)/i.exec(userAgent);
  if (winMatch?.[1]) {
    return { name: "windows", version: winMatch[1] };
  }
  const androidMatch = /Android ([0-9.]+)/i.exec(userAgent);
  if (androidMatch?.[1]) {
    return { name: "android", version: androidMatch[1] };
  }
  if (/Linux/i.test(userAgent)) {
    return { name: "linux", version: "0.0.0" };
  }
  return { name: "browser", version: "0.0.0" };
}
function resolveBrowserDefaultClientHeaders() {
  const clientMeta = readBrowserRuntimeClientMeta();
  if (!clientMeta) {
    return {};
  }
  const platform = resolveBrowserPlatform();
  return {
    [CLIENT_HEADER_NAMES.client]: "web",
    [CLIENT_HEADER_NAMES.clientVersion]: clientMeta.version,
    [CLIENT_HEADER_NAMES.clientBuild]: clientMeta.build,
    [CLIENT_HEADER_NAMES.platform]: platform.name,
    [CLIENT_HEADER_NAMES.platformVersion]: platform.version
  };
}
function fillMissingClientHeaders(headers) {
  if (typeof window === "undefined") {
    return headers;
  }
  const inferredHeaders = resolveBrowserDefaultClientHeaders();
  if (!Object.keys(inferredHeaders).length) {
    return headers;
  }
  return {
    ...inferredHeaders,
    ...headers
  };
}
async function resolveAiClientToken(config) {
  if (config.tokenProvider) {
    const token = await config.tokenProvider();
    return token ?? null;
  }
  return null;
}
async function resolveAiClientHeaders(config) {
  if (config.clientHeaders) {
    try {
      const headers = await config.clientHeaders();
      return headers && typeof headers === "object" ? { ...headers } : {};
    } catch {
      return {};
    }
  }
  return {};
}
function createAiClient(config = {}) {
  const fetchImpl = config.fetchImpl ?? globalThis.fetch?.bind(globalThis);
  if (!fetchImpl) {
    throw new Error("ai_client_missing_fetch");
  }
  const baseUrl = stripTrailingSlash(config.baseUrl ?? inferBaseUrl());
  async function buildHeaders() {
    const headers = fillMissingClientHeaders({
      ...await resolveAiClientHeaders(config)
    });
    const token = await resolveAiClientToken(config);
    if (token && !headers.Authorization) {
      headers.Authorization = `Bearer ${token}`;
    }
    return headers;
  }
  async function buildRequestInit(payload, signal) {
    const headers = await buildHeaders();
    headers["Content-Type"] = "application/json";
    return {
      method: "POST",
      headers,
      body: JSON.stringify(payload),
      credentials: resolveBrowserRequestCredentials(),
      signal
    };
  }
  async function throwHttpError(response) {
    let payload = null;
    try {
      const text = await response.text();
      if (text) {
        try {
          payload = JSON.parse(text);
        } catch {
          payload = { message: text };
        }
      }
    } catch {
      payload = null;
    }
    const code = payload?.error ?? `http_${response.status}`;
    const message = payload?.message ?? response.statusText ?? "Request failed";
    const error = new Error(`${code}: ${message}`);
    error.status = response.status;
    error.code = code;
    error.details = payload;
    throw error;
  }
  async function ensureOk(response) {
    if (!response.ok) {
      await throwHttpError(response);
    }
  }
  async function generateText(input, options) {
    const normalizedInput = input?.trim();
    if (!normalizedInput) {
      throw new Error("ai_client_missing_input");
    }
    const size = options?.size ?? "small";
    const mode = options?.mode ?? "text";
    const rawSystem = options?.system?.trim();
    const system = rawSystem && rawSystem.length ? rawSystem : void 0;
    const response = await fetchImpl(`${baseUrl}/text/generate`, await buildRequestInit({
      input: normalizedInput,
      size,
      mode,
      system
    }, options?.signal));
    await ensureOk(response);
    const data = await response.json();
    return data;
  }
  function applyMediaGenerationPayload(payload, request) {
    if (request.modality === "IMAGE") {
      payload.mode = "image";
      payload.image1 = request.image1 ?? void 0;
      payload.image2 = request.image2 ?? void 0;
      payload.aspectRatio = request.aspectRatio;
      payload.imageSize = request.imageSize;
      return true;
    }
    if (request.modality === "VIDEO") {
      payload.durationSeconds = typeof request.durationSeconds === "number" ? request.durationSeconds : void 0;
      payload.aspectRatio = request.aspectRatio;
      payload.resolution = "720p";
      payload.image1 = request.image1 ?? void 0;
      payload.image2 = request.image2 ?? void 0;
      return true;
    }
    return false;
  }
  function applyAudioGenerationPayload(payload, request) {
    if (request.modality === "MUSIC") {
      payload.durationMs = typeof request.durationMs === "number" ? request.durationMs : void 0;
      payload.forceInstrumental = typeof request.forceInstrumental === "boolean" ? request.forceInstrumental : void 0;
      payload.coverPrompt = typeof request.coverPrompt === "string" ? request.coverPrompt : void 0;
      return true;
    }
    if (request.modality === "SFX") {
      payload.durationSeconds = typeof request.durationSeconds === "number" ? request.durationSeconds : void 0;
      payload.loop = typeof request.loop === "boolean" ? request.loop : void 0;
      payload.coverPrompt = typeof request.coverPrompt === "string" ? request.coverPrompt : void 0;
      return true;
    }
    if (request.modality === "SPEECH") {
      payload.speechVoice = typeof request.speechVoice === "string" ? request.speechVoice : void 0;
      payload.speechProviderVoiceId = typeof request.speechProviderVoiceId === "string" ? request.speechProviderVoiceId : void 0;
      return true;
    }
    return false;
  }
  function applyGenerateAssetPayloadByModality(payload, request) {
    if (applyMediaGenerationPayload(payload, request) || applyAudioGenerationPayload(payload, request)) {
      return;
    }
    if (request.modality === "MODEL_3D") {
      payload.sourceMode = request.sourceMode;
      payload.image1 = request.image1 ?? void 0;
      payload.image2 = request.image2 ?? void 0;
      payload.topology = request.topology;
      payload.targetPolycount = typeof request.targetPolycount === "number" ? request.targetPolycount : void 0;
      payload.shouldRemesh = typeof request.shouldRemesh === "boolean" ? request.shouldRemesh : void 0;
      payload.shouldTexture = typeof request.shouldTexture === "boolean" ? request.shouldTexture : void 0;
    }
  }
  function buildGenerateAssetPayload(request) {
    const normalizedInput = request.input?.trim();
    if (!normalizedInput) {
      throw new Error("ai_client_missing_input");
    }
    const payload = {
      modality: request.modality,
      input: normalizedInput,
      assetName: request.assetName,
      assetDisplayName: request.assetDisplayName,
      assetDescription: request.assetDescription,
      assetVisibility: request.assetVisibility,
      attachAppVersionId: request.attachAppVersionId,
      remixAssetVersionRef: request.remixAssetVersionRef,
      suggestedTagRefs: request.suggestedTagRefs
    };
    if (request.modality !== "SPEECH") {
      payload.assetSubcategory = request.assetSubcategory;
    }
    applyGenerateAssetPayloadByModality(payload, request);
    return payload;
  }
  async function createGenerationJob(request) {
    const payload = buildGenerateAssetPayload(request);
    const response = await fetchImpl(`${baseUrl}/ai/assets/jobs`, await buildRequestInit(payload, request.signal));
    await ensureOk(response);
    return await response.json();
  }
  async function getGenerationJob(id, options = {}) {
    const normalizedId = id?.trim();
    if (!normalizedId) {
      throw new Error("ai_client_missing_job_id");
    }
    const response = await fetchImpl(`${baseUrl}/ai/assets/jobs/${encodeURIComponent(normalizedId)}`, {
      method: "GET",
      headers: await buildHeaders(),
      credentials: resolveBrowserRequestCredentials(),
      signal: options.signal
    });
    await ensureOk(response);
    return await response.json();
  }
  async function listGenerationJobs(options = {}) {
    const params = new URLSearchParams();
    if (options.modality) {
      params.set("modality", options.modality);
    }
    if (options.status) {
      params.set("status", options.status);
    }
    if (typeof options.limit === "number" && Number.isFinite(options.limit)) {
      params.set("limit", String(options.limit));
    }
    if (typeof options.offset === "number" && Number.isFinite(options.offset)) {
      params.set("offset", String(options.offset));
    }
    const queryString = params.toString();
    const query = queryString ? `?${queryString}` : "";
    const response = await fetchImpl(`${baseUrl}/ai/assets/jobs${query}`, {
      method: "GET",
      headers: await buildHeaders(),
      credentials: resolveBrowserRequestCredentials(),
      signal: options.signal
    });
    await ensureOk(response);
    return await response.json();
  }
  async function deleteGenerationJob(id, options = {}) {
    const normalizedId = id?.trim();
    if (!normalizedId) {
      throw new Error("ai_client_missing_job_id");
    }
    const response = await fetchImpl(`${baseUrl}/ai/assets/jobs/${encodeURIComponent(normalizedId)}`, {
      method: "DELETE",
      headers: await buildHeaders(),
      credentials: resolveBrowserRequestCredentials(),
      signal: options.signal
    });
    await ensureOk(response);
  }
  async function generateJson(input, options) {
    const normalizedInput = input?.trim();
    if (!normalizedInput) {
      throw new Error("ai_client_missing_input");
    }
    const normalizedSystem = options?.system?.trim();
    const response = await fetchImpl(`${baseUrl}/json/generate`, await buildRequestInit({
      input: normalizedInput,
      size: options?.size ?? "small",
      system: normalizedSystem && normalizedSystem.length ? normalizedSystem : void 0,
      responseJsonSchema: options?.responseJsonSchema
    }, options?.signal));
    await ensureOk(response);
    const data = await response.json();
    return data;
  }
  async function listGenerations(options = {}) {
    const params = new URLSearchParams();
    if (options.type) {
      params.set("type", options.type);
    }
    if (typeof options.limit === "number" && Number.isFinite(options.limit)) {
      params.set("limit", String(options.limit));
    }
    if (typeof options.offset === "number" && Number.isFinite(options.offset)) {
      params.set("offset", String(options.offset));
    }
    const queryString = params.toString();
    const query = queryString ? `?${queryString}` : "";
    const response = await fetchImpl(`${baseUrl}/generations${query}`, {
      method: "GET",
      headers: await buildHeaders(),
      credentials: resolveBrowserRequestCredentials(),
      signal: options.signal
    });
    await ensureOk(response);
    const data = await response.json();
    return data;
  }
  async function listDiscoverGenerations(options = {}) {
    const params = new URLSearchParams();
    if (options.type) {
      params.set("type", options.type);
    }
    if (typeof options.limit === "number" && Number.isFinite(options.limit)) {
      params.set("limit", String(options.limit));
    }
    if (typeof options.offset === "number" && Number.isFinite(options.offset)) {
      params.set("offset", String(options.offset));
    }
    const queryString = params.toString();
    const query = queryString ? `?${queryString}` : "";
    const response = await fetchImpl(`${baseUrl}/generations/discover${query}`, {
      method: "GET",
      headers: await buildHeaders(),
      credentials: resolveBrowserRequestCredentials(),
      signal: options.signal
    });
    await ensureOk(response);
    const data = await response.json();
    return data;
  }
  return {
    generateText,
    createGenerationJob,
    getGenerationJob,
    listGenerationJobs,
    deleteGenerationJob,
    generateJson,
    listGenerations,
    listDiscoverGenerations
  };
}
// Annotate the CommonJS export names for ESM import in node:
0 && (module.exports = {
  GENERATION_JOB_ETA_BASELINE_SECONDS,
  createAiClient
});
