import { z as i } from "zod";
import { alamos as V } from "@synnaxlabs/alamos";
import { NotFoundError as Z, UnexpectedError as f, ValidationError as D } from "@synnaxlabs/client";
import { shallow as Y, deep as N, status as x, color as o } from "@synnaxlabs/x";
import { e as K, s as u } from "./types-CGRCBVD4.js";
const F = (r, t, e = "") => {
  try {
    return r.parse(t);
  } catch (n) {
    if (n instanceof i.ZodError) {
      const s = n.issues.map((a) => a.path.length === 0 ? a.message : `${a.path.join(".")}: ${a.message}`);
      throw new Error(`${e} - ${s.join(`
`)}`);
    } else throw n;
  }
}, A = (r, t) => r instanceof Error ? (r.message = `[${t}] - ${r.message}`, r) : new Error(t ?? "unknown error", { cause: r }), L = (r) => {
  const t = r._zod.def.output;
  return t instanceof i.ZodVoid || t instanceof i.ZodNever || t instanceof i.ZodUnknown;
};
class T {
  type;
  key;
  sender;
  _internalState;
  _state;
  _prevState;
  _deleted = !1;
  parentCtxValues;
  childCtxValues;
  childCtxChangedKeys;
  instrumentation;
  schema = void 0;
  /**
   * Methods schema for invoke. Define this to enable invokable methods.
   * Method names in the schema must match method names on the class.
   */
  methods = void 0;
  _methodImplementations = null;
  constructor({
    key: t,
    type: e,
    sender: n,
    instrumentation: s,
    parentCtxValues: a
  }) {
    this.type = e, this.key = t, this.sender = n, this._internalState = {}, this.instrumentation = s.child(this.toString()), this.parentCtxValues = /* @__PURE__ */ new Map(), a?.forEach((c, h) => this.parentCtxValues.set(h, c)), this.childCtxValues = /* @__PURE__ */ new Map(), this.childCtxChangedKeys = /* @__PURE__ */ new Set();
  }
  initializeMethods() {
    if (!(this.methods == null || this._methodImplementations != null)) {
      this._methodImplementations = {};
      for (const [t, e] of Object.entries(this.methods)) {
        const n = this[t];
        if (typeof n != "function")
          throw new Error(`Method ${t} is not a function`);
        this._methodImplementations[t] = L(e) ? e.implement(n.bind(this)) : e.implementAsync(n.bind(this));
      }
    }
  }
  get _schema() {
    if (this.schema == null)
      throw new D(
        `[AetherLeaf] - expected subclass to define component schema, but none was found.
        Make sure to define a property 'schema' on the class.`
      );
    return this.schema;
  }
  /**
   * Sets the state on the component, communicating the change to the corresponding
   * React component on the main thread.
   *
   * @param next - The new state to set on the component. This can be the state object
   * or a pure function that takes in the previous state and returns the next state.
   */
  setState(t) {
    const e = K(t, this.state);
    this._prevState = Y.copy(this._state), this._state = F(this._schema, e, `${this.toString()}`), this.sender.send({ variant: "update", key: this.key, state: this._state });
  }
  /** @returns the current state of the component. */
  get state() {
    if (this._state == null)
      throw new f(
        `[AetherLeaf] - state not defined in ${this.toString()}`
      );
    return this._state;
  }
  get internal() {
    return this._internalState;
  }
  /** @returns the previous state of the component. */
  get prevState() {
    if (this._prevState === void 0) throw new Error("prevState not defined");
    return this._prevState;
  }
  get deleted() {
    return this._deleted;
  }
  get ctx() {
    return {
      get: (t) => {
        const e = this.parentCtxValues.get(t);
        if (e === void 0)
          throw new Z(
            `Context value for ${t} not found on ${this.toString()}`
          );
        return e;
      },
      getOptional: (t) => this.parentCtxValues.get(t),
      has: (t) => this.parentCtxValues.has(t),
      wasSetPreviously: (t) => this.childCtxValues.has(t),
      set: (t, e, n = !0) => {
        this.childCtxValues.set(t, e), n && this.childCtxChangedKeys.add(t);
      }
    };
  }
  toString() {
    return `${this.type}(${this.key})`;
  }
  /**
   * @implements AetherComponent, and should NOT be called by a subclass other than
   * AetherComposite.
   */
  _updateState({ path: t, state: e }) {
    if (!this.deleted)
      try {
        this.initializeMethods();
        const n = this.instrumentation.T.debug(`${this.toString()}:updateState`);
        this.validatePath(t);
        const s = F(this._schema, e, `${this.toString()}`);
        this._state != null ? this.instrumentation.L.debug("updating state", () => ({
          diff: N.difference(this.state, s)
        })) : this.instrumentation.L.debug("setting initial state", { state: e, path: t }), this._prevState = this._state ?? s, this._state = s, this.afterUpdate(this.ctx), n();
      } catch (n) {
        throw A(n, `${this.toString()}.updateState`);
      }
  }
  _updateContext(t) {
    try {
      const e = this.instrumentation.T.debug(`${this.toString()}:updateContext`);
      t.forEach((n, s) => this.parentCtxValues.set(s, n)), this.afterUpdate(this.ctx), e();
    } catch (e) {
      throw A(e, `${this.type}.${this.key}.updateContext`);
    }
  }
  /**
   * @implements AetherComponent, and should NOT be called by a subclass other than
   * AetherComposite.
   */
  _delete(t) {
    try {
      const e = this.instrumentation.T.debug(`${this.toString()}:delete`);
      this.validatePath(t), this._deleted = !0, this.afterDelete(this.ctx), e();
    } catch (e) {
      throw A(e, `[${this.toString()}:delete]`);
    }
  }
  /**
   * afterUpdate is optionally defined by a subclass, allowing the component to
   * perform some action after the component is updated. At this point, the current
   * state, previous state, derived state, and current context are all available to
   * the component.
   */
  afterUpdate(t) {
  }
  /**
   * Runs after the component has been spliced out of the tree. This is useful for
   * running cleanup code, such as unsubscribing from an event emitter. At this point,
   * the current state, previous state, derived state, and current context are all
   * available to the component, and this.deleted is true.
   */
  afterDelete(t) {
  }
  validatePath(t) {
    if (t.length === 0)
      throw new f(
        `[Leaf.setState] - ${this.toString()} received an empty path`
      );
    const e = t[t.length - 1];
    if (t.length > 1)
      throw new f(
        `[Leaf.setState] - ${this.toString()} received a subPath ${t.join(
          "."
        )} but is a leaf`
      );
    if (e !== this.key)
      throw new f(
        `[Leaf.setState] - ${this.toString()} received a key ${e} but expected ${this.key}`
      );
  }
  handleInvokeError({ method: t, key: e, args: n }, s) {
    if (!(e != null))
      return console.error(
        `Error in fire and forget method ${t} on ${this.toString()}`,
        s
      );
    const c = s instanceof Error ? s : new Error(String(s));
    this.sender.send({
      variant: "invoke_response",
      key: e,
      result: void 0,
      error: {
        name: c.name,
        message: `Failed to execute ${t}(${e}) with args ${JSON.stringify(n)} on ${this.toString()}: ${c.message}`,
        stack: c.stack ?? ""
      }
    });
  }
  _invokeMethod(t) {
    if (this.deleted) return;
    const { method: e, key: n, args: s } = t, a = n != null, c = this._methodImplementations?.[e];
    if (c == null)
      return this.handleInvokeError(
        t,
        new Error(`Method ${e} not found on ${this.toString()}`)
      );
    try {
      const h = c(...s);
      h instanceof Promise && h.then((m) => {
        a && this.sender.send({ variant: "invoke_response", key: n, result: m });
      }).catch((m) => this.handleInvokeError(t, m));
    } catch (h) {
      this.handleInvokeError(t, h);
    }
  }
}
class _ extends T {
  _children = /* @__PURE__ */ new Map();
  /** @returns a readonly array of the children of the component. */
  get children() {
    return Array.from(this._children.values());
  }
  /**
   * Finds a child component with the given key.
   *
   * @param key - the key of the child component to find.
   * @returns the child component, or null if no child component with the given key
   */
  getChild(t) {
    return this._children.get(t) ?? null;
  }
  /**
   * Finds all children of the component with the given type
   *
   * @param types - the type of the children to find
   * @returns an array of all children of the component with the given type
   */
  childrenOfType(...t) {
    return this.children.filter(
      (e) => t.includes(e.type)
    );
  }
  _updateState(t) {
    const { path: e, type: n, create: s } = t;
    if (this.deleted) return;
    const a = this.parsePath(e);
    if (a.length === 0) {
      if (this.childCtxChangedKeys.clear(), super._updateState(t), this.childCtxChangedKeys.size == 0) return;
      this.updateChildContexts();
      return;
    }
    const h = a[0], m = this.getChild(h);
    if (m != null) return m._updateState({ ...t, path: a });
    if (a.length > 1) {
      const I = e.slice(0, e.indexOf(h) + 1).join("."), R = e.join(".");
      throw new f(
        `Child of ${this.toString()} at path ${I} does not exist,
        but an extended path ${R} was provided. This means that the aether
        tree is attempting to create a new child  of type ${n} (or nested children)
        on a child that does not exist.

        Children present: ${this.children.map((k) => `${k.type}:${k.key}`).join(".")}

        `
      );
    }
    const $ = s(this.childCtx());
    $._updateState({ ...t, path: a }), this._children.set(h, $);
  }
  _updateContext(t) {
    super._updateContext(t), this.updateChildContexts();
  }
  childCtx() {
    return {
      get: (t) => this.childCtxValues.get(t) ?? this.parentCtxValues.get(t),
      forEach: (t) => {
        this.childCtxValues.forEach(
          (e, n) => t(e, n, this.childCtxValues)
        ), this.parentCtxValues.forEach((e, n) => {
          this.childCtxValues.has(n) || t(e, n, this.parentCtxValues);
        });
      }
    };
  }
  updateChildContexts() {
    const t = this.childCtx();
    this.children.forEach((e) => e._updateContext(t));
  }
  _delete(t) {
    const e = this.parsePath(t);
    if (e.length === 0) {
      for (const s of this.children) s._delete([s.key]);
      this._children.clear(), super._delete([this.key]);
    }
    const n = this.getChild(e[0]);
    if (n != null) {
      if (e.length > 1) return n._delete(e);
      this._children.delete(n.key), n._delete(e);
    }
  }
  /**
   * Find a child component at the given path for method invocation.
   * @param path - The path to the child component (excluding this component's key).
   * @returns The component at the path, or null if not found.
   */
  findChildAtPath(t) {
    if (t.length === 0) return null;
    const [e, ...n] = t, s = this.getChild(e);
    return s == null ? null : n.length === 0 ? s : "findChildAtPath" in s && typeof s.findChildAtPath == "function" ? s.findChildAtPath(n) : null;
  }
  parsePath(t, e) {
    const [n, ...s] = t;
    if (n == null)
      throw new Error(
        `Composite ${this.toString()} received an empty path${e != null ? ` for ${e}` : ""}`
      );
    if (n !== this.key)
      throw new f(
        `[Composite.getRequiredKey] - ${this.toString()} received a key ${n} but expected ${this.key}`
      );
    return s;
  }
}
const B = i.object({}), M = () => {
  throw new Error("should not call create");
};
class d extends _ {
  /** Key of the root component. */
  static TYPE = "root";
  /** Type of the root component. */
  static KEY = "root";
  /** A communication mechanism for sending messages to the main thread. */
  comms;
  /** A registry used for creating new components in the tree. */
  registry;
  schema = B;
  constructor({
    comms: t,
    instrumentation: e = V.Instrumentation.NOOP,
    registry: n
  }) {
    super({
      key: d.KEY,
      type: d.TYPE,
      sender: t,
      instrumentation: e,
      parentCtxValues: null
    }), this.comms = t, this.registry = n;
  }
  /**
   * Creates a new aether tree with the provided props, and starts listing for state
   * updates on the provided comms.
   */
  static render(t) {
    const e = new d(t);
    return e._updateState({
      path: [d.KEY],
      type: "",
      state: {},
      create: M
    }), e.comms.handle((n) => {
      try {
        e.handle(n);
      } catch (s) {
        const a = {
          name: "unknown",
          message: JSON.stringify(s),
          stack: "unknown"
        };
        s instanceof Error && (a.name = s.name, a.message = s.message, a.stack = s.stack), e.comms.send({ variant: "error", error: a });
      }
    }), e;
  }
  /**
   * Handles messages from the main thread and applies them as updates in the
   * aether tree.
   */
  handle(t) {
    const { variant: e } = t;
    if (e === "invoke_request") {
      this.invokeAtPath(t);
      return;
    }
    const { path: n, type: s } = t;
    if (e === "delete") {
      this._delete(n);
      return;
    }
    const { state: a } = t;
    this._updateState({
      path: n,
      type: s,
      state: a,
      create: (c) => {
        const h = n[n.length - 1];
        return this.create({ key: h, type: s, parentCtxValues: c });
      }
    });
  }
  invokeAtPath(t) {
    const { path: e } = t, [n, ...s] = e;
    if (n !== d.KEY) {
      this.handleInvokeError(
        t,
        new Error(`Invalid path: expected root key '${d.KEY}', got '${n}'`)
      );
      return;
    }
    if (s.length === 0) {
      this._invokeMethod(t);
      return;
    }
    const a = this.findChildAtPath(s);
    if (a == null) {
      this.handleInvokeError(
        t,
        new Z(`Component at path ${e.join(".")} not found`)
      );
      return;
    }
    a._invokeMethod(t);
  }
  /** Creates a new component from the registry */
  create({
    key: t,
    type: e,
    parentCtxValues: n
  }) {
    const s = this.registry[e];
    if (s == null)
      throw new f(`[Root.create] - ${e} not found in registry`);
    return new s({
      key: t,
      type: e,
      sender: this.comms,
      instrumentation: this.instrumentation,
      parentCtxValues: n
    });
  }
}
const U = d.render.bind(d), wt = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({
  __proto__: null,
  Composite: _,
  Leaf: T,
  Root: d,
  isFireAndForget: L,
  render: U
}, Symbol.toStringTag, { value: "Module" })), G = (r, t) => Array.isArray(t) ? t.some((e) => e.matches(r)) : t?.matches(r) ?? !1, X = (r) => {
  console.error(x.toString(r));
}, z = (r, t, e) => {
  const n = x.fromException(r, t);
  return X(n), G(r, e) ? null : n;
}, H = (r, t, e, n) => {
  if (typeof r == "function") return !0;
  const s = z(r, e, n);
  return s != null && t(s), !1;
}, j = async (r, t, e, n) => {
  try {
    const s = r();
    s != null && await s;
  } catch (s) {
    const a = z(s, e, n);
    if (a != null) return t(a);
  }
}, W = (r) => (t, e, n) => {
  H(t, r, e, n) && j(t, r, e, n);
}, q = (r) => async (t, e, n) => {
  H(t, r, e, n) && await j(t, r, e, n);
}, J = i.object({ statuses: x.statusZ().array() }), w = "status.aggregator";
class P extends _ {
  static TYPE = "status.Aggregator";
  schema = J;
  afterUpdate(t) {
    t.wasSetPreviously(w) || t.set(w, {
      add: this.add.bind(this),
      create: x.create
    });
  }
  add(t) {
    this.setState((e) => ({
      ...e,
      statuses: [...e.statuses, x.create(t)]
    }));
  }
}
const O = (r) => r.get(w).add, Et = (r) => {
  const t = r.getOptional(w);
  return t != null ? t.add : () => {
  };
}, Q = (r) => W(O(r)), _t = (r) => q(O(r)), At = {
  [P.TYPE]: P
}, tt = i.object({
  // Main background surface
  l0: o.colorZ,
  // Large surfaces to contrast against background
  l1: o.colorZ,
  // Small surfaces to contrast against background
  l2: o.colorZ,
  // Hover on small surfaces
  l3: o.colorZ,
  // Border strength 1
  l4: o.colorZ,
  // Border strength 2
  // Border strength 1 hover
  l5: o.colorZ,
  // Border strength 2 hover
  // Border strength 1 active
  l6: o.colorZ,
  // Border strength 2 active
  l7: o.colorZ,
  // Text strength 1
  l8: o.colorZ,
  // Text strength 2
  l9: o.colorZ,
  // Text strength 3
  l10: o.colorZ,
  // Text strength 4
  l11: o.colorZ
}), l = (r, t) => [
  r[0],
  r[1],
  t,
  r[3]
], et = i.object({
  m2: o.colorZ,
  m1: o.colorZ,
  z: o.colorZ,
  p1: o.colorZ,
  p2: o.colorZ
}), C = et.or(
  o.colorZ.transform((r) => {
    const t = o.hsla(r);
    return {
      m2: o.fromHSLA(l(t, 40)),
      m1: o.fromHSLA(l(t, 45)),
      z: r,
      p1: o.fromHSLA(l(t, 55)),
      p2: o.fromHSLA(l(t, 65))
    };
  })
), nt = i.object({
  name: i.string(),
  key: i.string(),
  colors: i.object({
    border: o.colorZ,
    primary: C,
    gray: tt,
    error: C,
    secondary: C,
    warning: C,
    palettes: i.record(i.string(), o.paletteZ),
    visualization: i.object({ palettes: i.record(i.string(), i.array(o.colorZ)) }).default({ palettes: {} }),
    white: o.colorZ,
    black: o.colorZ,
    text: o.colorZ,
    textInverted: o.colorZ,
    textOnPrimary: o.colorZ.default(o.ZERO),
    primaryText: o.colorZ,
    errorText: o.colorZ,
    warningText: o.colorZ,
    logo: i.string()
  }),
  sizes: i.object({
    base: i.number(),
    border: i.object({
      radius: i.number(),
      width: i.number(),
      thickWidth: i.number()
    }),
    schematic: i.object({ elementStrokeWidth: i.number() })
  }),
  typography: i.object({
    family: i.string(),
    codeFamily: i.string(),
    h1: u,
    h2: u,
    h3: u,
    h4: u,
    h5: u,
    p: u,
    small: u
  })
}).transform((r) => ((r.colors.textOnPrimary == null || o.isZero(r.colors.textOnPrimary)) && (r.colors.textOnPrimary = o.pickByContrast(
  r.colors.primary.z,
  r.colors.text,
  r.colors.textInverted
)), r)), rt = '"Inter Variable", sans-serif', st = '"Geist Mono", monospace', ot = 6, p = [357, 91, 55, 1], g = [48, 90, 55, 1], it = [
  "#FEFEFE",
  // l0 - background
  "#FAFAFA",
  // l1 - large surfaces
  "#F2F2F2",
  // l2 - small surfaces
  "#ECECEC",
  // l3 - small surfaces hover
  "#E4E4E4",
  // l4 - border 1
  "#D1D1D1",
  // l5 - border 2
  "#BCBCBC",
  // l6 - border 2 hover
  "#ACACAC",
  // l7 - border 2 active
  "#8F8F8F",
  // l8 - text 1
  "#4F4F4F",
  // l9 - text 2
  "#292929",
  // l10 - text 3
  "#050505"
  // l11 - text 4
], y = Object.fromEntries(
  it.map((r, t) => [`l${t}`, r])
), at = () => typeof window > "u" ? !1 : window.devicePixelRatio > 1, ht = at(), b = {
  key: "synnaxBase",
  name: "Synnax Base",
  colors: {
    primary: {
      m2: "#041B3D",
      m1: "#356fc5",
      z: "#3774D0",
      p1: "#5E94EE",
      p2: "#8AB8FF"
    },
    secondary: {
      m2: "#2D8F4E",
      m1: "#38B261",
      z: "#50C878",
      p1: "#73D393",
      p2: "#96DEAE"
    },
    gray: y,
    border: y.l4,
    error: {
      m2: o.fromHSLA(l(p, 30)),
      m1: o.fromHSLA(l(p, 40)),
      z: o.fromHSLA(p),
      p1: o.fromHSLA(l(p, 65)),
      p2: o.fromHSLA(l(p, 77))
    },
    warning: {
      m2: o.fromHSLA(l(g, 30)),
      m1: o.fromHSLA(l(g, 40)),
      z: o.fromHSLA(g),
      p1: o.fromHSLA(l(g, 65)),
      p2: o.fromHSLA(l(g, 75))
    },
    palettes: { recent: { key: "recent", name: "Recent", swatches: [] } },
    visualization: {
      palettes: {
        default: [
          "#DC136C",
          "#20A4F3",
          "#7AC74F",
          "#FFC43D",
          "#FE5F55",
          "#8075FF",
          "#D90429",
          "#f7aef8",
          "#f18f01",
          "#791e94",
          "#279af1",
          "#d9fff5",
          "#ff6b6b",
          "#52ffb8"
        ]
      }
    },
    logo: "url(#synnax-linear-gradient)",
    white: "#FFFFFF",
    black: "#000000",
    text: y.l11,
    textInverted: y.l0,
    textOnPrimary: y.l0,
    primaryText: "#3b82f6",
    errorText: "#ef4444",
    warningText: "#f59e0b"
  },
  sizes: {
    base: ot,
    border: { radius: 3, width: ht ? 0.5 : 1, thickWidth: 1 },
    schematic: { elementStrokeWidth: 2 }
  },
  typography: {
    family: rt,
    codeFamily: st,
    h1: { size: 5.5, weight: "500", lineHeight: 5.5 * 1.5 },
    h2: { size: 4.5, weight: "medium", lineHeight: 4.5 * 1.5 },
    h3: { size: 3.5, weight: "medium", lineHeight: 3.5 * 1.5 },
    h4: { size: 2.6666, weight: "medium", lineHeight: 2.6666 * 1.5 },
    h5: { size: 2.333333, weight: 450, lineHeight: 2.333333 * 1.5 },
    p: { size: 2.1666666666, weight: "regular", lineHeight: 2 * 1.5 },
    small: { size: 1.916666, weight: "regular", lineHeight: 2.3333333 }
  }
}, lt = Object.freeze({
  ...b,
  key: "synnaxLight",
  name: "Synnax Light"
}), ct = [
  "#020202",
  // l0
  "#080808",
  // l1
  "#151515",
  // l2
  "#202020",
  // l3
  "#272727",
  // l4
  "#3B3B3B",
  // l5
  "#4A4A4A",
  // l6
  "#5C5C5C",
  // l7
  "#767676",
  // l8
  "#959595",
  // l9
  "#dadada",
  // l10
  "#FAFAFA"
  // l11
], S = Object.fromEntries(
  ct.map((r, t) => [`l${t}`, r])
), dt = Object.freeze({
  ...b,
  key: "synnaxDark",
  name: "Synnax Dark",
  colors: {
    ...b.colors,
    gray: S,
    logo: "var(--pluto-text-color)",
    border: S.l4,
    text: S.l11,
    textInverted: S.l0,
    textOnPrimary: S.l11,
    primaryText: "#93c5fd",
    errorText: "#fca5a5",
    warningText: "#fcd34d"
  }
}), bt = { synnaxDark: dt, synnaxLight: lt }, ut = ["tiny", "small", "medium", "large", "huge"], ft = i.enum(ut), vt = (r) => ft.safeParse(r).success, v = "pluto-theming-context", mt = i.object({
  name: i.string(),
  url: i.string()
}), pt = i.object({
  theme: nt,
  fontURLs: i.array(mt)
});
class E extends _ {
  static TYPE = "theming.Provider";
  static z = pt;
  schema = E.z;
  afterUpdate(t) {
    if (t.getOptional(v) != null && this.state.theme.key === this.prevState.theme.key) return;
    t.set(v, this.state.theme), Q(t)(async () => {
      await this.loadFonts();
    }, "failed to load theme fonts");
  }
  async loadFonts() {
    await Promise.all(
      this.state.fontURLs.map(async ({ name: t, url: e }) => {
        const n = new FontFace(t, `url(${e})`);
        try {
          await n.load(), self.fonts.add(n);
        } catch (s) {
          console.error(s);
        }
      })
    );
  }
}
const $t = (r) => r.get(v), kt = {
  [E.TYPE]: E
};
export {
  P as A,
  _ as C,
  T as L,
  E as P,
  kt as R,
  dt as S,
  lt as a,
  bt as b,
  At as c,
  wt as d,
  O as e,
  mt as f,
  Q as g,
  L as h,
  vt as i,
  W as j,
  J as k,
  q as l,
  _t as m,
  Et as n,
  ut as o,
  F as p,
  U as r,
  ft as s,
  nt as t,
  $t as u
};
