import { ref as g, markRaw as V, shallowReactive as M, defineComponent as C, onUnmounted as S, createElementBlock as U, openBlock as v, Fragment as b, renderList as O, unref as R, createBlock as T, resolveDynamicComponent as k } from "vue";
import { waitWhile as B } from "../utils/system.js";
import { historySetState as P, genHash as A, getHash as x } from "../utils/route.js";
import { querySelectorAllArray as y, isVisible as H } from "../utils/dom.js";
class r {
  static state = {
    load: void 0,
    decoratorOnCreate: void 0,
    /**
     * Порядковый номер перехода в диалоговых окнах
     *
     * Для расчета анимации Вперед / Назад
     */
    viewPageN: 0
  };
  static inited = !1;
  /**
   * Инициировать события слежения за парамтерами url
   *
   * Если в параметрах есть запрос на открытие диалогового окна, TopDialog будет автоматически подключен на страницу
   */
  static init(e) {
    if (this.inited) return;
    this.inited = !0, this.state.load = e?.load, this.state.decoratorOnCreate = e?.decoratorOnCreate;
    const t = e?.autoInitDelay ?? 5e3;
    window.addEventListener("hashchange", (a) => {
      this.opendDialogsFromChangeUrl(a.oldURL, a.newURL);
    }), this.opendDialogsFromChangeUrl("", location.href), document.addEventListener("mousedown", async (a) => {
      if (!(a.target instanceof HTMLElement)) return;
      const i = a.target.closest("a[data-to-view]");
      if (!i) return;
      let n = "next";
      i.dataset.action === "top-dialog-close" && (n = "prev"), i.href = r.genViewPageHash(i.dataset.toView, n);
    }), document.addEventListener("click", async (a) => {
      if (!(a.target instanceof HTMLElement)) return;
      const i = a.target.closest("[data-to-view]");
      if (!i) return;
      if (i instanceof HTMLAnchorElement && i.href === ".") {
        a.preventDefault();
        const w = new MouseEvent("mousedown", {
          bubbles: !0,
          cancelable: !0,
          view: window
        });
        i.dispatchEvent(w), setTimeout(() => i.click());
        return;
      }
      const n = await this.getDialogsUtils(), o = i.dataset.toView, u = o.split("-")[0], d = n.getElDialogById(u);
      let p = "next";
      if (d) {
        const w = y(d, ".modal-layer"), D = w.reduce((f, E) => {
          const h = E.querySelector(":scope > .active");
          return h && f.push(h), f;
        }, []);
        if (D.length) {
          const f = o.split("-")[1].split(":")[0];
          (w.reduce((h, L) => {
            const N = L?.querySelector(`:scope > [data-view-page="${f}"]`);
            return N && h.push(N), h;
          }, [])[0]?.dataset.order ?? 0) < (D[0]?.dataset.order ?? 0) && (p = "prev");
        }
      }
      i.dataset.action === "top-dialog-close" && (p = "prev");
      const m = r.genViewPageHash(o, p);
      if (i instanceof HTMLAnchorElement) {
        if (!d || !H(d)) return;
        if (location.hash.indexOf(o.replace("-", "=")) !== -1) {
          await n.toViewDirty(o);
          return;
        }
      }
      !!d?.dataset.toViewReplace ? (a.preventDefault(), P(!0, m), await n.toViewDirty(o), p == "next" ? r.state.viewPageN++ : r.state.viewPageN--) : i.tagName !== "A" && (this.compareStates(m, location.hash) ? P(!1, m) : await n.toViewDirty(o));
    }), setTimeout(() => this.getDialogsUtils(), t);
  }
  static opendDialogsFromChangeUrl(e, t) {
    const a = e.replace(/.*?#/, "#"), s = t.replace(/.*?#/, "#");
    this.compareStates(a, s) && this.opendDialogsFromUrl();
  }
  static async getDialogsUtils() {
    const { TopDialogUtils: e } = await import("./utils-DG_W0xvD.es.js");
    return e;
  }
  static getDialog(e) {
    return e.closest(".ui-dialog-content");
  }
  /**
   * todo: Переписать на сайте на this.getDialog()
   *
   * @deprecated Для обратной совместимости
   */
  static get$dialog(e) {
    return e.closest(".ui-dialog-content");
  }
  static getPage(e) {
    return e.closest("[data-view-page]");
  }
  /**
   * todo: Переписать на сайте на this.getPage()
   *
   * @deprecated Для обратной совместимости
   */
  static get$page(e) {
    return e.closest("[data-view-page]");
  }
  /**
   * todo: Переписать на сайте на this.getPairPage()
   *
   * @deprecated Для обратной совместимости
   */
  static get$pairPage(e) {
    const t = r.get$dialog(e), s = r.get$page(e).data("view-page");
    return $('[data-view-page="' + s + '"]', t);
  }
  static getPairPage(e) {
    const t = r.getDialog(e);
    if (!t) return;
    const s = r.getPage(e)?.dataset.viewPage;
    return y(t, `[data-view-page="${s}"]`);
  }
  /**
   * Закрыть диалоговое окно
   */
  static close(e) {
    const t = $("#" + e);
    if (t.dialog("instance")) {
      t.dialog("close");
      return;
    }
    const a = document.getElementById(e);
    a instanceof HTMLDialogElement && a.close();
  }
  /**
   * Размонтировать $.dialog
   */
  static destroy(e) {
    const t = $("#" + e);
    if (t.dialog("instance")) {
      t.dialog("close"), t.dialog("destroy");
      return;
    }
    const a = document.getElementById(e);
    a instanceof HTMLDialogElement && a.close();
  }
  /**
   * Сгенерировать ссылку на страницу в диалоговом окне
   * @param toView - указатель в формате: dialog_{{ dialogId }}={{ pageName }}:{{ args }}
   * @param moveDirection
   */
  static genViewPageHash(e, t = "next") {
    let a = this.state.viewPageN;
    t == "prev" ? a-- : a++;
    const s = e.split("-"), i = s.shift(), n = s.join("-");
    let o = A("vpn", a);
    return o = A("view-" + i, n, o), o;
  }
  /**
   * Сравнить версию открытых диалоговых окон
   * @returns вернет true, если состояния открытых окон изменилось
   */
  static compareStates(e, t) {
    const a = e.match(/[#&]view-[^&]+/g) || [], s = t.match(/[#&]view-[^&]+/g) || [];
    return !!(a.length !== s.length || a.filter((n, o) => {
      const u = s[o] || "";
      return n !== u;
    }).length);
  }
  static opendDialogsFromUrl = async () => {
    const e = Number(x("vpn")) || 0;
    let t;
    const a = new RegExp("view-((\\w+)=([\\w-]+)(?::([\\w.:-]+))?)", "g");
    for (; t = a.exec(location.hash); ) {
      let i = "next";
      return e < this.state.viewPageN && (i = "prev"), (await this.getDialogsUtils()).toViewDirty(t[1], i);
    }
    return y(document, ".ui-dialog-content[data-view-page-active]").filter((i) => H(i)).forEach((i) => {
      const n = i.getAttribute("id");
      if (!n) throw "Диалоговое окно не содержит id";
      x("view-" + n) || $(i).dialog("close");
    }), this.state.viewPageN = e, !0;
  };
}
class F {
  /**
   * Индентификатор, определяется на уровне компонента TopDialogComponent
   *
   * Может использоваться в навигации для открытия нужных окон с нужными настройками
   */
  id;
  /**
   * ID, используемый в верстке диалогового окна
   */
  idAttr;
  /**
   * Пользовательский компонент диалогового окна
   */
  Component;
  /**
   * Компонент инициирован
   *
   * Устанавливается после первого вызова useTopDialog()
   */
  isMounted = g(!1);
  /**
   * Компонент готов к использованию
   *
   * Используется для внутренних преобразований после отрисовки
   */
  isReady = g(!1);
  /**
   * Диалоговое окно открыто
   */
  isOpened = g(!1);
  /**
   * Имя активной страницы дилогового окна
   */
  pageActive = g("");
  /**
   * Диалоговое окно находится в состоянии загрузки своей страницы
   */
  isLoadingPage = g(!1);
  /**
   * Следующая активная страница
   *
   * В один момент времени может потребоваться отобразить две страницы, чтобы воспроизвести анимацию
   */
  pageActiveNext = g("");
  /**
   * props компонента, доступны после инициализации
   */
  props;
  /**
   * emit базового компонента `TopDialog`
   */
  emit;
  /**
   * Одноразовое событие на закрытие диалогового окна
   *
   * Используется для привязки окна к сценариям использования
   */
  onCloseOnce;
  constructor(e) {
    this.id = e.id, this.idAttr = "dialog_" + e.id, this.Component = V(e);
  }
  /**
   * Событие - компонент инициирован
   */
  onMounted(e, t) {
    this.isMounted.value = !0, this.props = e.props, this.emit = t.emit;
  }
  /**
   * Открыть диалоговое окно
   *
   * Учтите, что props в диалоговом окне будут доступны не сразу, а только после инициализации vue компонента
   */
  async open(e = "main", t, a = [], s, i) {
    t && await this.setProps(t), s && (this.onCloseOnce = s), await (await r.getDialogsUtils()).toView(this.idAttr, e, a, i);
  }
  /**
   * Открыть диалоговое окно как ссылку, для хеш-навигации
   *
   * Диалоговые окна загружаются по имени, см. настройку плагина Core topDialogLoader
   */
  async openAsLink(e = "main", t, a = [], s, i) {
    t && await this.setProps(t), s && (this.onCloseOnce = s);
    const n = this.idAttr + "-" + e, o = r.genViewPageHash(n, i);
    P(!1, o);
  }
  /**
   * Закрыть диалоговое окно
   *
   * Не меняет состояние компонента диалогового окна
   */
  async close() {
    r.close(this.idAttr);
  }
  /**
   * Размонтировать $.dialog
   */
  async destroy() {
    r.destroy(this.idAttr);
  }
  /**
   * Устанвоить props
   *
   * Полностью сбрасывается состояние props
   */
  async setProps(e = {}) {
    this.isMounted || await B(() => !this.props);
    for (const t in this.props)
      this.props[t] = e[t];
  }
  /**
   * Проверить, есть ли необходимость отрисовки страницы диалогового окна
   */
  needShowPage(e) {
    return this.isOpened.value ? this.pageActive.value === e || this.pageActiveNext.value === e : !1;
  }
}
const _ = {
  class: "top-dialogs",
  style: { display: "none" }
}, c = M(/* @__PURE__ */ new Map()), J = (l) => (l = l.replace(/^dialog_/, ""), c.get(l)), K = (l) => {
  if (!l?.id)
    throw console.log({ TopDialogComponent: l }), new Error("Expected TopDialogComponent");
  return c.has(l.id) || c.set(l.id, new F(l)), c.get(l.id);
}, Q = /* @__PURE__ */ C({
  name: "DialogWrapper",
  __name: "dialogs",
  setup(l) {
    return S(() => {
      c.forEach((e) => e.destroy()), c.clear();
    }), (e, t) => (v(), U("div", _, [
      (v(!0), U(b, null, O(R(c), ([a, s]) => (v(), T(k(s.Component), { key: a }))), 128))
    ]));
  }
});
export {
  r as T,
  Q as _,
  K as a,
  J as g
};
//# sourceMappingURL=dialogs.vue_vue_type_script_setup_true_lang-DMhcuiHP.es.js.map
