import { s as x, c as O } from "../chunks/source-identity-qAmkNtEK.js";
import { j as q } from "../chunks/index-CuHybtft.js";
import { createContext as T, useContext as U, useMemo as m, useState as b, useCallback as h, useRef as R, useEffect as _ } from "react";
import { jsx as C } from "react/jsx-runtime";
import { v as K } from "../chunks/validators-BnLhuIhd.js";
function P(t) {
  var r;
  const e = z(t);
  return {
    version: 1,
    kind: "metric",
    id: t.id,
    label: t.label,
    source: k(t),
    metrics: e,
    primaryMetric: F(t, e),
    dateField: t.dateField ? s(t.dateField, "date") : void 0,
    timeGrain: t.timeGrain,
    dimensions: (r = t.dimensions) == null ? void 0 : r.map((n) => s(n, "dimension")),
    comparison: et(t.comparison),
    orderBy: t.orderBy ? {
      field: s(t.orderBy.field),
      direction: t.orderBy.direction
    } : void 0,
    inputs: D(t.inputs),
    limit: t.limit
  };
}
function F(t, e) {
  if (!t.primaryMetric)
    return e[0] || { name: "", role: "measure" };
  const r = s(t.primaryMetric, "measure"), n = L(r, e), o = n.length === 1 ? n[0] : void 0;
  return o ? w(r, o) : r;
}
function z(t) {
  const e = [];
  for (const r of t.metrics.map((n) => s(n, "measure"))) {
    if (!r.name)
      continue;
    const n = e.findIndex(
      (o) => V(o, r)
    );
    if (n === -1) {
      e.push(r);
      continue;
    }
    e[n] = w(e[n], r);
  }
  return e;
}
function V(t, e) {
  return x(t, e) && g(t) === g(e);
}
function j(t, e) {
  return g(e) === g(t);
}
function N(t, e) {
  return e.name !== t.name || t.source && !x(e, t) ? !1 : j(t, e);
}
function L(t, e) {
  const r = e.filter(
    (n) => N(t, n)
  );
  return t.aggregate !== void 0, r;
}
function g(t) {
  return (t.aggregate || "SUM").toUpperCase();
}
function w(t, e) {
  if (t.aggregate && e.aggregate && t.aggregate !== e.aggregate)
    throw new Error(
      `Metric "${t.name}" was requested with conflicting aggregate semantics: ${t.aggregate} and ${e.aggregate}.`
    );
  return {
    ...O(t, e),
    aggregate: t.aggregate || e.aggregate
  };
}
function Q(t) {
  if ("sort" in t)
    throw new Error(
      "useSemaphorRecords supports orderBy for a single deterministic sort. Multiple sort clauses are not supported by the analytics protocol yet."
    );
  if (!tt(t))
    throw new Error(
      "useSemaphorRecords needs at least one field."
    );
  const e = G(t.fields);
  return {
    version: 1,
    kind: "records",
    id: t.id,
    label: t.label,
    source: k(t),
    fields: e,
    dateField: t.dateField ? s(t.dateField, "date") : void 0,
    timeGrain: t.timeGrain,
    orderBy: t.orderBy ? {
      field: s(t.orderBy.field),
      direction: t.orderBy.direction
    } : void 0,
    inputs: D(t.inputs),
    limit: t.limit
  };
}
function G(t) {
  return t.map((e) => {
    const r = s(e);
    if (!r.role)
      throw new Error(
        `useSemaphorRecords field "${r.name}" needs an explicit role.`
      );
    return r;
  });
}
function J(t) {
  return {
    version: 1,
    kind: "inputOptions",
    id: t.id,
    label: t.label,
    source: k(t),
    field: s(t.field, "dimension"),
    search: t.search,
    limit: t.limit
  };
}
function H(t) {
  if ("toAnalyticsInput" in t) {
    const e = t.toAnalyticsInput();
    return {
      inputId: e.inputId,
      ...e.field ? { field: e.field } : {}
    };
  }
  return {
    inputId: t.inputId,
    ...t.field ? { field: t.field } : {}
  };
}
function vt(t) {
  const e = D(t);
  return e.length > 0 ? e : void 0;
}
function W(t) {
  return (t || []).map(Z);
}
function B(t) {
  return W(t).filter((e) => e.isActive);
}
function X(t) {
  return t.kind === "filter" ? {
    inputId: t.id,
    kind: t.kind,
    label: t.label,
    field: s(t.field, "dimension"),
    operator: t.operator || "in"
  } : {
    inputId: t.id,
    kind: t.kind,
    label: t.label
  };
}
function Y(t = []) {
  return t.map(
    (e) => typeof e == "object" ? e : {
      label: String(e),
      value: e
    }
  );
}
function A(t) {
  return t == null ? !1 : Array.isArray(t) ? t.length > 0 : typeof t == "string" ? t.trim().length > 0 : !0;
}
function Z(t) {
  return "toAnalyticsInput" in t ? t.toAnalyticsInput() : "kind" in t && "isActive" in t ? t : {
    ...t,
    kind: "filter",
    isActive: A(
      t.value
    ),
    value: t.value
  };
}
function k(t) {
  return t.source;
}
function tt(t) {
  var e;
  return !!((e = t.fields) != null && e.length);
}
function s(t, e) {
  return {
    ...t,
    role: t.role || e
  };
}
function D(t) {
  return (t || []).map(H);
}
function et(t) {
  if (t)
    return t;
}
function rt() {
  return {
    executeMetric: (t, e) => v(t, e),
    executeRecords: (t, e) => v(t, e),
    executeInputOptions: (t, e) => v(t, e)
  };
}
async function v(t, e) {
  if (!e.token)
    throw new Error("SemaphorDataAppProvider needs a token to execute queries.");
  const r = await fetch(it(e), {
    method: "POST",
    headers: {
      "Content-Type": "application/json",
      Authorization: `Bearer ${e.token}`
    },
    body: JSON.stringify({
      intent: t,
      activeInputs: e.activeInputs,
      resultShape: t.kind
    })
  }), n = await nt(r);
  if (!r.ok || n.error)
    throw new Error(
      n.error || `Semaphor Data App execution failed with status ${r.status}.`
    );
  return n;
}
async function nt(t) {
  const e = await t.text().catch(() => "");
  if (!e.trim())
    return t.ok ? {
      error: "Semaphor Data App execution returned an empty response."
    } : {};
  try {
    return JSON.parse(e);
  } catch {
    return t.ok ? {
      error: "Semaphor Data App execution returned invalid JSON.",
      details: e
    } : {
      error: ot(t, e),
      details: e
    };
  }
}
function ot(t, e) {
  const r = t.statusText ? ` ${t.statusText}` : "", n = e.replace(/\s+/g, " ").trim();
  return n ? `Semaphor Data App execution failed with status ${t.status}${r}: ${n.slice(0, 240)}` : `Semaphor Data App execution failed with status ${t.status}${r}.`;
}
function it(t) {
  const e = at(t).replace(/\/+$/, "");
  return e ? e.endsWith("/api") ? `${e}/v1/data-app/execute` : `${e}/api/v1/data-app/execute` : "/api/v1/data-app/execute";
}
function at(t) {
  if (t.apiBaseUrl)
    return t.apiBaseUrl;
  if (!t.token)
    return "";
  try {
    return q(t.token).apiServiceUrl || "";
  } catch {
    return "";
  }
}
const $ = T({});
function ut() {
  if (!(typeof window > "u"))
    return window.__SEMAPHOR_DATA_APP_RUNTIME__;
}
function st() {
  return U($);
}
function St({
  token: t,
  apiBaseUrl: e,
  executor: r,
  children: n
}) {
  var l;
  const o = ut(), a = ((l = o == null ? void 0 : o.authToken) == null ? void 0 : l.accessToken) || t, i = (o == null ? void 0 : o.dataApiBaseUrl) || (o == null ? void 0 : o.apiBaseUrl) || e, p = m(() => rt(), []), u = r || p, c = m(
    () => ({
      token: a,
      apiBaseUrl: i,
      executor: u
    }),
    [i, u, a]
  );
  return /* @__PURE__ */ C($.Provider, { value: c, children: n });
}
const S = { value: null }, lt = { records: [] }, I = { options: [] };
function dt(t) {
  const e = B(t.inputs);
  try {
    const r = P(t), n = E(r);
    return n ? {
      error: n,
      activeInputs: e,
      queryKey: d(void 0, e, n),
      idleData: S
    } : {
      intent: r,
      error: null,
      activeInputs: e,
      queryKey: d(r, e),
      idleData: S
    };
  } catch (r) {
    const n = y(r);
    return {
      error: n,
      activeInputs: e,
      queryKey: d(void 0, e, n),
      idleData: S
    };
  }
}
function ct(t) {
  const e = B(t.inputs), r = lt;
  try {
    const n = Q(t), o = E(n);
    return o ? {
      error: o,
      activeInputs: e,
      queryKey: d(void 0, e, o),
      idleData: r
    } : {
      intent: n,
      error: null,
      activeInputs: e,
      queryKey: d(n, e),
      idleData: r
    };
  } catch (n) {
    const o = y(n);
    return {
      error: o,
      activeInputs: e,
      queryKey: d(void 0, e, o),
      idleData: r
    };
  }
}
function ft(t) {
  try {
    const e = J(t), r = E(e);
    return r ? {
      error: r,
      queryKey: d(void 0, void 0, r),
      idleData: I
    } : {
      intent: e,
      error: null,
      queryKey: d(e),
      idleData: I
    };
  } catch (e) {
    const r = y(e);
    return {
      error: r,
      queryKey: d(void 0, void 0, r),
      idleData: I
    };
  }
}
function y(t) {
  return t instanceof Error ? t : new Error(String(t));
}
function E(t) {
  const e = K(t);
  if (e.ok)
    return null;
  const r = e.errors.map(
    (n) => n.path ? `${n.code} at ${n.path}: ${n.message}` : `${n.code}: ${n.message}`
  ).join("; ");
  return new Error(`Invalid Semaphor analytics intent. ${r}`);
}
function d(t, e, r) {
  return JSON.stringify({
    intent: t,
    activeInputs: e,
    error: r == null ? void 0 : r.message
  });
}
function It(t) {
  const [e, r] = b(t.defaultValue), n = Object.prototype.hasOwnProperty.call(t, "value"), o = n ? t.value : e, a = m(
    () => Y(t.options),
    [t.options]
  ), i = h(
    (u) => {
      var l;
      const c = u;
      (l = t.onValueChange) == null || l.call(t, c), n || r(c);
    },
    [n, t]
  ), p = h(() => i(void 0), [i]);
  return m(() => {
    const u = X(t);
    return {
      id: t.id,
      kind: t.kind,
      label: t.label,
      field: u.field,
      operator: u.operator,
      controlRole: t.kind === "control" ? t.role : void 0,
      value: o,
      options: a,
      isActive: A(o),
      setValue: i,
      clear: p,
      toAnalyticsInput: () => ({
        inputId: u.inputId,
        field: u.field,
        kind: t.kind,
        label: t.label,
        value: o,
        isActive: A(o),
        operator: u.operator,
        controlRole: t.kind === "control" ? t.role : void 0
      })
    };
  }, [p, a, i, t, o]);
}
function At(t) {
  const e = m(() => dt(t), [t]), r = h(
    (a) => {
      var i;
      return e.intent ? (i = a.executor) == null ? void 0 : i.executeMetric(e.intent, a) : void 0;
    },
    [e.intent]
  ), n = M(
    e.queryKey,
    r,
    e.idleData,
    e.activeInputs
  ), o = e.error ? e.idleData : n.data;
  return {
    id: t.id,
    intent: e.intent,
    value: (o == null ? void 0 : o.value) ?? null,
    metrics: o == null ? void 0 : o.metrics,
    comparisonValue: o == null ? void 0 : o.comparisonValue,
    delta: o == null ? void 0 : o.delta,
    deltaPercent: o == null ? void 0 : o.deltaPercent,
    records: o == null ? void 0 : o.records,
    status: e.error ? "error" : n.status,
    isLoading: !e.error && n.status === "loading",
    error: e.error || n.error
  };
}
function kt(t) {
  const e = m(() => ct(t), [t]), r = h(
    (a) => {
      var i;
      return e.intent ? (i = a.executor) == null ? void 0 : i.executeRecords(e.intent, a) : void 0;
    },
    [e.intent]
  ), n = M(
    e.queryKey,
    r,
    e.idleData,
    e.activeInputs
  ), o = e.error ? e.idleData : n.data;
  return {
    id: t.id,
    intent: e.intent,
    records: (o == null ? void 0 : o.records) || [],
    columns: o == null ? void 0 : o.columns,
    rowCount: o == null ? void 0 : o.rowCount,
    status: e.error ? "error" : n.status,
    isLoading: !e.error && n.status === "loading",
    error: e.error || n.error
  };
}
function Dt(t) {
  const e = m(() => ft(t), [t]), r = h(
    (a) => {
      var i;
      return e.intent ? (i = a.executor) == null ? void 0 : i.executeInputOptions(e.intent, a) : void 0;
    },
    [e.intent]
  ), n = M(
    e.queryKey,
    r,
    e.idleData
  ), o = e.error ? e.idleData : n.data;
  return {
    id: t.id,
    intent: e.intent,
    options: (o == null ? void 0 : o.options) || [],
    status: e.error ? "error" : n.status,
    isLoading: !e.error && n.status === "loading",
    error: e.error || n.error
  };
}
function M(t, e, r, n) {
  const o = st(), a = R(e), i = R(n), [p, u] = b({
    status: "idle",
    data: r,
    error: null
  });
  return a.current = e, i.current = n, _(() => {
    let c;
    try {
      c = a.current({
        ...o,
        activeInputs: i.current
      });
    } catch (f) {
      u({
        status: "error",
        data: r,
        error: y(f)
      });
      return;
    }
    if (!c) {
      u({ status: "idle", data: r, error: null });
      return;
    }
    let l = !1;
    return u((f) => ({
      status: "loading",
      data: f.data,
      error: null
    })), c.then((f) => {
      l || u({ status: "success", data: f, error: null });
    }).catch((f) => {
      l || u({
        status: "error",
        data: r,
        error: y(f)
      });
    }), () => {
      l = !0;
    };
  }, [r, t, o]), p;
}
export {
  $ as SemaphorDataAppContext,
  St as SemaphorDataAppProvider,
  rt as createSemaphorQueryExecutor,
  A as hasSemaphorInputValue,
  Y as normalizeSemaphorInputOptions,
  ut as readWindowRuntime,
  B as toSemaphorActiveInputSnapshots,
  H as toSemaphorInputBinding,
  vt as toSemaphorInputBindings,
  J as toSemaphorInputOptionsIntent,
  W as toSemaphorInputSnapshots,
  X as toSemaphorInputSpec,
  P as toSemaphorMetricIntent,
  Q as toSemaphorRecordsIntent,
  st as useSemaphorDataAppRuntime,
  It as useSemaphorInput,
  Dt as useSemaphorInputOptions,
  At as useSemaphorMetric,
  kt as useSemaphorRecords
};
