<template lang="pug">
    .oc-tree-select-container.vm(ref="dropContainer", tabindex="-1", @blur.capture="_blurHandler($event)", :disabled="disabled", @mouseenter="handlehoverClearIcon", @mouseleave="handlehideHoverClearIcon")
        .pr.h
            select.ocFormElement(ref="ocFormElement", :name="name", tabindex="-1", :required="required", :multiple="multiple", :disabled="disabled")
                option(:selected="true", v-for="id in selected", :value="id")
            .oc-ipt-result(@focus.capture="show($event)", :class="{ multipleLine: isMultipleLine, showClearAll: isShowClearAll }", :style="iptStyle", tabindex="0", ref="ipt", :disabled="disabled", @keyup.enter="$emit('enter')")
                i.oc-select-clear-icon.fa.fa-times-circle(v-if="isShowClearAll && !disabled", tabindex="1", @click="handleClear")
                div.oc-ipt-tip.ml5(v-if="!selected.length") Please select
                template(v-else)
                    span.oc-ipt-result-item(v-for="id in selected", tabindex="-1", :title="getSelectedFullText(id)", :data-id="id") {{getSelectedText(id)}}
                        i(tabindex="-1", @click.stop.prevent="remove(id)", v-if="!disabled") ×
</template>

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

    export default {
        name: 'oc-treeselectdom',
        mixins: [ formElement, blurHandler ],

        props: {
            iptStyle: null,

            // 根据名称过滤--------
            textFilters: { type: Array, default: null },

            //支持直接放入html的构建
            treeNode: { type: Object, default: null },
            
            isAutoFocusSearch: { type: Boolean, default: false },
            isMultipleLine: { type: Boolean, default: false }, //多行显示 ---

            isDisableItem: { type: Boolean, default: false }, //是否限制选择某些可维护属性
            
            minShowLevel: { type: Number, default: null },
            limitedLevel: { type: Number, default: null },  //最多显示的级别
            isOnlySelectedLast: { type: Boolean, default: false }, //是否限制只允许选中最后一级, 有时第三级是最后一级，有时第四级是
            onlySelectedLevel: { type: Number, default: null },  //限制只能选中的级别
            
            defaultShowLevel: { type: Number, default: null }, //配置了此值将展示展开折叠的功能
            isPopperElmFromParent: { type: Boolean, default: false }
        },

        data() {
            return { 
                popperElm: null,
                _timer: null,
                _blurTimer: null,
                keyword: null,
                isTop: false,
                isShowClearAll: false
            }
        },

        computed: {
            currentTreeNode() {
                return this.treeNode;
            },
            
            selected() {
                if(this.currentValue === null || this.currentValue === undefined || this.currentValue === '') {
                    return [];
                }
                let selected = (this.currentValue instanceof Array)? this.currentValue : [this.currentValue];
                return selected.map(one => this.getString(one));
            },
            selectedIds() {
                return this.selected;
            }
        },

        watch: { 
            keyword(val, oldVal) {
                if((oldVal || '').toString() === (val || '').toString()) {
                    return;
                }
                
                this.filterByKeyword();
            },

            selected() {
                this.setSelectedStatus();
            },
            
            currentTreeNode(newNode, oldNode) {
                this.beforeRemoveTreeNodeFromBody && this.beforeRemoveTreeNodeFromBody();
                this.$nextTick(_ => {
                    oldNode && oldNode.remove();
                    this.appendTreeNodeToBody();
                })
            }
        },

        mounted() {
            this.appendTreeNodeToBody();

            var slc = this.$refs.ocFormElement;
           
            if(this.value && !this.currentValue) {
                this.setValueToCurrent(this.value);
            }

            //调用oc.tools.form.fill赋值时，会触发onchange
            if(slc) {
                // console.log('appendTreeNodeToBody:', slc);
                slc.onchange = (e, val) => {
                    this.setValueToCurrent(val);
                    
                    //fill时的值，有可能跟最终的值不一致，使用组件中最终的值 ----
                    this.$nextTick(_ => {
                        $(slc).val(this.currentValue);
                    })
                }
            }
        },

        beforeDestroy() {
            this.hide();
        },

        methods: {
            //保证tree dom在body中的唯一性 ----
            appendTreeNodeToBody() {
                if(this.currentTreeNode && this.currentTreeNode.parent()[0] !== document.body) {
                    this.currentTreeNode.appendTo(document.body).addClass('ocTreeSelectPop');
                }

                this.currentTreeNode && (this.popperElm = this.currentTreeNode[0]);
            },

            //初始化treeNode上的方法 -----
            initTreeNode() {
                this.currentTreeNode[0].removeEventListener('blur', this._blurHandler, true);
                this.currentTreeNode[0].addEventListener('blur', this._blurHandler, true);
                this.currentTreeNode.off('click').on('click', this.treeBodyClickHandler);
                this.currentTreeNode.off('mouseover').on('mouseover', this.treeBodyMouseenterHandler);
                this.currentTreeNode.off('input', 'input').on('input', 'input', this.filter);
                this.currentTreeNode.find('input').val('');
            },

            show(event) {
                let timer = new Date().getTime();
                if(this.disabled || event.target.nodeName === 'I') {
                    return;
                }
                let headWidth = this.$refs.dropContainer.clientWidth;
                setTimeout(_ =>{
                    if(this.currentTreeNode) {
                        //防止treeSelectDom被同层（z-index)遮盖
                        this.currentTreeNode.appendTo(document.body);
                        this.initTreeNode();
                        this.keyword = null;
                        this.filterByKeyword();
                        this.currentTreeNode.css('min-width', headWidth + 'px');
                        this.resetPosition();
                        this.currentTreeNode.addClass('drop-enter-active');
                        this.filterNodeByLevel();

                        this.$nextTick(_ => {
                            setTimeout(_ => {
                                this.currentTreeNode.removeClass('drop-enter-active');
                            }, 300)
                            
                            this.isAutoFocusSearch && this.currentTreeNode.find('.iptFilter').focus();

                            // console.log('tree timer2', new Date().getTime() - timer);
                            this.setSelectedStatus();
                            this.filterCustomer();
                            
                            let ocTreeSelectDropBody = this.currentTreeNode.find('.oc-tree-select-drop-body');
                            ocTreeSelectDropBody.scrollTop(0);

                            window.document.body.addEventListener('scroll', this.windowScroll, true);

                            this.afterShow && this.afterShow(event);
                            this.$emit('afterShow', event);
                            this.$emit('focus');
                        })
                    }

                },0)
            },

            //设置位置
            resetPosition(isResetHeight = true) {
                this.isTop = putAside(this.$refs.dropContainer, this.currentTreeNode[0], isResetHeight) > 0;
                this.isTop? this.currentTreeNode.addClass('top') : this.currentTreeNode.removeClass('top');
            },

            hide() {
                if(!this.currentTreeNode) {
                    return;
                }
                this.currentTreeNode.css('left', '-3000px');
                this.currentTreeNode.off('click').off('input', 'input');
                this.currentTreeNode[0].removeEventListener('blur', this._blurHandler, true);
                window.document.body.removeEventListener('scroll', this.windowScroll, true);

                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();
                        }
                    }
                    this.afterHide && this.afterHide();
                    this.$emit('afterHide');
                })
            },

            handleClear(event) {
                this.currentValue = null;
                this.$refs.dropContainer.focus();
            },

            handlehideHoverClearIcon(){
                this.isShowClearAll = false;
            },

            handlehoverClearIcon() {
                if(this.selected.length){
                    this.isShowClearAll = true;
                }
            }, 

            setValueToCurrent(val) {
                if(!this.multiple) {
                    this.currentValue = val;
                    return;
                }

                if(!val) {
                    this.currentValue = [];
                    return;
                }
                
                if(!Number(val) && typeof val === 'string' && val.split) {

                    let jsonArr = val;
                    if(val.indexOf('[') > -1) { //JSON字符串 ---
                        try {
                            jsonArr = JSON.parse(val);
                        }
                        catch(err) {
                            console.log(err)
                        }
                    } else {
                        jsonArr = val.split(',')
                    }

                    this.currentValue = jsonArr.filter(one => {
                        return $.trim(one) !== '';
                    }).map(one => one.toString());
                }
                else if(Array.isArray(val)) {
                    this.currentValue = val.map(one => this.getString(one));
                }
                else {
                    this.currentValue = [this.getString(val)];
                }
            },

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

            //展示层级上 ----
            filterNodeByLevel() {
                if(!this.currentTreeNode) {
                    return;
                }

                let node = this.currentTreeNode;
                node.find('.treeItem').removeClass('notInSelectedLevel').removeClass('lastShowLevel').removeClass('notInShowLevel').removeClass('open').removeClass('treeItemHideText')
                .css('margin-left', 0);

                let ocTreeSelectDropBody = this.currentTreeNode.find('.oc-tree-select-drop-body');
                ocTreeSelectDropBody.removeClass('disableItem');
                this.isDisableItem && ocTreeSelectDropBody.addClass('disableItem');


                if(this.minShowLevel) {
                    let items = node.find('.treeItem[data-level="'  + this.minShowLevel + '"]');
                    items.css('margin-left', '-' + (this.minShowLevel - 1) * 20 + 'px').parents('.treeItem').addClass('treeItemHideText');
                }

                let maxShowLevel = this.limitedLevel || this.onlySelectedLevel;
                if(this.onlySelectedLevel && this.onlySelectedLevel < this.limitedLevel) {
                    maxShowLevel = this.onlySelectedLevel;
                } 

                if(maxShowLevel) {
                    let items = node.find('.treeItem[data-level="'  + maxShowLevel + '"]');
                    items.addClass('lastShowLevel').find('.treeItem').addClass('notInShowLevel');
                }

                if(this.onlySelectedLevel) { //不能selected的子级隐藏
                    let items = node.find('.treeItem[data-level="'  + this.onlySelectedLevel + '"]');
                    node.find('.treeItem').addClass('notInSelectedLevel');
                    items.addClass('lastShowLevel').removeClass('notInSelectedLevel')
                    // .parents().addClass('notInSelectedLevel');
                }

                if(this.isOnlySelectedLast) {
                    node.find('.treeItem:not(.notInShowLevel)').each((index, one) => {
                        let item = $(one);
                        if(item.find('.treeItem:not(.notInShowLevel)').length) {
                            item.addClass('notInSelectedLevel');
                        }
                    })
                }

                this.resetOpenLevel();
                
                return node;
            },

            resetOpenLevel() {
                let defaultShowLevel = this.defaultShowLevel;
                if(!defaultShowLevel || (this.minShowLevel && this.minShowLevel > defaultShowLevel)) {
                    defaultShowLevel = this.minShowLevel;
                }
                if(defaultShowLevel) {
                    this.currentTreeNode.addClass('toggleOpen');
                    let openItems = this.currentTreeNode.find('.treeItem.hasmore[data-level="' + (defaultShowLevel - 1) + '"]');
                    openItems.addClass('open').parents().addClass('open');
                }
            },

            getSelectedText(id) {
                if(!this.currentTreeNode) {
                    return '';
                }
                return this.currentTreeNode.find('.content[data-id="' + id + '"] .text').first().text();
            },

            getSelectedFullText(id) {
                if(!this.currentTreeNode) {
                    return '';
                }
                let currentItem = this.currentTreeNode.find('.treeItem[data-id="' + id + '"]');
                let textes = [];
                currentItem.parents('.treeItem').each((index, one) => {
                    textes.push($(one).find('>.content>.text').text());
                })
                textes = textes.slice(0, -1);
                textes.reverse().push(currentItem.find('>.content>.text').text());

                return textes.join(' - ');
            },
            
            remove(id) {
                if(this.multiple) {
                    let index = this.currentValue.indexOf(id);
                    if(index !== -1) {
                        this.currentValue.splice(index, 1);
                    }
                }
                else {
                    this.currentValue = null;
                }

                this.$refs.dropContainer.focus();
            },

            // dispatchInput() {
            //     if(!this.currentTreeNode) {
            //         return;
            //     }
            //     this.$nextTick( e => {
            //         this.$emit('input', this.currentValue, this.$refs.ocFormElement);
            //     })
            // },

            toggleOpen(i) {
                let treeItem = $(i).closest('.treeItem');

                if(treeItem.hasClass('selected')) {
                    return;
                }
                else {
                    treeItem.toggleClass('open');
                }
            },
            treeBodyMouseenterHandler(event) {
                let ele = event.target;
                let treeItem
                if(ele.nodeName === 'I' && ele.classList.contains('fa')) {
                    return this.toggleOpen(ele);
                }
                if(ele.classList.contains('text')) {
                    ele = ele.parentNode;
                }
                if(ele.classList.contains('content')) {
                    treeItem = $(ele).parent();
                } else if (ele.parentNode.classList.contains('content')){
                    ele = ele.parentNode;
                    treeItem = $(ele).parent();
                } else {
                    return 
                }
                let id = ele.getAttribute('data-id');
                if(!id || id === "undefined") {
                    return;
                }  
                this.$emit('mouseenterHandle',id);
            },
            treeBodyClickHandler(event) {
                let ele = event.target;
                let treeItem
                if(ele.nodeName === 'I' && ele.classList.contains('fa')) {
                    return this.toggleOpen(ele);
                }
                if(ele.classList.contains('text')) {
                    ele = ele.parentNode;
                }

                if(ele.classList.contains('content')) {
                    treeItem = $(ele).parent();
                } else if (ele.parentNode.classList.contains('content')){
                    ele = ele.parentNode;
                    treeItem = $(ele).parent();
                } else {
                    return 
                }
                // if(!ele.classList.contains('content')) {
                //     return;
                // }

                
                let id = ele.getAttribute('data-id');
                if(!id || id === "undefined") {
                    return;
                }
                
                if(this.isDisableItem && treeItem.hasClass('disabled')) {
                    return;
                }
                
                //不管是不是disable状态，如果选中的，点击时可以取消，防止赋值错误出现下级不能显示 ----
                if(!this.multiple) {
                    if(this.currentValue == id) {
                        this.currentValue = null;
                        return;
                    }
                }
                else {
                    let index = (this.currentValue || []).indexOf(id); 

                    //已被选中则去除
                    if(index !== -1) {
                        this.currentValue.splice(index, 1);
                        return;
                    }
                }
                
                
                if(treeItem.hasClass('notInSelectedLevel')) {
                    return;
                }
                else if(this.isOnlySelectedLast) {
                    //只允许选择最后一级，这时候，如果有子节点，则自动忽略
                    if(treeItem.find('.treeItem:not(.notInShowLevel)').length > 0) {
                        return;
                    }
                    else {
                        this.$emit('select',id);
                        this.addSelected(id);
                    }
                }
                else {
                    this.addSelected(id, treeItem);
                }
            },

            addSelected(id, selectedItem) {
                if(this.multiple) {
                    if(!this.currentValue) {
                        this.currentValue = [];
                    }
                    this.currentValue.push(id);
                    //去除选中的子节点---
                    if(selectedItem) {
                        let selected = this.currentValue;
                        selectedItem.find('.treeItem').each(function(one) {
                            let childId = this.getAttribute('data-id');
                            let index = selected.indexOf(childId);
                            index !== -1 && selected.splice(index, 1);
                        })
                    }
                }
                else {
                    this.currentValue = id;
                    this.hide();
                }
            },
            
            filter(e) {
                e.preventDefault();
                this._timer && clearTimeout(this._timer);
                this._timer = setTimeout( t => {
                    this.keyword = e.target.value.trim();
                }, 300)
            },

            setSelectedStatus() {
                let container = this.currentTreeNode
                if(!container || !container.is(':visible')) {
                    return;
                }
                container.find('.treeItem.selected').removeClass('selected');
                if(!this.selected || !this.selected.length) {
                    return;
                }

                this.selected.map(one => {
                    container.find('.treeItem[data-id="' + one + '"]').addClass('selected');
                })
            },

            //自定义的过滤条件，优先于keyword
            filterCustomer() {
                let container = this.currentTreeNode;
                if(!container || !container.is(':visible')) {
                    return;
                }

                let textFilters = this.textFilters;
                //如果没有过滤，则全部显示----
                if(!textFilters || !textFilters.length) {
                    container.find('.treeItem[data-level="1"]').removeClass('firstHidden');
                }
                else {
                    textFilters = textFilters.map(one => one.toLowerCase());
                    //判断第一级是不是在这里面----
                    let firstLevelItems = container.find('.treeItem[data-level="1"]').addClass('firstHidden');
                    firstLevelItems.each(function() {
                        let firstLevelItem = $(this);
                        let text = firstLevelItem.find('>.content>.text').text();
                        if(textFilters.indexOf(text.toLowerCase()) !== -1) {
                            firstLevelItem.removeClass('firstHidden');
                        }
                    })
                }
            },
            
            filterByKeyword() {
                let container = this.currentTreeNode;
                if(!container || !container.is(':visible')) {
                    return;
                }
                container.find('.text.filter-text').removeClass('filter-text')
                //如果没有过滤，则全部显示----
                if(!this.keyword) {
                    container.find('.treeItem').removeClass('hidden').removeClass('open');
                    this.resetOpenLevel();
                    return;
                }

                let keyword = this.keyword.toUpperCase();
                
                container.find('.treeItem').addClass('hidden').removeClass('open');

                let filterItems = container.find('.text').each(function() {
                    let ele = $(this);
                    let treeItem = ele.parents('.treeItem:eq(0)');
                    if(treeItem.hasClass('firstHidden')) {
                        return;
                    }
                    if(ele.text().toUpperCase().indexOf(keyword) !== -1) {
                        ele.addClass('filter-text');
                        ele.parents('.treeItem').removeClass('hidden').addClass('open');
                        treeItem.find('.treeItem').removeClass('hidden')
                    }
                })
            }
        }
    }
