<template>
    <menu-item v-if="isLeaf" :menu="menu" ref="title" @selected="onSubMenuSelected" :depth="depth" :collapse="collapse" :width="width" :colors="colors" :activeId="activeId"></menu-item>
    <li v-else @mouseenter="enterBody" @mouseleave="leaveBody">
        <div class="sub-menu-title" :style="titelStyle" ref="title" @click.stop="isOpen=!isOpen" @mouseenter="hover = true" @mouseleave="hover = false">
            <i class="icon fa-fw" :class="menu.icon" v-if="menu.icon"></i>
            <transition name="el-fade-in">
                <span v-if="!collapse || depth > 0">{{menu.name}}</span>
            </transition>
            <transition name="el-fade-in">
                <i class="el-icon-arrow-left" v-if="!collapse || depth > 0" :class="{open:isOpen}"></i>
            </transition>
        </div>
        <transition :name="transitionName">
            <div class="sub-menu-wrapper" :style="menuStyle" v-show="isOpen">
                <ul class="sub-menu" :style="subMenuStyle" ref="child">
                    <!-- <slot :isOpen="isOpen" @onSelected="onSubMenuSelected"></slot> -->
                    <sub-menu v-for="item in menu.children" :key="item.id" :menu="item" :depth="depth+1" :width="width" :collapse="collapse" :colors="colors" :activeId="activeId" @selected="onSubMenuSelected" @opened="onSubMenuOpened"></sub-menu>
                </ul>
            </div>
        </transition>
    </li>
</template>
<script>
import tinyColor from 'tinycolor2'
import MenuItem from './MenuItem'
export default {
    name: 'SubMenu',
    props: {
        menu: {
            type: Object,
            required: true
        },
        depth: {
            type: Number,
            default: 0
        },
        parentIsOpen: {
            type: Boolean,
            default: false
        },
        collapse: {
            type: Boolean,
            default: false
        },
        width: {
            type: Number
        },
        colors: {
            type: Object
        },
        activeId: {}
    },
    data() {
        return {
            x: 0,
            y: 0,
            w: 0,
            h: 0,
            c: 0,
            isOpen: false,
            active: false,
            collapsing: false,
            hover: false
        }
    },
    mounted() {
        this.reCale()
    },
    computed: {
        isLeaf() {
            return !(this.menu.children instanceof Array)
        },
        titelStyle() {
            let style = {
                paddingLeft: this.depth === 1 && !this.collapse ? '45px ' : '',
                color: this.colors.textColor
            }
            if (this.active && (this.collapse || (this.depth > 0))) {
                style.backgroundColor = this.colors.activeBackgroundColor
                style.borderLeft = `2px solid ${this.colors.textColor}`
            } else if (this.hover) {
                style.backgroundColor = this.colors.hoverBackgroundColor
            } else {
                style.backgroundColor = this.colors.backgroundColor
            }
            return style
        },
        menuStyle() {
            if ((this.collapse || (this.depth > 0)) && !this.collapsing) {
                let style = {
                    position: 'absolute',
                    left: this.x + this.w + 'px',
                    height: 56 * this.c + 10 + 'px',
                    paddingLeft: '5px',
                    zIndex: 3
                }
                if (this.y + 56 * this.c + 10 > window.innerHeight) {
                    style.top = window.innerHeight - 56 * this.c - 15 + 'px'
                } else {
                    style.top = this.y + 'px'
                }
                return style
            }
            return {
                height: 56 * this.c + 'px'
            }
        },
        subMenuStyle() {
            let style = {
                backgroundColor: this.colors.backgroundColor
            }
            if ((this.depth > 0 || this.collapse) && !this.collapsing) {
                style = {
                    ...style,
                    width: this.width + 'px',
                    boxSizing: 'border-box',
                    padding: '5px 0',
                    borderRadius: '2px',
                    boxShadow: '0 2px 12px 0 rgba(0, 0, 0, 0.1)'
                }
            }
            return style
        },
        transitionName() {
            if (this.collapsing) {
                return 'menu-collapse'
            }
            return this.collapse || (this.depth > 0) ? 'menu-zoom' : 'menu-collapse'
        }
    },
    methods: {
        activeChange(activeId) {
            if (activeId instanceof Array && activeId.indexOf(this.menu.id) === -1) {
                this.active = false
            }
            this.$children.forEach(child => {
                child.activeChange(activeId)
            })
        },
        openedChange(openedId) {
            if (openedId.indexOf(this.menu.id) === -1) {
                this.isOpen = false
            }
            this.$children.forEach(child => {
                child.openedChange(openedId)
            })
        },
        reCale() {
            this.x = this.$refs.title.offsetLeft
            this.y = this.$refs.title.offsetTop
            this.w = this.$refs.title.offsetWidth
            this.h = this.$refs.title.offsetHeight
            if (!this.isLeaf) {
                this.c = this.$refs.child.childElementCount
            }
        },
        enterBody(e) {
            if (this.collapse || (this.depth > 0)) {
                this.isOpen = true
            }
        },
        leaveBody(e) {
            if (this.collapse || (this.depth > 0)) {
                this.isOpen = false
            }
        },
        onSubMenuSelected(e) {
            this.active = true
            if (this.depth === 0 && !this.collapse) {
                this.isOpen = true
            }
            let selected = [this.menu.id, ...e]
            if (this.isLeaf) {
                this.$emit('selected', e)
            } else {
                this.$emit('selected', selected)
            }
        },
        onSubMenuOpened(e) {
            this.$emit('opened', [this.menu.id, ...e])
        }
    },
    watch: {
        parentIsOpen(val) {
            if (!val) this.isOpen = false
        },
        isOpen(val) {
            this.reCale()
            if (val) {
                this.$emit('opened', [this.menu.id])
            }
        },
        collapse(val) {
            if (val) {
                this.collapsing = true
                setTimeout(() => {
                    this.collapsing = false
                }, 300);
                this.isOpen = false
            } else {
                this.isOpen = this.active && this.depth === 0 ? true : false
            }
        }
    },
    components: {
        MenuItem
    }
}
</script>
<style lang="less" scoped>
.sub-menu-title {
    height: 56px;
    line-height: 56px;
    font-size: 14px;
    padding: 0 20px;
    box-sizing: border-box;
    transition: background-color 0.2s, color 0.2s;
    position: relative;
    .icon {
        margin-right: 6px;
    }
    .el-icon-arrow-left {
        position: absolute;
        right: 20px;
        top: 50%;
        margin-top: -7px;
        font-size: 12px;
        transition: all 0.3s;
        &.open {
            transform: rotate(-90deg);
        }
    }
    * {
        vertical-align: middle;
    }
}

.menu-collapse-enter,
.menu-collapse-leave-active {
    height: 0 !important;
}
.menu-collapse-enter-active,
.menu-collapse-leave-active {
    transition: height 0.3s ease;
    transform: translate3d(0, 0, 0);
    overflow: hidden;
}

.menu-zoom-enter,
.menu-zoom-leave-active {
    transform: scale3d(0.2, 0.2, 1);
    opacity: 0;
}
.menu-zoom-enter-active,
.menu-zoom-leave-active {
    transform-origin: 0 0;
    transition: transform 0.3s cubic-bezier(0.23, 1, 0.32, 1),
        opacity 0.3s cubic-bezier(0.23, 1, 0.32, 1);
    overflow: hidden;
}
</style>
