import { defineComponent, shallowRef, onUpdated, computed, onMounted, watch, nextTick, onBeforeUnmount, createVNode } from 'vue';
import '../../../utils/index.mjs';
import '../../../hooks/index.mjs';
import Portal from './Portal.mjs';
import { canUseDom } from '../../../utils/dom/canUseDom.mjs';
import PropTypes from '../../../utils/vue/vueTypes.mjs';
import { booleanType } from '../../../utils/vue/propType.mjs';
import { useScrollLocker } from '../../../hooks/use-scroll-locker/index.mjs';
import { raf } from '../../../utils/vue/raf.mjs';

let openCount = 0;
const supportDom = canUseDom();
function getOpenCount() {
  return process.env.NODE_ENV === "test" ? openCount : 0;
}
function getParent(getContainer) {
  if (!supportDom)
    return null;
  if (getContainer) {
    if (typeof getContainer === "string")
      return document.querySelectorAll(getContainer)[0];
    if (typeof getContainer === "function")
      return getContainer();
    if (typeof getContainer === "object" && getContainer instanceof window.HTMLElement)
      return getContainer;
  }
  return document.body;
}
var PortalWrapper = /* @__PURE__ */ defineComponent({
  compatConfig: {
    MODE: 3
  },
  name: "PortalWrapper",
  inheritAttrs: false,
  props: {
    wrapperClassName: String,
    forceRender: {
      type: Boolean,
      default: void 0
    },
    getContainer: PropTypes.any,
    visible: {
      type: Boolean,
      default: void 0
    },
    autoLock: booleanType(),
    didUpdate: Function
  },
  setup(props, {
    slots
  }) {
    const container = shallowRef();
    const componentRef = shallowRef();
    const rafId = shallowRef();
    const triggerUpdate = shallowRef(1);
    const defaultContainer = canUseDom() && document.createElement("div");
    const removeCurrentContainer = () => {
      var _a, _b;
      if (container.value === defaultContainer)
        (_b = (_a = container.value) == null ? void 0 : _a.parentNode) == null ? void 0 : _b.removeChild(container.value);
      container.value = null;
    };
    let parent = null;
    const attachToParent = (force = false) => {
      if (force || container.value && !container.value.parentNode) {
        parent = getParent(props.getContainer);
        if (parent) {
          parent.appendChild(container.value);
          return true;
        }
        return false;
      }
      return true;
    };
    const getContainer = () => {
      if (!supportDom)
        return null;
      if (!container.value) {
        container.value = defaultContainer;
        attachToParent(true);
      }
      setWrapperClassName();
      return container.value;
    };
    const setWrapperClassName = () => {
      const {
        wrapperClassName
      } = props;
      if (container.value && wrapperClassName && wrapperClassName !== container.value.className)
        container.value.className = wrapperClassName;
    };
    onUpdated(() => {
      setWrapperClassName();
      attachToParent();
    });
    useScrollLocker(computed(() => {
      return props.autoLock && props.visible && canUseDom() && (container.value === document.body || container.value === defaultContainer);
    }));
    onMounted(() => {
      let init = false;
      watch([() => props.visible, () => props.getContainer], ([visible, _], [prevVisible, prevGetContainer]) => {
        if (supportDom) {
          parent = getParent(props.getContainer);
          if (parent === document.body) {
            if (visible && !prevVisible)
              openCount += 1;
            else if (init)
              openCount -= 1;
          }
        }
        if (init) {
          const getContainerIsFunc = typeof props.getContainer === "function" && typeof prevGetContainer === "function";
          if (getContainerIsFunc ? props.getContainer.toString() !== prevGetContainer.toString() : props.getContainer !== prevGetContainer)
            removeCurrentContainer();
        }
        init = true;
      }, {
        immediate: true,
        flush: "post"
      });
      nextTick(() => {
        if (!attachToParent()) {
          rafId.value = raf(() => {
            triggerUpdate.value += 1;
          });
        }
      });
    });
    onBeforeUnmount(() => {
      const {
        visible
      } = props;
      if (supportDom && parent === document.body) {
        openCount = visible && openCount ? openCount - 1 : openCount;
      }
      removeCurrentContainer();
      raf.cancel(rafId.value);
    });
    return () => {
      const {
        forceRender,
        visible
      } = props;
      let portal = null;
      const childProps = {
        getOpenCount: () => openCount,
        getContainer
      };
      if (triggerUpdate.value && (forceRender || visible || componentRef.value)) {
        portal = createVNode(Portal, {
          "getContainer": getContainer,
          "ref": componentRef,
          "didUpdate": props.didUpdate
        }, {
          default: () => {
            var _a;
            return (_a = slots.default) == null ? void 0 : _a.call(slots, childProps);
          }
        });
      }
      return portal;
    };
  }
});

export { PortalWrapper as default, getOpenCount };
//# sourceMappingURL=PortalWrapper.mjs.map
