import { defineComponent, computed, createVNode, Fragment, Transition, withDirectives, vShow, cloneVNode } from 'vue';
import _defineProperty from '@babel/runtime/helpers/esm/defineProperty';
import { isBoolean, isFunction } from 'lodash-es';
import LazyTeleport from '../_util/components/lazyTeleport';
import getPrefixCls from '../_util/getPrefixCls';
import { UPDATE_MODEL_EVENT } from '../_util/constants';
import useClickOutSide from '../_util/use/useClickOutSide';
import useResize from '../_util/use/useResize';
import { getFirstValidNode } from '../_util/vnode';
import getElementFromVueInstance from '../_util/getElementFromVueInstance';
import { useTheme } from '../_theme/useTheme';
import { useConfig } from '../config-provider';
import useTrigger from './useTrigger';
import usePopper from './usePopper';
import useScroll from './useScroll';
import { popperProps } from './props';

function ownKeys(e, r) { var t = Object.keys(e); if (Object.getOwnPropertySymbols) { var o = Object.getOwnPropertySymbols(e); r && (o = o.filter(function (r) { return Object.getOwnPropertyDescriptor(e, r).enumerable; })), t.push.apply(t, o); } return t; }
function _objectSpread(e) { for (var r = 1; r < arguments.length; r++) { var t = null != arguments[r] ? arguments[r] : {}; r % 2 ? ownKeys(Object(t), !0).forEach(function (r) { _defineProperty(e, r, t[r]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(e, Object.getOwnPropertyDescriptors(t)) : ownKeys(Object(t)).forEach(function (r) { Object.defineProperty(e, r, Object.getOwnPropertyDescriptor(t, r)); }); } return e; }
const prefixCls = getPrefixCls('popper');
var popper = defineComponent({
  name: 'FPopper',
  props: popperProps,
  emits: [UPDATE_MODEL_EVENT, 'clickOutside'],
  setup(props, _ref) {
    let {
      slots,
      emit,
      expose
    } = _ref;
    useTheme();
    if (!slots.trigger) {
      throw new Error('[FPopper]: Trigger must be provided');
    }
    const config = useConfig();
    const getContainer = computed(() => {
      var _config$getContainer;
      return props.getContainer || ((_config$getContainer = config.getContainer) === null || _config$getContainer === void 0 ? void 0 : _config$getContainer.value);
    });
    const {
      visible,
      updateVisible,
      triggerRef,
      popperRef,
      arrowRef,
      computePopper,
      popperStyle,
      updateVirtualRect,
      cacheVisible,
      transitionName
    } = usePopper(props, emit);
    const disabledWatch = computed(() => (isBoolean(props.disabled) ? props.disabled : false) || !visible.value);
    const triggerElement = computed(() => {
      const elm = getElementFromVueInstance(triggerRef.value);
      if (elm instanceof Text) {
        throw new TypeError(`FPopper: trigger must be a Element, but get Text(${elm.nodeValue})`);
      }
      return elm;
    });
    useScroll(triggerElement, e => {
      var _getContainer$value;
      if (disabledWatch.value) {
        return;
      }
      if (isFunction(props.disabled) && props.disabled()) {
        return;
      }
      // 不挂载在container上
      if (!props.appendToContainer) {
        return;
      }
      if (e.target === ((_getContainer$value = getContainer.value) === null || _getContainer$value === void 0 ? void 0 : _getContainer$value.call(getContainer))) {
        return;
      }
      computePopper();
    });
    useClickOutSide([triggerRef, popperRef], () => {
      updateVisible(false);
      emit('clickOutside');
    }, disabledWatch);
    useResize(triggerElement, computePopper, disabledWatch);
    useResize(computed(() => getElementFromVueInstance(popperRef.value)), computePopper, disabledWatch);
    const {
      events,
      onPopperMouseEnter,
      onPopperMouseLeave
    } = useTrigger(visible, updateVisible, props, updateVirtualRect);
    const popperClass = computed(() => [prefixCls, props.popperClass].filter(Boolean));
    const renderTrigger = () => {
      var _slots$trigger;
      const vNode = getFirstValidNode((_slots$trigger = slots.trigger) === null || _slots$trigger === void 0 ? void 0 : _slots$trigger.call(slots));
      if (vNode) {
        return cloneVNode(vNode, _objectSpread({
          ref: triggerRef
        }, events.value), true);
      }
    };
    const Content = () => {
      var _slots$default;
      return createVNode("div", {
        "class": popperClass.value
      }, [(_slots$default = slots.default) === null || _slots$default === void 0 ? void 0 : _slots$default.call(slots), props.arrow && createVNode("div", {
        "ref": arrowRef,
        "class": `${prefixCls}-arrow`
      }, null)]);
    };
    expose({
      updatePopperPosition() {
        computePopper();
      }
    });
    return () => {
      var _getContainer$value2;
      return createVNode(Fragment, null, [renderTrigger(), createVNode(LazyTeleport, {
        "to": (_getContainer$value2 = getContainer.value) === null || _getContainer$value2 === void 0 ? void 0 : _getContainer$value2.call(getContainer),
        "disabled": !props.appendToContainer,
        "show": Boolean(!props.lazy || visible.value)
      }, {
        default: () => [createVNode("div", {
          "ref": popperRef,
          "class": `${prefixCls}-wrapper`,
          "style": [popperStyle, props.popperStyle],
          "role": 'tooltip',
          "onMouseenter": onPopperMouseEnter,
          "onMouseleave": onPopperMouseLeave
        }, [createVNode(Transition, {
          "name": transitionName.value,
          "type": "animation",
          "appear": true,
          "onBeforeEnter": computePopper
        }, {
          default: () => [withDirectives(createVNode(Content, null, null), [[vShow, visible.value && cacheVisible.value]])]
        })])]
      })]);
    };
  }
});

export { popper as default };
