<template lang="pug">
    div(ref="container", style="display: inline-block")
        oc-treeselectdom.w(ref="tree", :required="required", :isOnlySelectedLast="isLast", :isDisableItem="isDisableItem", :isAutoFocusSearch="true", :textFilters="textFilters", :treeNode="treeNode", :addSelectedHandler="addSelectedHandler", :multiple="multiple", :value="treeValue", :name="name", @input="input", @afterShow="afterShow", @afterHide="clearData", :isPopperElmFromParent="true", :customerFilterHandler="customerFilterHandler")
        
        div#divProps.f12.formSm.pt10(ref="divProps", v-show="activePropId !== null", style="position: absolute; left: 0; top: 0; width: 100%; height: 100%; background: rgba(255, 255, 255, .9)")
            p.pl15.fb.pb10.mb10(style="border-bottom: 1px solid #eee;") 当前节点：{{activePropName}}
            div.divPropsItem.pb5.mr30.ml15(v-for="item in formatedNodeProperties", style="display: inline-block;")
                span(style="display: inline-block; width: 120px; white-space: nowrap; overflow: hidden; vertical-align:middle") {{item[propertyNameKey] + ':'}}
                oc-select.w150(:items="item[propertyValueKey]", :name="item[propertyKey]", :isAll="true", :value="item[defaultValueKey]", :disabled="item[isSystemPropertyKey]")
            div.pt10.pl20
                button.info.w80.sm(type="button", @click="confirm") 确 认
                button.ml10.w80.sm(type="button", @click="cancel") 取 消

        span#divFormProps(ref="divFormProps", v-if="isUseFormProperties")
            span.pb5(v-for="item in selectedSameProperties", :style="{ display: 'inline-block', 'margin-right': formPropsStyle.itemMarginRight }")
                label(:style="{ display: 'inline-block', 'color': '#888', overflow: 'hidden', 'vertical-align': 'middle', width: samePropsLabelWidth, 'margin-right': formPropsStyle.labelMarginRight }") {{item[propertyNameKey] + ':'}}
                oc-select.w150(:items="item[propertyValueKey]", :name="(formPropertiesPrefix || '') + item[propertyKey] + '_in'", :isAll="true", multiple)
</template>

