<template>
    <li :class="subMenuClass"
        role="menuitem"
        aria-haspopup="true"
        :aria-expanded="opened"
        :style="(layout=='horizontal' && isFirstLevel)?'display:inline-block; vertical-align: top;':'display:block'"
        @mouseenter="handleMouseenter"
        @mouseleave="handleMouseleave"
        @focus="handleMouseenter">
        <div ref="submenu-title"
             :class="`${prefix}-submenu__title`"
             :style="[paddingStyle, titleStyle, { backgroundColor }]"
             @click="handleClick"
             @mouseenter="handleTitleMouseenter"
             @mouseleave="handleTitleMouseleave">
            <span v-if="icon || $slots.icon"
                  :class="`${prefix}-menu__icon`">
                <slot name="icon"><i :class="icon"></i></slot>
            </span>
            <slot name="title"></slot>
            <i :class="[ `${prefix}-menu-arrow`, submenuTitleIcon ]"></i>
        </div>
        <component :is="innerMenu"
                   ref="menu"
                   :opened="opened"
                   :popperClass="popperClass"
                   :animate="menuTransitionName"
                   :placement="currentPlacement"
                   @mouseenter="handleMouseenter"
                   @mouseleave="handleMouseleave">
            <slot></slot>
        </component>
    </li>
