import { APIError } from "../../_exceptions.js";
const LOCAL_LANGUAGES = {
  ar: 0.35,
  de: 0.245,
  en: 0.36,
  es: 0.35,
  fr: 0.285,
  hi: 0.305,
  id: 0.345,
  it: 0.23,
  ja: 0.295,
  ko: 0.4,
  nl: 0.2,
  pt: 0.32,
  tr: 0.255,
  zh: 0.355
};
function normalizeLanguage(input) {
  const lower = input.toLowerCase().trim();
  if (lower.length === 2) return lower;
  const dashIdx = lower.indexOf("-");
  if (dashIdx === 2) return lower.slice(0, 2);
  const aliases = {
    arabic: "ar",
    german: "de",
    english: "en",
    spanish: "es",
    french: "fr",
    hindi: "hi",
    indonesian: "id",
    italian: "it",
    japanese: "ja",
    korean: "ko",
    dutch: "nl",
    portuguese: "pt",
    turkish: "tr",
    chinese: "zh",
    mandarin: "zh"
  };
  return aliases[lower] ?? lower;
}
const round4 = (value) => Math.round(value * 1e4) / 1e4;
function normalizeOverrides(overrides) {
  if (overrides === void 0 || typeof overrides !== "object") {
    return overrides;
  }
  const out = {};
  for (const [k, v] of Object.entries(overrides)) {
    out[normalizeLanguage(k)] = Number(v);
  }
  return out;
}
class ThresholdOptions {
  _model;
  _overrides;
  _bcOverrides;
  // server/shipped defaults
  _serverThresholds;
  _serverDefault;
  // backchannel server defaults: cloud-only (the local mini model produces no
  // backchannel probability), arrive via `SessionCreated`.
  _serverBcThresholds;
  _serverBcDefault;
  // materialized values (server defaults layered with user overrides)
  _thresholds = {};
  _default = void 0;
  _bcThresholds = {};
  _bcDefault = void 0;
  constructor(model, overrides = void 0, backchannelOverrides = void 0) {
    this._model = model;
    this._overrides = normalizeOverrides(overrides);
    this._bcOverrides = normalizeOverrides(backchannelOverrides);
    if (model === "turn-detector-v1-mini") {
      this._serverThresholds = { ...LOCAL_LANGUAGES };
      this._serverDefault = LOCAL_LANGUAGES.en;
    }
    this._resolve();
  }
  get model() {
    return this._model;
  }
  get overrides() {
    return this._overrides;
  }
  get backchannelOverrides() {
    return this._bcOverrides;
  }
  get thresholds() {
    return this._thresholds;
  }
  get defaultThreshold() {
    return this._default;
  }
  lookup(language) {
    const key = language ? normalizeLanguage(language) : "en";
    return key in this._thresholds ? this._thresholds[key] : this._default;
  }
  /**
   * Backchannel threshold for a language, or `undefined` when backchannel is
   * disabled — no server defaults / overrides resolved, or the resolved value is
   * non-positive (an explicit "off"). Backchannel is server-driven and cloud-only.
   */
  lookupBackchannel(language) {
    if (Object.keys(this._bcThresholds).length === 0 && this._bcDefault === void 0) {
      return void 0;
    }
    const key = language ? normalizeLanguage(language) : "en";
    const threshold = key in this._bcThresholds ? this._bcThresholds[key] : this._bcDefault;
    return threshold !== void 0 && threshold > 0 ? threshold : void 0;
  }
  supports(language) {
    const pending = this._model === "turn-detector-v1" && this._serverThresholds === void 0;
    return pending || this.lookup(language) !== void 0;
  }
  updateOverrides(overrides) {
    this._overrides = normalizeOverrides(overrides);
    this._resolve();
  }
  updateBackchannelOverrides(overrides) {
    this._bcOverrides = normalizeOverrides(overrides);
    this._resolve();
  }
  /**
   * @internal Adopt the calibrated defaults a `turn-detector` gateway sends in
   * `SessionCreated`. Raises (non-retryable) when the server produced no usable
   * thresholds — the caller degrades the session to the local model.
   */
  _updateDefaults(serverThresholds, serverDefault, backchannelThresholds, backchannelDefault = 0) {
    if (!serverThresholds || Object.keys(serverThresholds).length === 0 || serverDefault <= 0) {
      throw new APIError("turn detector session created without usable default thresholds", {
        retryable: false
      });
    }
    const norm = {};
    for (const [lang, value] of Object.entries(serverThresholds)) {
      norm[normalizeLanguage(lang)] = round4(value);
    }
    this._serverThresholds = norm;
    this._serverDefault = round4(serverDefault);
    if (backchannelThresholds && Object.keys(backchannelThresholds).length > 0) {
      const bcNorm = {};
      for (const [lang, value] of Object.entries(backchannelThresholds)) {
        bcNorm[normalizeLanguage(lang)] = round4(value);
      }
      this._serverBcThresholds = bcNorm;
    } else {
      this._serverBcThresholds = void 0;
    }
    this._serverBcDefault = backchannelDefault > 0 ? round4(backchannelDefault) : void 0;
    this._resolve();
  }
  /**
   * @internal Promote to the local mini model on cloud→local fallback,
   * preserving the user's effective-vs-default ratio per language:
   * `local = LOCAL[lang] * (effective_t / server[lang])`.
   */
  _toLocalFallback() {
    if (this._model === "turn-detector-v1-mini") {
      return;
    }
    let rescaled;
    const server = this._serverThresholds;
    if (server) {
      rescaled = {};
      for (const lang of Object.keys(server)) {
        const activeT = this.lookup(lang);
        const local = LOCAL_LANGUAGES[lang];
        if (activeT !== void 0 && local !== void 0 && server[lang] !== 0) {
          rescaled[lang] = local * (activeT / server[lang]);
        }
      }
    }
    this._model = "turn-detector-v1-mini";
    this._serverThresholds = { ...LOCAL_LANGUAGES };
    this._serverDefault = LOCAL_LANGUAGES.en;
    this._serverBcThresholds = void 0;
    this._serverBcDefault = void 0;
    this._resolve();
    if (rescaled !== void 0) {
      this._thresholds = rescaled;
      this._default = this.lookup("en");
    }
  }
  _resolve() {
    [this._thresholds, this._default] = ThresholdOptions._resolveLayer(
      this._serverThresholds,
      this._serverDefault,
      this._overrides
    );
    [this._bcThresholds, this._bcDefault] = ThresholdOptions._resolveLayer(
      this._serverBcThresholds,
      this._serverBcDefault,
      this._bcOverrides
    );
  }
  /**
   * Layer a user override onto the server defaults. A scalar override replaces
   * the whole map (every language resolves through it); a dict override is
   * merged over the server map. Before server defaults arrive, only a scalar
   * override resolves up front.
   */
  static _resolveLayer(serverThresholds, serverDefault, overrides) {
    const scalarOverride = typeof overrides === "number";
    if (serverThresholds === void 0 || serverDefault === void 0) {
      return [{}, scalarOverride ? overrides : void 0];
    }
    if (overrides === void 0) {
      return [{ ...serverThresholds }, serverDefault];
    }
    if (scalarOverride) {
      return [{}, overrides];
    }
    return [{ ...serverThresholds, ...overrides }, serverDefault];
  }
}
export {
  LOCAL_LANGUAGES,
  ThresholdOptions
};
//# sourceMappingURL=languages.js.map