"use strict";
const vue = require("vue");
const types = require("./types.js");
const useMouse = require("../hooks/use-mouse.js");
const is = require("../_utils/is.js");
const zIndex = require("../_utils/z-index.js");
const icons = require("../_utils/icons.js");
const index = require("../icon/index.js");
const __default__ = {
  inheritAttrs: false
};
const _sfc_main = /* @__PURE__ */ vue.defineComponent({
  ...__default__,
  __name: "OLayer",
  props: types.layerProps,
  emits: ["change", "update:visible", "click:mask", "click:button"],
  setup(__props, { expose: __expose, emit: __emit }) {
    const props = __props;
    const emits = __emit;
    const visible = vue.ref(props.visible);
    const toMount = vue.ref(props.visible);
    const zIndex$1 = vue.ref(visible.value ? zIndex.createTopZIndex() : 0);
    const isToBody = vue.ref(false);
    const LayerClass = {
      OPEN: "o-layer-open"
    };
    const mainRef = vue.ref(null);
    let mouse = useMouse.useMouse({
      type: "client"
    });
    const layerRef = vue.ref(null);
    let wrapperEl = null;
    const initWrapperEl = () => {
      if (!wrapperEl && layerRef.value) {
        wrapperEl = layerRef.value.offsetParent;
        if (!wrapperEl) {
          wrapperEl = document.body;
          isToBody.value = true;
        } else {
          isToBody.value = wrapperEl === document.body;
        }
      }
      return wrapperEl;
    };
    const handleWrapperScroll = () => {
      vue.nextTick(() => {
        initWrapperEl();
        if (wrapperEl) {
          if (visible.value) {
            wrapperEl.classList.add(LayerClass.OPEN);
          } else {
            wrapperEl.classList.remove(LayerClass.OPEN);
          }
        }
      });
    };
    const mainStyle = vue.ref({});
    const getOriginStyle = () => {
      let ox = "center";
      let oy = "center";
      if (mainRef.value && mouse) {
        const { offsetLeft, offsetTop } = mainRef.value;
        if (isToBody.value) {
          ox = `${mouse.x.value - offsetLeft}px`;
          oy = `${mouse.y.value - offsetTop}px`;
        } else if (wrapperEl) {
          const size = wrapperEl.getBoundingClientRect();
          ox = `${mouse.x.value - offsetLeft - size.x}px`;
          oy = `${mouse.y.value - offsetTop - size.y}px`;
        }
      }
      return `${ox} ${oy}`;
    };
    const updateOrigin = (_el) => {
      if (props.transitionOrign === "mouse") {
        initWrapperEl();
        mainStyle.value.transformOrigin = getOriginStyle();
      }
    };
    const beforeToggle = async (show) => {
      let goon = true;
      if (show) {
        if (is.isFunction(props.beforeShow)) {
          goon = await props.beforeShow();
        }
      } else {
        if (is.isFunction(props.beforeHide)) {
          goon = await props.beforeHide();
        }
      }
      return goon !== false;
    };
    const updateZIndex = (show) => {
      if (show) {
        zIndex$1.value = zIndex.createTopZIndex();
      } else {
        zIndex.removeZIndex(zIndex$1.value);
      }
    };
    vue.watch(
      () => props.visible,
      async (v) => {
        if (visible.value !== v) {
          const goon = await beforeToggle(v);
          if (!goon) {
            emits("update:visible", visible.value);
            return;
          }
          updateZIndex(v);
          visible.value = v;
          emits("change", v);
          handleWrapperScroll();
        }
      }
    );
    const toggle = async (show) => {
      if (visible.value === show) {
        return;
      }
      let toShow = show === void 0 ? !visible.value : show;
      const goon = await beforeToggle(toShow);
      if (!goon) {
        return;
      }
      updateZIndex(toShow);
      visible.value = toShow;
      emits("update:visible", visible.value);
      emits("change", visible.value);
      handleWrapperScroll();
    };
    const isMounted = vue.computed(() => {
      return !props.unmountOnHide || visible.value || toMount.value;
    });
    const handleTransitionStart = () => {
      toMount.value = true;
    };
    const handleTransitionEnter = () => {
      if (visible.value) {
        updateOrigin(mainRef.value);
      }
    };
    const handleTransitionEnd = () => {
      if (!props.unmountOnHide) {
        toMount.value = false;
      } else if (!visible.value) {
        toMount.value = false;
      }
    };
    const onMaskClick = (e) => {
      if (props.maskClose) {
        toggle(false);
      }
      emits("click:mask", e);
    };
    const onCloseButtonClick = (e) => {
      toggle(false);
      emits("click:button", e);
    };
    vue.onMounted(() => {
      if (visible.value) {
        handleWrapperScroll();
      }
    });
    vue.onUnmounted(() => {
      mouse == null ? void 0 : mouse.destroy();
      wrapperEl == null ? void 0 : wrapperEl.classList.remove(LayerClass.OPEN);
    });
    __expose({
      /** Toggle the OLayer */
      toggle
    });
    return (_ctx, _cache) => {
      return vue.openBlock(), vue.createBlock(vue.Teleport, {
        to: props.wrapper,
        disabled: !props.wrapper
      }, [
        isMounted.value ? vue.withDirectives((vue.openBlock(), vue.createElementBlock(
          "div",
          vue.mergeProps({
            key: 0,
            ref_key: "layerRef",
            ref: layerRef,
            class: ["o-layer", { "o-layer-to-body": isToBody.value }]
          }, _ctx.$attrs, {
            style: {
              "--layer-z-index": zIndex$1.value
            }
          }),
          [
            props.mask ? (vue.openBlock(), vue.createBlock(vue.Transition, {
              key: 0,
              name: props.maskTransition,
              appear: true,
              persisted: ""
            }, {
              default: vue.withCtx(() => [
                vue.withDirectives(vue.createElementVNode(
                  "div",
                  {
                    class: "o-layer-mask",
                    onClick: onMaskClick
                  },
                  null,
                  512
                  /* NEED_PATCH */
                ), [
                  [vue.vShow, visible.value]
                ])
              ]),
              _: 1
              /* STABLE */
            }, 8, ["name"])) : vue.createCommentVNode("v-if", true),
            vue.createVNode(vue.Transition, {
              appear: true,
              name: props.mainTransition,
              onBeforeEnter: handleTransitionStart,
              onEnter: handleTransitionEnter,
              onAfterEnter: handleTransitionEnd,
              onBeforeLeave: handleTransitionStart,
              onAfterLeave: handleTransitionEnd,
              persisted: ""
            }, {
              default: vue.withCtx(() => [
                vue.withDirectives(vue.createElementVNode(
                  "div",
                  {
                    ref_key: "mainRef",
                    ref: mainRef,
                    class: vue.normalizeClass([props.mainClass, "o-layer-main"]),
                    style: vue.normalizeStyle(mainStyle.value)
                  },
                  [
                    vue.renderSlot(_ctx.$slots, "default")
                  ],
                  6
                  /* CLASS, STYLE */
                ), [
                  [vue.vShow, visible.value]
                ])
              ]),
              _: 3
              /* FORWARDED */
            }, 8, ["name"]),
            props.buttonClose ? (vue.openBlock(), vue.createElementBlock("div", {
              key: 1,
              class: "o-layer-close",
              onClick: onCloseButtonClick
            }, [
              vue.renderSlot(_ctx.$slots, "close", {}, () => [
                vue.createVNode(vue.unref(index.OIcon), {
                  button: "",
                  icon: vue.unref(icons.IconClose),
                  class: "o-layer-close-icon"
                }, null, 8, ["icon"])
              ])
            ])) : vue.createCommentVNode("v-if", true)
          ],
          16
          /* FULL_PROPS */
        )), [
          [vue.vShow, visible.value || toMount.value]
        ]) : vue.createCommentVNode("v-if", true)
      ], 8, ["to", "disabled"]);
    };
  }
});
module.exports = _sfc_main;