</template>
<script>
import menuMixin from './mixins';
import poperMixins from 'jdd-design/utils/mixins/popper';
import { prefix, prefixMixins, getZIndex, pointInView } from 'jdd-design/utils';
import PopMenu from './pop-menu';
import InlineMenu from './inline-menu';
export default {
    name: `${prefix}-submenu`,
    componentName: `${prefix}-submenu`,
    mixins: [menuMixin, prefixMixins, poperMixins],
    props: {
        transformOrigin: {
            type: [Boolean, String],
            default: false
        },
        index: {
            type: String,
            required: true
        },
        showTimeout: {
            type: Number,
            default: 300
        },
        hideTimeout: {
            type: Number,
            default: 300
        },
        popperClass: String,
        disabled: Boolean,
        icon: String
    },

    data() {
        return {
            popperJS: null,
            timeout: null,
            items: {},
            submenus: {},
            mouseInChild: false
        };
    },
    watch: {
        opened(val) {
            if (this.isMenuPopup) {
                this.$nextTick(_ => {
                    this.updatePopper();
                });
            }
        }
    },
    computed: {
        subMenuClass() {
            const { active, opened, disabled } = this;
            let clsNames = [`${prefix}-submenu`];
            active && clsNames.push('is-active');
            opened && clsNames.push('is-opened');
            disabled && clsNames.push('is-disabled');
            return clsNames;
        },
        popperAppendToBody() {
            return this.appendToBody === undefined
                ? this.isFirstLevel
                : this.appendToBody;
        },
        menuTransitionName() {
            if (this.jddMenu.collapse) {
                return 'ani-zoom-in-left';
            }
            if (this.layout === 'horizontal') {
                if (this.isFirstLevel) {
                    return 'ani-zoom-in-top';
                } else {
                    return 'ani-zoom-in-left-out-top';
                }
            }
            return 'ani-zoom-in-left';
        },
        opened() {
            return this.jddMenu.openedMenus.indexOf(this.index) > -1;
        },
        active() {
            let isActive = false;
            const submenus = this.submenus;
            const items = this.items;

            Object.keys(items).forEach(index => {
                if (items[index].active) {
                    isActive = true;
                }
            });

            Object.keys(submenus).forEach(index => {
                if (submenus[index].active) {
                    isActive = true;
                }
            });

            return isActive;
        },
        isMenuPopup() {
            return this.jddMenu.isMenuPopup;
        },
        titleStyle() {
            if (this.layout !== 'horizontal') {
                return {
                    color: this.textColor
                };
            }
            return {
                borderBottomColor: this.active
                    ? this.jddMenu.activeTextColor
                        ? this.activeTextColor
                        : ''
                    : 'transparent',
                color: this.active ? this.activeTextColor : this.textColor
            };
        },
        isFirstLevel() {
            let isFirstLevel = true;
            let parent = this.$parent;
            while (parent && parent !== this.jddMenu) {
                if (
                    [`${prefix}-submenu`, `${prefix}-menu-item-group`].indexOf(
                        parent.$options.componentName
                    ) > -1
                ) {
                    isFirstLevel = false;
                    break;
                } else {
                    parent = parent.$parent;
                }
            }
            return isFirstLevel;
        },
        innerMenu() {
            return this.isMenuPopup ? PopMenu : InlineMenu;
        },
        submenuTitleIcon() {
            return (this.jddMenu.layout === 'horizontal' &&
                this.isFirstLevel) ||
                (this.jddMenu.layout === 'vertical' && !this.jddMenu.collapse)
                ? `${prefix}-icon-arrow-down`
                : `${prefix}-icon-arrow-right`;
        }
    },
    methods: {
        handleCollapseToggle(value) {
            if (value) {
                this.initPopper();
            } else {
                this.doDestroy();
            }
        },
        addItem(item) {
            this.$set(this.items, item.index, item);
        },
        removeItem(item) {
            delete this.items[item.index];
        },
        addSubmenu(item) {
            this.$set(this.submenus, item.index, item);
        },
        removeSubmenu(item) {
            delete this.submenus[item.index];
        },
        handleClick() {
            const { jddMenu, disabled } = this;
            if (
                (jddMenu.menuTrigger === 'hover' &&
                    jddMenu.layout === 'horizontal') ||
                (jddMenu.collapse && jddMenu.layout === 'vertical') ||
                disabled
            ) {
                return;
            }
            this.jddMenu.$emit('submenu-click', this);
        },
        handleMouseenter(event, showTimeout = this.showTimeout) {
            const { jddMenu, disabled } = this;
            if (
                (jddMenu.menuTrigger === 'click' &&
                    jddMenu.layout === 'horizontal') ||
                (!jddMenu.collapse && jddMenu.layout === 'vertical') ||
                disabled
            ) {
                return;
            }
            this.parentMenu.$emit('child-mouse-enter', this);
            clearTimeout(this.timeout);
            this.timeout = setTimeout(() => {
                this.jddMenu.openMenu(this.index, this.indexPath);
            }, showTimeout);
        },
        handleMouseleave(event, hideTimeout = this.hideTimeout) {
            const { jddMenu, mouseInChild, appendToBody, index } = this;
            if (
                (jddMenu.menuTrigger === 'click' &&
                    jddMenu.layout === 'horizontal') ||
                (!jddMenu.collapse && jddMenu.layout === 'vertical')
            ) {
                return;
            }
            if (!appendToBody) {
                //由弹出菜单触发的
                if (this.$el !== event.target) {
                    return;
                }
            } else {
                if (this.$el !== event.target) {
                    if (
                        pointInView(
                            { x: event.clientX, y: event.clientY },
                            this.$el
                        )
                    ) {
                        return;
                    } else {
                        //关闭所有
                        setTimeout(() => {
                            if (!this.mouseInChild) {
                                this.jddMenu.openedMenus = [];
                            }
                        }, hideTimeout / 2);
                    }
                }
            }
            this.parentMenu.$emit('child-mouse-leave', this);
            clearTimeout(this.timeout);
            this.timeout = setTimeout(() => {
                !this.mouseInChild && jddMenu.closeMenu(index);
            }, hideTimeout);
        },
        handleTitleMouseenter() {
            if (this.layout === 'horizontal' && !this.jddMenu.backgroundColor)
                return;
            const title = this.$refs['submenu-title'];
            title &&
                (title.style.backgroundColor = this.jddMenu.hoverBackground);
        },
        handleTitleMouseleave() {
            if (this.layout === 'horizontal' && !this.jddMenu.backgroundColor)
                return;
            const title = this.$refs['submenu-title'];
            title &&
                (title.style.backgroundColor =
                    this.jddMenu.backgroundColor || '');
        },
        updatePlacement() {
            this.currentPlacement =
                this.layout === 'horizontal' && this.isFirstLevel
                    ? 'bottom-start'
                    : 'right-start';
        },
        initPopper() {
            this.referenceElm = this.$el;
            this.popperElm = this.$refs.menu.$el;
            this.updatePlacement();
        }
    },
    created() {
        this.$on('toggle-collapse', this.handleCollapseToggle);
        this.$on('child-mouse-enter', o => {
            this.mouseInChild = true;
            clearTimeout(this.timeout);
        });
        this.$on('child-mouse-leave', o => {
            this.mouseInChild = false;
            clearTimeout(this.timeout);
        });
    },
    mounted() {
        this.parentMenu.addSubmenu(this);
        this.jddMenu.addSubmenu(this);
        this.initPopper();
    },
    beforeDestroy() {
        this.parentMenu.removeSubmenu(this);
        this.jddMenu.removeSubmenu(this);
    }
};
</script>
