var f = Object.defineProperty;
var w = (s, t, i) => t in s ? f(s, t, { enumerable: !0, configurable: !0, writable: !0, value: i }) : s[t] = i;
var h = (s, t, i) => (w(s, typeof t != "symbol" ? t + "" : t, i), i);
import { UNSAFE_initAccessToken as l } from "../utils/initAccessToken.js";
import { getVirtualRunnerUrl as k } from "../utils/jwt.js";
var S = /* @__PURE__ */ ((s) => (s[s.VISUAL = 0] = "VISUAL", s[s.VOICE = 1] = "VOICE", s[s.COGNITIVE = 2] = "COGNITIVE", s))(S || {});
class g {
  constructor(t) {
    /**
     * Configurations for VirtualService prompting
     */
    h(this, "configs");
    /**
     * 3D Model URL
     */
    h(this, "modelUrl");
    /**
     * Runner URL
     */
    h(this, "runnerUrl");
    /**
     * Runner supported cores
     */
    h(this, "cores");
    this.configs = t, this.modelUrl = "", this.runnerUrl = "", this.cores = [];
  }
  /**
   * Function to initialize modelUrl and runnerUrl.
   */
  async initVirtual() {
    var n;
    let t = localStorage.getItem(`runnerToken${this.configs.virtualId}`) ?? "";
    const i = k(t), e = i || "https://runner.virtuals.gg";
    this.runnerUrl = e;
    try {
      const r = await fetch(`${e}/model`, {
        method: "GET",
        headers: {
          "Content-Type": "application/json",
          Authorization: `Bearer ${t}`
        }
      });
      if (r.status !== 200)
        throw new Error("Fetch model failed");
      const o = await r.json();
      this.modelUrl = ((n = o == null ? void 0 : o.data) == null ? void 0 : n.model) ?? "";
    } catch {
      this.modelUrl = "";
    }
    try {
      const r = await fetch(`${e}/cores`, {
        method: "GET",
        headers: {
          "Content-Type": "application/json",
          Authorization: `Bearer ${t}`
        }
      });
      if (r.status !== 200)
        throw new Error("Fetch cores failed");
      const o = await r.json();
      this.cores = (o == null ? void 0 : o.data) ?? [], this.initComplete();
    } catch {
      this.cores = [];
    }
  }
  /**
   * Function when init completed
   */
  async initComplete() {
    var i, e;
    const t = [];
    this.modelUrl && t.push(
      0
      /* VISUAL */
    ), this.cores.includes("tts") && t.push(
      1
      /* VOICE */
    ), this.cores.includes("llm") && t.push(
      2
      /* COGNITIVE */
    ), (e = (i = this.configs).onInitCompleted) == null || e.call(i, t);
  }
  /**
   * Function to initialize user session by virtual id
   * @param vid virtualId
   * @param retry function will retry for 3 times, to prevent this behavior, set to a number above 3
   */
  async initSession(t, i = 0) {
    try {
      if (t) {
        const n = await (this.configs.initAccessToken ? this.configs.initAccessToken : l)(t, this.configs.metadata);
        localStorage.setItem(`runnerToken${t}`, n);
      }
      await this.initVirtual();
    } catch (e) {
      if (i >= 3)
        throw e;
      localStorage.removeItem(`runnerToken${t}`), await this.initSession(t, i + 1);
    }
  }
  /**
   * Function to send prompt to the runner service and get Virtual response.
   * @param content text / audio blob contents
   * @param configs additional configuration during prompting
   * @param onPromptReceived callback when prompt is received from the runner service
   * @param retry function will retry for 3 times, to prevent this behavior, set to a number above 3
   * @returns Prompt object
   */
  async createPrompt(t, i, e, n) {
    var r, o, p, T;
    try {
      if (!this.configs.virtualId)
        throw new Error("Virtual not found");
      const d = await (this.configs.initAccessToken ? this.configs.initAccessToken : l)(
        this.configs.virtualId ?? -1,
        this.configs.metadata
      ), c = new FormData();
      typeof t != "string" && (c.append("audio", t, "recording.webm"), c.append("skipTTS", i != null && i.skipTTS ? "true" : "false"), c.append("userName", this.configs.userName ?? ""), c.append("botName", this.configs.virtualName ?? ""));
      const u = await fetch(`${this.runnerUrl}/prompts`, {
        method: "POST",
        headers: typeof t == "string" ? {
          "Content-Type": "application/json",
          Authorization: `Bearer ${d}`
        } : {
          Authorization: `Bearer ${d}`
        },
        body: typeof t == "string" ? JSON.stringify({
          text: t,
          skipTTS: i == null ? void 0 : i.skipTTS,
          userName: this.configs.userName,
          botName: this.configs.virtualName
        }) : c
      });
      if (u.status !== 200 && (n ?? 0) < 3)
        return localStorage.removeItem(`runnerToken${this.configs.virtualId}`), await this.initSession(this.configs.virtualId), await this.createPrompt(
          t,
          {
            skipTTS: !!(i != null && i.skipTTS)
          },
          e,
          (n ?? 0) + 1
        );
      u.status !== 200 && ((o = (r = this.configs).onPromptError) == null || o.call(r, u));
      const a = await u.json();
      if (a != null && a.error)
        throw new Error(a.error);
      return e && e(a), a;
    } catch (m) {
      return (n ?? 0) < 3 ? await this.createPrompt(
        t,
        {
          skipTTS: !!(i != null && i.skipTTS)
        },
        e,
        (n ?? 0) + 1
      ) : ((T = (p = this.configs).onPromptError) == null || T.call(p, m), {});
    }
  }
  /**
   * Text-to-speech function
   * @param content text content
   * @returns audio in URL
   */
  async getTTSResponse(t) {
    try {
      if (!this.configs.virtualId)
        throw new Error("Virtual not found");
      const e = await (this.configs.initAccessToken ? this.configs.initAccessToken : l)(
        this.configs.virtualId ?? -1,
        this.configs.metadata
      ), n = await fetch(`${this.runnerUrl}/prompts/voice`, {
        method: "POST",
        headers: {
          "Content-Type": "application/json",
          Authorization: `Bearer ${e}`
        },
        body: JSON.stringify({
          text: t
        })
      }), r = await n.json();
      if (r != null && r.error)
        throw new Error(r.error);
      return n.status !== 200 ? "" : (r == null ? void 0 : r.audioUid) ?? "";
    } catch {
      return "";
    }
  }
}
const A = new g({});
export {
  S as Core,
  g as VirtualService,
  A as defaultVirtualService
};
