<template lang="pug">
    .ocDrop(ref="dropContainer", tabindex="-1", @blur="_blurHandler($event)")
        .dropHead(ref="dropHead", tabindex="-1", @focus.capture="show($event)", @blur.capture="_blurHandler($event)", @mouseenter="handleMouseenterHead", @mouseleave="handleMouseleaveHead")
            slot(name="dropHead")

        transition(name="drop")
            .ocDropBody.ocScroll(ref="dropBody", :class="{ dropFlex: isFlex, flexTop: isTop }", tabindex="-1", @blur.capture="_blurHandler($event)", :style="dropBodyStyle", v-if="isShow", @mouseenter="handleMouseenter", @mouseleave="handleMouseleave")
                slot(name="dropBody")
</template>

<script>    
    import putAside from './util/putaside'
    import blurHandler from './mixins/blurHandler'

    export default {
        mixins: [ blurHandler ],
        name: 'oc-dropdown',
        props: {
            isHover: { type: Boolean, default: false },
            dropBodyStyle: null,
            isFlex: { type: Boolean, default: false },
            isSetMinWidth: { type: Boolean, default: true},
            disabled: { type: Boolean, default: false },
        },
        data() {
            return {
                popperElm: null,
                isShow: false,
                hoverTimer: null,
                scrollTimer: null,
                windowScrollTimer: null,
                isTop: false //是否显示在顶部
            }
        },

        computed: {
            dropBody() {
                return this.$refs.dropBody;
            }
        },

        beforeDestroy() {
            window.document.body.removeEventListener('scroll', this.windowScroll, true);
            if(this.dropBody) {
                this.dropBody.removeEventListener('scroll', this.scrollHandler);
                this.dropBody.remove();
            }
        },

        methods: {
            windowScroll(e) {
                let element = e.target;
                clearTimeout(this.windowScrollTimer);
                this.windowScrollTimer = setTimeout(_ => {
                    if(element.contains(this.$refs.dropHead)) {
                        this.resetPosition(false);
                    }
                }, 30)
            },

            hide () {  
                window.document.body.removeEventListener('scroll', this.windowScroll, true);
                this.clearHoverTimeout();
                if(this.isShow) {
                    this.isShow = false;
                    //如果是popperElm子元素，则focus住
                    this.$emit('hide');
                    
                    this.$nextTick(_ => {
                        if(this.$refs.dropContainer) {
                            let parentDropBody = $(this.$refs.dropContainer).parents('.ocDropBody');
                            //如果是popperElm子元素，且focus不在此元素内部了，则focus住
                            if(parentDropBody.length && !parentDropBody[0].contains(document.activeElement)) {
                                this.$refs.dropContainer.focus();
                            }
                        }
                    })
                }   
            },

            scrollHandler(e) {
                let element = e.target;
                clearTimeout(this.scrollTimer);
                this.scrollTimer = setTimeout(e => {
                    this.$emit('scroll', element.clientHeight, element.scrollTop, element);
                }, 30)
            },

            show (event) {
                this.clearHoverTimeout();
                // console.log('show called', this.hoverTimer);
                //点击I图标时，不作操作 ---
                if(this.isShow || this.disabled || (event && event.target && event.target.nodeName === 'I') ) {
                    return;
                }

                this.isShow = true;
                this.$nextTick(e => {
                    this.$refs.dropBody.style.minWidth = '0px';
                    if(this.isSetMinWidth) {
                        this.$refs.dropBody.style.minWidth = this.$refs.dropHead.clientWidth + 'px';
                    }
                    this.popperElm = this.$refs.dropBody;
                    
                    this.$refs.dropContainer.popperElm = this.popperElm;
                    let dropBody = this.$refs.dropBody;
                    dropBody.parentNode !== document.body && document.body.appendChild(dropBody);
                    
                    //等待appendTo body完成--, todo 重构这里，组件应该保持独立性----
                    this.$nextTick(_ => {
                        let isTop = this.resetPosition();
                        
                        this.$nextTick(e => {
                            this.$emit('show', isTop);
                        })
                        if(dropBody.querySelector('.oc-select-drop-body')) {
                            dropBody = dropBody.querySelector('.oc-select-drop-body');
                        }
                        dropBody.addEventListener('scroll', this.scrollHandler);
                        window.document.body.addEventListener('scroll', this.windowScroll, true);
                    })
                })
            },

            resetPosition(isResetHeight = true) {
                return putAside(this.$refs.dropHead, this.$refs.dropBody, isResetHeight) === 1;
            },

            clearHoverTimeout() {
                let comp = this;
                while(comp) {
                    clearTimeout(comp.hoverTimer);
                    comp = comp.$parent;
                }
            },

            handleMouseenterHead() {
                this.$emit('mouseenterHead');
                this.handleMouseenter();
            },

            handleMouseleaveHead() {
                this.$emit('mouseleaveHead');
                this.handleMouseleave();
            },

            handleMouseenter() {
                this.clearHoverTimeout();
                clearTimeout(this.hoverTimer);
                if(!this.isHover || this.isShow) {
                    return;
                }
                // console.log('handleMouseenter:', this.popperElm && this.popperElm.innerHTML);
                this.hoverTimer = setTimeout(_ => {
                    this.show();
                }, 250)
            },

            handleMouseleave () {
                this.clearHoverTimeout();
                if(!this.isHover || !this.isShow) {
                    return;
                }
                // console.log('handleMouseleave', this.popperElm, new Date().getTime(), this._uid);
                
                this.hoverTimer = setTimeout(_ => {
                    this.isShow = false;
                }, 250);
            }
        }
    }
</script>

<style lang="stylus" scoped>
    .ocDrop
        position relative
        display inline-block
        &:focus
            outline none
    .dropHead
        &:focus
            outline none
    .ocDropBody
        width auto
        overflow auto
        position absolute
        z-index 2000
        background #fff
        border-radius 2px
        border 1px solid #d1dbe5
        list-style none
        overflow auto
        box-shadow 0 2px 4px rgba(0,0,0,.12), 0 0 6px rgba(0,0,0,.04)
        line-height 25px
        transition top .2s
        &:focus
            outline none
        &.dropFlex
            display flex 
            flex-direction column
        &.flexTop, &.ocPopTop
            flex-direction column-reverse
        
    
</style>