<script>
    import ocDialog from './js/dialog'
    import ocForm from './js/form'

    export default {
        name: 'oc-tagselect',
        props: {
            treeNode: { type: Object, default: null },
            treeDataNodes: { type: Array, default: null },
            baseProperties: { type: Array, default: null },

        	name: null,
        	value: null,
        	multiple: { type: Boolean, default: false },
            required: { type: Boolean, default: false },
            isLast: { type: Boolean, default: false },
            textFilters: { type: Array, default: null },
            isDisableItem: { type: Boolean, default: false },
            filterBuIds: { type: Array, default: null },
            isUseProperties: { type: Boolean, default: false },

            isUseFormProperties: { type: Boolean, default: false },
            formPropertiesPrefix: { type: String, default: null },  //查询时，额外附加的属性前缀
            buKey: { type: String, default: 'bu_code' },
            propertyParentKey: { type: String, default: 'issue_category_base_property_id' },
            nodePropertyKey: { type: String, default: 'properties' },
            propertyValueKey: { type: String, default: 'property_value' },
            propertyNameKey: { type: String, default: 'property_name' },
            propertyKey: { type: String, default: 'property_key' },
            defaultValueKey: { type: String, default: 'default_value' },
            isSystemPropertyKey: { type: String, default: 'is_system_property' },
        },

        data() {
            return {
                currentValue: null,

                activePropId: null,

                samePropsLabelWidth: '80px',
                
                formPropsStyle: {
                    itemMarginRight: '10px',
                    labelMarginRight: '0'
                },

                hiddenKeys: ['bu_code', 'module_category', 'chinese_version']
            }
        },

        computed: {
            treeValue() {
                if(!this.isUseProperties || !this.value) {
                    return this.value;
                }
                
                return this.multiple? this.value.map(one => one.id) : this.value.id;
            },

            activePropName() {
                if(!this.activePropId || !this.treeDataNodes || !this.treeDataNodes.length) {
                    return '';
                }
                
                let treeNode = this.treeDataNodes.find(one => one.id === parseInt(this.activePropId));
                return treeNode && treeNode.name;
            },

            nodeProperties() {
                if(!this.treeDataNodes || !this.activePropId) {
                    return [];
                }

                let treeNode = this.treeDataNodes.find(one => one.id === parseInt(this.activePropId));
                return treeNode[this.nodePropertyKey] || [];
            },

            //当前激活节点的属性 ----
            formatedNodeProperties() {
                var self = this;
                return this.nodeProperties.map(one => {
                    let target = this.baseProperties.find(item => item.id === one[self.propertyParentKey]);
                    if(!target || this.hiddenKeys.indexOf(target[self.propertyKey]) !== -1) {
                        return null;
                    }

                    target = $.extend(true, {}, target);
                    let propertyValueKey = this.propertyValueKey;
                    //按照可选范围进行过滤 ----
                    let valueObj = this.getObjFromString(target[propertyValueKey]);

                    let validValues = this.filterPropValueFromBu(one[propertyValueKey]);
                    if(Array.isArray(validValues) && validValues.length) {
                        let newValueObj = {};
                        for(let key in valueObj) {
                            if(validValues.indexOf((valueObj[key]).toString()) !== -1) {
                                newValueObj[key] = valueObj[key];
                            }
                        }

                        valueObj = newValueObj;
                    }


                    target[self.propertyValueKey] = valueObj;
                    target[self.defaultValueKey] = this.filterPropValueFromBu(one[self.defaultValueKey]);

                    return target;
                }).filter(one => !!one);
            },

            buBaseProperty() {
                if(!this.baseProperties) {
                    return null;
                }
                return this.baseProperties.find(one => one[this.propertyKey] === this.buKey);
            },

            buBasePropertyValue() {
                if(!this.buBaseProperty) {
                    return null;
                }

                return JSON.parse(this.buBaseProperty[this.propertyValueKey]);
            },

            //所有选中的节点的共同属性值---
            selectedSameProperties() {
                if(!this.currentValue || !this.isUseFormProperties || !this.treeDataNodes || !this.treeDataNodes.length) {
                    return [];
                }

                if(this.currentValue.length === 0) {
                    return [];
                }

                //复制跟属性---
                let validBaseProps = $.extend(true, [], this.baseProperties).filter(one => this.hiddenKeys.indexOf(one[this.propertyKey]) === -1);
                
                let curr = this.currentValue;
                if(!this.multiple) {
                    curr = [this.currentValue];
                }
                curr.map(id => {
                    let treeNode = this.treeDataNodes.find(one => one.id === parseInt(id));
                    if(treeNode) {
                        let nodeProperties = treeNode[this.nodePropertyKey] || [];
                        let nodePropIds = nodeProperties.map(one => parseInt(one[this.propertyParentKey]));
                        validBaseProps = validBaseProps.filter(one => nodePropIds.indexOf(one.id) !== -1);
                    }
                })
                validBaseProps.map(one => {
                    one[this.propertyValueKey] = this.formatSelectObj(one[this.propertyValueKey]);
                    return one;
                })

                return validBaseProps;
            }
        },

        watch: {
            treeNode() {
                this.appendPropsDivToTree();
            },

            value() {
                if(this.value) {
                    this.currentValue = $.extend(true, Array.isArray(this.value)? [] : {}, this.value);
                }
                else {
                    this.currentValue = null;
                }
            }
        },

        mounted() {
            this.appendPropsDivToTree();
            this.appendFormPropsDivToTree();
        },
        
        methods: {
            //根据可用的bu过滤属性 ----
            filterPropValueFromBu(propValueString) {
                if(!propValueString) {
                    return null;
                }

                if(propValueString.indexOf('"') === -1) {
                    return propValueString;
                }
                
                let validValues = JSON.parse(propValueString);
                let isArray = Array.isArray(validValues);
                if(!validValues || (isArray && !validValues.length)) {
                    return null;
                }

                if(this.filterBuIds) {
                    validValues = validValues[this.filterBuIds[0]];

                }
                else if(isArray) {
                    return validValues;
                }
                return null;
            },

            appendPropsDivToTree() {
                if(this.treeNode && this.$refs.divProps.parentNode !== this.treeNode) {
                    this.treeNode.append(this.$refs.divProps);
                }
            },

            appendFormPropsDivToTree() {
                if(!this.isUseFormProperties) {
                    return;
                }
                let span = this.$refs.container.parentNode;
                let form = span.parentNode;

                if(this.$refs.divFormProps.parentNode !== form) {
                    $(span).after(this.$refs.divFormProps);
                    let label = span.querySelector('label');
                    if(span.classList.contains('ocFormItem')) {
                        this.formPropsStyle.itemMarginRight = '20px';
                        this.formPropsStyle.labelMarginRight = '5px';
                    }
                    this.$nextTick(_ => {
                        label && (this.samePropsLabelWidth = label.clientWidth + 'px');
                    })
                }
            },

            customerFilterHandler(container) {
                if(!this.filterBuIds || !this.filterBuIds.length || !this.buBaseProperty) {
                    return;
                }

                let treeItems = container.find('.treeItem:not(.firstHidden)');
                treeItems.addClass('firstHidden');

                let filterBuIds = this.filterBuIds;
                let properties = this.baseProperties;
                let treeDataNodes = this.treeDataNodes;
                let buBaseProperty = this.buBaseProperty;
                var self = this;

                treeItems.each(function() {
                    let ele = $(this);
                    let id = ele.attr('data-id');

                    let nodeModel = treeDataNodes.find(one => one.id === parseInt(id));
                    if(nodeModel) {
                        let buBasePropertyId = buBaseProperty.id;

                        let buProperty = nodeModel[self.nodePropertyKey].find(one => one[self.propertyParentKey] === buBasePropertyId);
                        if(buProperty) {
                            let validBus = JSON.parse(buProperty[self.propertyValueKey]);
                            let isFindOne = filterBuIds.find(one => validBus.indexOf((one).toString()) !== -1);
                            if(isFindOne) {
                                ele.removeClass('firstHidden');
                                ele.parents('.treeItem').removeClass('firstHidden');
                                ele.parents('.treeItem:eq(0)').find('.treeItem').removeClass('firstHidden');
                            }
                        }
                    }
                })
            },

            afterShow(event) {
                if(!this.isUseProperties) {
                    return;
                }
                let target = event.target;
                if(target.classList.contains('oc-ipt-result-item')) {
                    this.activePropId = target.getAttribute('data-id');
                    let params = this.currentValue;
                    if(this.multiple) {
                        params = this.currentValue.find(one => one.id === this.activePropId);
                    } 
                    this.$nextTick(_ => {
                        ocForm.fill(this.$refs.divProps, params);
                    })
                }
            },

            //清除掉那些必填项还没填写完整的数据 
            clearData() {
                if(!this.isUseProperties) {
                    return;
                }

                this.activePropId = null;

                let tree = this.$refs.tree;
                if(!tree.currentValue) {
                    return;
                }

                if(!this.currentValue) {
                    tree.currentValue = null;

                    return;
                }

                ocForm.clear(this.$refs.divProps);

                if(this.multiple) {
                    tree.currentValue = tree.currentValue.filter(id => {
                        return !!this.currentValue.find(one => one.id === id);
                    })
                }
                else if(this.currentValue.id !== tree.currentValue) {
                    tree.currentValue = null;
                }
            },

            showProps(id, params) {                
                this.activePropId = id;

                //不存在属性时，不处理
                if(this.nodeProperties.length) {
                    if(params) {
                        this.$nextTick(_ => {
                            ocForm.fill(divProps, params);
                        })
                    }
                }
                else {
                    this.confirm();
                }
            },

            confirm() {
                if(!this.activePropId) {
                    return;
                }

                let divProps = this.$refs.divProps;
                if(ocForm.validity(divProps)) {
                    let params = ocForm.getJson(divProps);
                    let treeNode = this.treeDataNodes.find(one => one.id === parseInt(this.activePropId));
                    params.id = this.activePropId;  

                    if(!this.multiple) {
                        this.$refs.tree.hide();

                        // this.currentValue = params;
                    }
                    else {
                        if(!this.currentValue) {
                            this.currentValue = [];
                        }
                        let index = this.currentValue.findIndex(one => one.id === this.activePropId);
                        if(index === -1) {
                            this.currentValue.push(params);
                        }
                        else {
                            this.currentValue.splice(index, 1, params);
                        }
                        ocForm.clear(divProps);
                        this.treeNode.find('.oc-tree-select-filter input').focus();
                    }

                    this.activePropId = null;
                    
                    this.$emit('input', this.currentValue);
                }
            },

            cancel() {
                this.clearData();
                this.treeNode.find('.oc-tree-select-filter input').focus();
            },

            formatSelectObj(propertyValue) {
                let ret = {};
                if(propertyValue.indexOf('{') > -1) { //JSON字符串 ---
                    try {
                        ret = JSON.parse(propertyValue);
                        return ret;
                    }
                    catch(err) {
                        ocDialog.tips('_select 组件 ' + this.config.propertyKey + ' 数据错误', 2000);
                    }
                }

                let isObject = propertyValue.indexOf(':') > 0 || propertyValue.indexOf('：') > 0;
                let arr = propertyValue.split(/,|，|;/g);
                arr = arr.map(one => $.trim(one)).filter(one => !!one);
                if(!isObject) {
                    arr.map(one => {
                        ret[one] = one;
                    });

                    return ret;
                }
                else {
                    let ret = {};
                    arr.map(one => {
                        let objectArr = one.split(/:|：/g);
                        if(objectArr.length === 2) {
                            ret[$.trim(objectArr[0])] = $.trim(objectArr[1]);
                        }
                    })

                    return ret;
                }
            },

            filterVal(val) {
                //新增节点时，属性没填写完整，不需要触发事件
                let needInputEvent = true;
                if(val && !this.currentValue) {
                    needInputEvent = false;
                }

                if(!val || !this.currentValue) {
                    this.currentValue = null;
                    this.$emit('input', null);

                    return;
                }
                
                if(this.$refs.tree.multiple) {
                    needInputEvent = val.length <= this.currentValue.length;
                    this.currentValue = this.currentValue.filter(one => val.indexOf(one.id) !== -1);
                }
                else if(this.currentValue.id !== val) {
                    this.currentValue = null;
                }

                needInputEvent && this.$emit('input', this.currentValue);
            },

            input(val) {
                if(this.isUseProperties) {
                    this.filterVal(val);
                }
                else {
                    this.currentValue = val;
                    this.$emit('input', val);
                }
            },

            addSelectedHandler(id) {
                if(this.isUseProperties) {
                    this.showProps(id);
                }
                else if(!this.multiple) {
                    this.$refs.tree.hide();
                }
            },

            getObjFromString(propertyValue) {                                                                            
                if(typeof propertyValue === 'string') {
                    if(propertyValue.indexOf('$store') === 0) {
                        try {
                            let obj = eval('this.' + propertyValue);
                            return obj || {};
                        }
                        catch(err) {
                            ocDialog.tips('_select 组件的缓存数据错误', 2000);
                            return {};
                        }
                    }
                    else {
                        let ret = {};
                        if(propertyValue.indexOf('{') > -1) { //JSON字符串 ---
                            try {
                                ret = JSON.parse(propertyValue);
                                return ret;
                            }
                            catch(err) {
                                ocDialog.tips('_select 组件 ' + this.config.propertyKey + ' 数据错误', 2000);
                            }
                        }
                        
                        let isObject = propertyValue.indexOf(':') > 0 || propertyValue.indexOf('：') > 0;
                        let arr = propertyValue.split(/,|，/g);
                        arr = arr.map(one => $.trim(one)).filter(one => !!one);
                        if(!isObject) {
                            return arr;
                        }
                        else {
                            let ret = {};
                            arr.map(one => {
                                let objectArr = one.split(/:|：/g);
                                if(objectArr.length === 2) {
                                    ret[$.trim(objectArr[0])] = $.trim(objectArr[1]);
                                }
                            })

                            return ret;
                        }
                    }
                }

                return propertyValue;  
            }
        }
    }
</script>

