import { nextTick as b } from "vue";
import { Widget as N } from "@bryntum/taskboard";
class c {
  /**
   * Development warning. Showed when environment is set to 'development'
   * @param {String} clsName vue component instance
   * @param {String} msg console message
   */
  static devWarning(t, e) {
    (window.bryntum?.isTestEnv || process.env.NODE_ENV === "development") && console.warn(
      `Bryntum${t}Component development warning!
${e}
Please check Vue integration guide: https://bryntum.com/products/grid/docs/guide/Grid/integration/vue/guide`
    );
  }
  static devWarningContainer(t, e) {
    c.devWarning(
      t,
      `Using "${e}" parameter for configuration is not recommended.
Widget is placed automatically inside it's container element.
Solution: remove "${e}" parameter from configuration.`
    );
  }
  static devWarningConfigProp(t, e) {
    c.devWarning(
      t,
      `Using "${e}" parameter for configuration is not recommended.
Solution: Use separate parameter for each "${e}" value to enable reactive updates of the API instance`
    );
  }
  static devWarningUpdateProp(t, e) {
    c.devWarning(
      t,
      `"${e}" is a static config option for component constructor only. No runtime changes are supported!`
    );
  }
  static camelize(t) {
    return t.replace(/-./g, (e) => (e[1] || "").toUpperCase());
  }
  static capitalize(t) {
    return t.charAt(0).toUpperCase() + t.slice(1);
  }
  /**
   * Returns `true` if the provided configuration object is valid for Vue processing.
   * @param {*} config
   * @returns {Boolean}
   */
  static isVueConfig(t) {
    return !!t?.vue;
  }
  /**
   * Creates bryntum component config from vue component
   * @param {Object} context
   * @param {Object} context.me vue component instance
   * @param {Object} context.widgetData reference to data
   * @param {Function} context.emit reference to emit
   * @param {Object} context.element HTML element
   * @param {Function} context.processCellContent cell renderer method
   * @param {Function} context.processEventContent event renderer method
   * @param {Function} context.processWidgetContent widget renderer method
   * @param {Function} context.hasFrameworkRenderer checks presence of vue renderer
   * @param {Function} context.toRaw Vue fn to unwrap reactive object
   * @returns {Object} config object
   */
  static createConfig({
    me: t,
    widgetData: e,
    emit: n,
    element: i,
    processCellContent: o,
    processEventContent: s,
    processWidgetContent: l,
    hasFrameworkRenderer: r,
    toRaw: d
  }) {
    const f = {}, u = t.vnode.props || {};
    for (const a of Object.keys(u))
      f[this.camelize(a)] = u[a];
    const {
      instanceClass: m,
      instanceName: v
    } = e, y = (a) => f[a] !== void 0, p = (e.configNames || []).filter(y), C = (e.propertyConfigNames || []).filter(y), h = (e.propertyNames || []).filter(y), $ = (e.featureNames || []).filter(y), E = e.eventNames.filter((a) => !y(a) && !f[`on${this.capitalize(a)}`]), g = {
      vueComponent: t,
      listeners: {},
      features: {},
      processCellContent: o,
      processEventContent: s,
      processWidgetContent: l,
      hasFrameworkRenderer: r
    };
    E.forEach((a) => g.listeners[a] = (P) => n(a, P)), [
      ...p,
      ...C,
      ...$
    ].forEach((a) => {
      c.applyPropValue(g, a, f[a], !0, d), ["features", "config"].includes(a) && c.devWarningConfigProp(m.$name, a);
    }), g.cls = (g.cls || "") + ` b-vue-${m.$name.toLowerCase()}-container`, e.configNames = p, e.propertyNames = [
      ...p,
      ...h,
      ...C,
      ...$
    ], e.eventNames = [], e.propertyConfigNames = [], e.featureNames = [];
    const V = [
      "adopt",
      "appendTo",
      "insertAfter",
      "insertBefore"
    ].find((a) => g[a]);
    return V ? c.devWarningContainer(m.$name, V) : v === "Button" ? g.appendTo = i : g.adopt = i, g;
  }
  /**
   * Setup store events relay
   * @param {Object} data reference to data
   * @param {Object} instance bryntum widget instance
   */
  static relayStores(t, e) {
    const { dataStores: n, projectStores: i } = t;
    n && (Object.keys(n).forEach((o) => {
      const s = i ? e.project[o] : e[o];
      s && (s.syncDataOnLoad == null && !s.readUrl && !s.lazyLoad && (!s.crudManager || !s.crudManager.loadUrl) && (s.syncDataOnLoad = !0), e && e.relayStoreEvents && s.relayAll(e, n[o]));
    }), delete t.dataStores);
  }
  /**
   * Creates bryntum Widget from vue component
   * @param {Object} config
   * @param {Object} config.me vue component instance
   * @param {Object} config.widgetData reference to data
   * @param {Function} config.emit reference to emit
   * @param {Object} config.element HTML element
   * @param {Function} config.processCellContent cell renderer method
   * @param {Function} config.hasFrameworkRenderer check the presence of vue renderer
   * @param {Function} config.toRaw Vue fn to unwrap reactive object
   * @returns {Object} widget object
   */
  static createWidget(t) {
    const { instanceClass: e } = t.widgetData, n = c.createConfig(t);
    return e.$name === "Widget" ? N.create(n) : new e(n);
  }
  /**
   * Applies property value to Bryntum config or instance.
   * @param {Object} configOrInstance target object
   * @param {String} prop property name
   * @param {Object} value value
   * @param {Boolean} [isConfig] config setting mode
   * @param {Function} [toRaw] Vue fn to unwrap reactive object
   */
  static applyPropValue(t, e, n, i = !0, o) {
    if (e === "project")
      n && typeof n == "object" && (t[e] = n.instance ? n.instance.value || n.instance : n);
    else if (e === "features" && typeof n == "object")
      Object.keys(n).forEach((s) => c.applyPropValue(t, `${s}Feature`, n[s], i, o));
    else if (e === "config" && typeof n == "object")
      Object.keys(n).forEach((s) => c.applyPropValue(t, s, n[s], i, o));
    else if (e === "columns" && !i)
      t.columns.data = n;
    else if (e.endsWith("Feature")) {
      const s = t.features, l = e.replace("Feature", "");
      if (i)
        s[l] = n;
      else {
        const r = s[l];
        r && r.setConfig(n);
      }
    } else
      t[e] = o ? o(n) : n;
  }
  /**
   * Creates watches for vue component properties
   * @param {Object} me vue component instance
   * @param {Object} instance bryntum widget instance
   * @param {Object} props reference to props
   * @param {Object} data reference to data
   * @param {Function} watcher watch method reference (Accepts: prop and newValue)
   */
  static watchProps(t, e, n) {
    const {
      configNames: i,
      propertyNames: o,
      instanceClass: s
    } = e;
    o.forEach((l) => n(l, (r) => {
      const d = Array.isArray(r) ? r.slice() : r;
      c.applyPropValue(t, l, d, !1), i.includes(l) && c.devWarningUpdateProp(s.$name, l);
    })), e.configNames = [], e.propertyNames = [];
  }
  /**
   * Called from Widget.js to add the Vue component to teleports
   * @param {Object} context
   * @param {Widget} context.widget Widget which content is rendered by the Vue component
   * @param {Object} context.html Object containing the Vue component properties and event listeners
   */
  static processWidgetContent({ widget: t, html: e }) {
    const { is: n, bind: i = {}, vue: o, on: s = {} } = e, { vueComponent: l } = this, { teleports: { value: r } } = l.provides, { contentElement: d, id: f } = t;
    if (o) {
      const u = `key-${f}`;
      r.has(u) && r.delete(u), b(() => {
        r.set(u, { bind: i, on: s, key: u, is: n, to: d });
      });
    }
  }
  /**
   * Handles the content provided by a Vue component for the widget.
   * @param {Widget} widget Owner widget
   * @param {String} html The HTML content to be processed
   */
  static handleVueContent(t, e) {
    const n = (s) => !!s.vueComponent?.provides?.teleports, i = t.closest(n);
    (i?.vueComponent ? i : N.query(n))?.processWidgetContent?.({ widget: t, html: e });
  }
  /**
   * Event renderer method
   * @param {Object} context
   * @param {*} context.jsx
   * @param {DomConfig} context.domConfig
   * @param {HTMLElement} context.targetElement
   * @param {Boolean} context.isRelease
   * @returns {Boolean}
   */
  static processEventContent({
    // Core passes it as jsx for React wrappers.
    // Let's rename it to a more appropriate name.
    jsx: t,
    domConfig: e,
    targetElement: n,
    isRelease: i
  }) {
    let o = n, s = !1;
    const l = this.isVertical ? e?.elementData?.renderData : e?.elementData;
    if (c.isVueConfig(t) && t?.is) {
      e?.dataset?.isMilestone ? o = n.parentElement.parentElement.parentElement : o = n.parentElement.parentElement;
      const r = this.isVertical ? o.elementData.renderData : o.elementData, { assignmentRecord: d } = i ? l : r, { eventRecord: f } = r, { vueComponent: u } = this, { teleports: { value: m } } = u.provides, v = f.isRecurring || f.isOccurrence, y = `assignment-${d?.id}${v ? "-" + f.id : ""}`;
      o.vueKey && m.get(o.vueKey)?.to === n && m.delete(o.vueKey);
      const p = { ...t }, { is: C, on: h = {} } = p;
      delete p.is, delete p.on, b(() => {
        m.set(y, {
          bind: p,
          key: y,
          is: C,
          on: h,
          to: n,
          generation: d.generation
        });
      }), o.vueKey = y, s = !0;
    }
    return s;
  }
  /**
   * Cell renderer method
   * @param {Object} context
   * @param {RenderData} context.rendererData
   * @param {*} context.rendererHtml
   * @returns {Boolean}
   */
  static processCellContent({ rendererData: t, rendererHtml: e }) {
    const { record: n, column: i, cellElement: o, row: s } = t;
    if (c.isVueConfig(i.data) && i.data?.renderer) {
      const { vueComponent: l } = this, { teleports: { value: r } } = l.provides, d = `${i.id}-${n.id}`, f = i.tree ? o.querySelector(".b-tree-cell-value") : o;
      o.vueKey && r.delete(o.vueKey);
      const u = { ...e }, { is: m, on: v = {} } = u;
      delete u.is, delete u.on, b(() => {
        s.id === n.id && r.set(d, {
          bind: u,
          key: d,
          is: m,
          on: v,
          to: f,
          generation: n.generation
        });
      }), o.vueKey = d;
    }
  }
  /**
   *
   * @param {Object} context
   * @param {*} context.cellContent Content to be rendered in cell (set by renderer)
   * @param {*} context.column Column being rendered
   * @returns {Boolean} `true` if there is a Vue Renderer in this cell, `false` otherwise
   */
  static hasFrameworkRenderer({ cellContent: t, column: e }) {
    return t && typeof t == "object" && c.isVueConfig(e?.data);
  }
}
window.bryntum = window.bryntum || {};
window.bryntum.vue = {
  isVueConfig: c.isVueConfig,
  handleVueContent: c.handleVueContent
};
export {
  c as WrapperHelper
};
//# sourceMappingURL=WrapperHelper.js.map
