import { defineComponent, getCurrentInstance, ref, computed, onMounted, onBeforeUnmount, provide, watch, createVNode, mergeProps, Fragment, withDirectives, vShow } from 'vue';
import { pick } from 'lodash-es';
import getPrefixCls from '../_util/getPrefixCls';
import FadeInExpandTransition from '../_util/components/fadeInExpandTransition';
import Popper from '../popper/popper';
import DownOutlined from '../icon/DownOutlined';
import RightOutlined from '../icon/RightOutlined';
import Ellipsis from '../ellipsis/ellipsis';
import { COMPONENT_NAME, SUB_MENU_KEY } from './const';
import useChildren from './useChildren';
import useParent from './useParent';
import useMenu from './useMenu';

const prefixCls = getPrefixCls('sub-menu');
const subMenuProps = {
  value: {
    type: [String, Number]
  },
  label: String
};
var subMenu = defineComponent({
  name: COMPONENT_NAME.SUB_MENU,
  components: {
    Ellipsis,
    FadeInExpandTransition
  },
  props: {
    value: {
      type: [String, Number],
      default: null
    },
    label: String
  },
  setup(props, _ref) {
    let {
      slots
    } = _ref;
    const instance = getCurrentInstance();
    const {
      indexPath
    } = useMenu(instance);
    const subMenuRef = ref(null);
    const {
      rootMenu,
      parentMenu,
      paddingStyle,
      isFirstLevel,
      onlyIcon
    } = useChildren(indexPath);
    // 根节点 menu
    if (!rootMenu) {
      console.warn(`[${COMPONENT_NAME.SUB_MENU}] must be a child of ${COMPONENT_NAME.MENU}`);
    }
    // 父级组件，可能为 menu 或者 sub-menu
    if (!parentMenu) {
      console.warn(`[${COMPONENT_NAME.SUB_MENU}] must be a child of ${COMPONENT_NAME.MENU} or ${COMPONENT_NAME.SUB_MENU}`);
    }
    const {
      children
    } = useParent();
    const isOpened = ref(false);
    const isActive = computed(() => children.some(child => child === null || child === void 0 ? void 0 : child.isActive));
    const subMenu = {
      uid: instance.uid,
      value: props.value,
      type: 'subMenu',
      children,
      isOpened,
      isActive
    };
    onMounted(() => {
      parentMenu.addChild(subMenu);
    });
    onBeforeUnmount(() => {
      parentMenu.removeChild(subMenu);
    });
    provide(SUB_MENU_KEY, {
      handleItemClick: () => {
        if (rootMenu.renderWithPopper.value) {
          isOpened.value = false;
          rootMenu.updateExpandedKeys([]);
        }
      }
    });
    const placement = computed(() => {
      if (rootMenu.props.mode === 'horizontal') {
        return isFirstLevel.value ? 'bottom-start' : 'right-start';
      }
      return 'right-start';
    });
    const classList = computed(() => [prefixCls, isActive.value && 'is-active'].filter(Boolean).join(' '));
    const handleTriggerClick = () => {
      isOpened.value = !isOpened.value;
      rootMenu.handleSubMenuExpand(subMenu, indexPath);
    };
    watch([rootMenu.currentExpandedKeys], () => {
      // 要通过监听 currentExpandedKeys，自动打开或者关闭子菜单
      const currentIsExpanded = rootMenu.currentExpandedKeys.value.includes(props.value || instance.uid);
      if (isOpened.value && !currentIsExpanded) {
        isOpened.value = false;
      } else if (!isOpened.value && currentIsExpanded) {
        isOpened.value = true;
      }
    }, {
      immediate: true
    });
    const renderTitle = () => {
      var _slots$label;
      return createVNode(Ellipsis, {
        "class": `${prefixCls}-label`
      }, {
        default: () => [((_slots$label = slots.label) === null || _slots$label === void 0 ? void 0 : _slots$label.call(slots)) || props.label]
      });
    };
    const renderIcon = () => {
      if (slots.icon) {
        return createVNode("div", {
          "class": `${prefixCls}-icon`
        }, [slots.icon()]);
      }
      if (onlyIcon.value) {
        return renderTitle();
      }
      return null;
    };
    const renderArrow = () => {
      if (rootMenu.renderWithPopper.value && !isFirstLevel.value) {
        return createVNode("span", {
          "class": `${prefixCls}-arrow`
        }, [createVNode(RightOutlined, null, null)]);
      }
      return createVNode("span", {
        "class": [`${prefixCls}-arrow`, isOpened.value && 'is-opened']
      }, [createVNode(DownOutlined, null, null)]);
    };
    const wrapperContent = () => {
      return createVNode(Fragment, null, [renderIcon(), !onlyIcon.value ? renderTitle() : null, !onlyIcon.value ? renderArrow() : null]);
    };
    const renderWrapperClick = () => {
      return createVNode("div", {
        "class": `${prefixCls}-wrapper`,
        "style": paddingStyle.value,
        "onClick": handleTriggerClick
      }, [wrapperContent()]);
    };
    const renderWrapperPopper = () => {
      return createVNode("div", {
        "class": `${prefixCls}-wrapper`,
        "style": paddingStyle.value
      }, [wrapperContent()]);
    };
    const renderDefault = () => {
      var _slots$default;
      return (_slots$default = slots.default) === null || _slots$default === void 0 ? void 0 : _slots$default.call(slots);
    };
    const popperProps = computed(() => {
      if (!rootMenu.renderWithPopper.value) {
        return {};
      }
      return pick(rootMenu.props, ['getContainer', 'appendToContainer']);
    });
    const renderContent = () => {
      if (rootMenu.renderWithPopper.value) {
        return createVNode(Popper, mergeProps({
          "modelValue": isOpened.value,
          "onUpdate:modelValue": $event => isOpened.value = $event
        }, popperProps.value, {
          "trigger": `hover`,
          "placement": placement.value,
          "popperClass": `${prefixCls}-popper`,
          "appendToContainer": !(indexPath.value.length > 2),
          "offset": 1
        }), {
          default: renderDefault,
          trigger: () => renderWrapperPopper()
        });
      }
      return createVNode(Fragment, null, [renderWrapperClick(), createVNode(FadeInExpandTransition, null, {
        default: () => [withDirectives(createVNode("div", {
          "class": `${prefixCls}-children`
        }, [renderDefault()]), [[vShow, isOpened.value]])]
      })]);
    };
    return () => createVNode("div", {
      "class": classList.value,
      "ref": subMenuRef
    }, [renderContent()]);
  }
});

export { subMenu as default, subMenuProps };