</script>

<style lang="stylus">
    .oc-tree-select-container
        vertical-align middle
        display inline-block
        &:focus
            outline none
        .ocFormElement
            opacity 0
            position absolute
            left 0
            width 0
            top 0
            bottom 0
            height 100%
            width 100%
            z-index -1
        .oc-ipt-result
            padding 3px
    .oc-tree-select-filter
        height 40px
        padding 5px
        .iptFilter
            width 100%
            border-radius 0
    
    .ocTreeSelectPop
        position fixed
        top 0
        background-color #fff
        z-index 2000
        left -3000px
        border-radius 2px
        border 1px solid #d1dbe5
        box-shadow 0 2px 4px rgba(0,0,0,0.12), 0 0 6px rgba(0,0,0,0.04)
        overflow auto
        min-width 320px
        display flex 
        flex-direction column
        transform-origin 0 0
        
        &.hide 
            max-width 0
            overflow hidden
            left -10px
        &:focus
            outline none
        &.top 
            flex-direction column-reverse
        .fa-caret-down
            display none
        &.toggleOpen
            .treeItem.hasmore:not(.open)
                >.treeItem 
                    display none !important
            
            .text
                position relative
                padding-left 15px
                .fa-caret-down
                    display block
                    padding 5px 8px
                    position absolute
                    top 2px
                    left -5px
                    color inherit
                    cursor pointer
                    &:before
                        content '\f0da'
                        padding-left 1px
                    &:hover 
                        color inherit
                &.filter-text
                    color #e9c311
            .treeItem.open
                >.content
                    .fa-caret-down:before
                        content '\f0d7'
                        padding-left 0px

    .oc-tree-select-drop-body
        padding-bottom 10px
        min-width 240px
        overflow auto
        width 100%
        max-height 100%
        flex 1
        >.treeItem
            margin-left -32px
            >.content
                display none
        
        .treeItem.notInSelectedLevel, .treeItem[data-id="undefined"], .treeItem[data-id="null"]
            >.content
                color #888 !important
                &:hover
                    background-color transparent
                    cursor default
        .treeItem
            .iconDisabled
                display none
            &.notInShowLevel
                display none !important
            &.lastShowLevel
                >.content>.text>.fa-caret-down
                    display none !important
            &.selected
                >.content
                    .fa 
                       color #bbb
                       cursor default
            &.treeItemHideText 
                >.content
                    display none !important
        &.disableItem 
            .treeItem.disabled
                >.content
                    color #888 !important
                    &:hover
                        background-color transparent
                        cursor default   
                    >.iconDisabled
                        display inline-block
                        margin-left 3px    

    
</style>
            
