<template>
    <div v-show="myConfig.visible">
        <Cascader
            ref="myControl"
            v-model="value"
            :data="cascaderData"
            :size="myConfig.size"
            :disabled="myConfig.readOnly"
            :clearable="myConfig.clearable"
            @on-change="_setFatherValue"
            :placeholder="myConfig.placeholder"
            @on-visible-change="onOpenChange"
            :render-format="format"
        ></Cascader>
    </div>
</template>
<script>
import Base from '@/components/base/controlbase.vue';
export default {
    name: 'cascaderbox',
    extends: Base,
    data() {
        return {
            myConfig: {
                data: [],
                valueField: 'code',
                textField: 'name',
                parentField: 'pcode',
                codeWithName: false,
                separate: '/',
                defaultValue: '',
                clearable: true,
                readOnly: false,
            },
            value: [],
        };
    },
    computed: {
        cascaderData() {
            return this.toCascaderData();
        },
    },
    methods: {
        fatherValueToValue(value) {
            let separate = this.myConfig.separate;
            if (this.config.separate !== undefined) {
                separate = this.config.separate;
            }
            if (value) {
                return value.split(separate);
            } else {
                if (this.myConfig.defaultValue) {
                    return this.myConfig.defaultValue.split(separate);
                } else {
                    return [];
                }
            }
        },
        valueToFatherValue() {
            let separate = this.myConfig.separate;
            if (this.config.separate !== undefined) {
                separate = this.config.separate;
            }
            let para = {};
            if (this.value.length > 0) {
                para.value = this.value.join(separate);
            } else {
                para.value = '';
            }
            para.name = this.config.name;
            return para;
        },
        toCascaderData() {
            let pos = {};
            let tree = [];
            let i = 0;
            let rootCode = '0';
            if (this.config.rootCode !== undefined) {
                rootCode = this.config.rootNode;
            }
            let data = this.$Method.copy(this.myConfig.data);
            let tempData = this.$Method.copy(data);
            if (data.length > 0) {
                if (!this.checkData(data)) {
                    return [];
                }
            }
            while (data.length !== 0) {
                // 解决找不到节点，而导致的死循环
                const index = tempData.findIndex(item => item[this.myConfig.valueField] === data[i][this.myConfig.parentField]);

                if (
                    data[i][this.myConfig.parentField] === rootCode ||
                    index < 0
                ) {
                    tree.push(this.setNode(data[i]));
                    pos[data[i][this.myConfig.valueField]] = [tree.length - 1];
                    data.splice(i, 1);
                    i--;
                } else {
                    let posArr = pos[data[i][this.myConfig.parentField]];
                    if (posArr) {
                        let obj = tree[posArr[0]];
                        for (var j = 1; j < posArr.length; j++) {
                            obj = obj.children[posArr[j]];
                        }
                        obj.children.push(this.setNode(data[i]));
                        pos[data[i][this.myConfig.valueField]] = posArr.concat([
                            obj.children.length - 1,
                        ]);
                        data.splice(i, 1);
                        i--;
                    }
                }
                i++;
                if (i > data.length - 1) {
                    i = 0;
                }
            }
            return tree;
        },
        setNode(temp) {
            let reTemp = this.$Method.copy(temp);

            if (this.myConfig.codeWithName) {
                reTemp.label =
                    '[' +
                    reTemp[this.myConfig.valueField] +
                    ']  ' +
                    reTemp[this.myConfig.textField];
            } else {
                reTemp.label = reTemp[this.myConfig.textField];
            }
            reTemp.value = reTemp[this.myConfig.valueField];

            if (reTemp.children === undefined) {
                reTemp.children = [];
            } else {
                let children = [];
                reTemp.children.forEach(el => {
                    children.push(Object.assign({}, el, this.setSelected(el)));
                });
                reTemp.children = children;
            }
            return reTemp;
        },
        checkData(data) {
            let index = data.findIndex(el => el[this.myConfig.valueField] === el[this.myConfig.parentField]);
            if (index > -1) {
                return false;
            }
            return true;
        },
        isOptionShow(temp) {
            if (this.myConfig.readOnly) {
                return true;
            } else {
                return temp.visible;
            }
        },
        onOpenChange(value) {
            if (this.config.onOpenChange) {
                this.config.onOpenChange(value);
            }
        },
        format(labels) {
            let separate = this.myConfig.separate;
            if (this.config.separate !== undefined) {
                separate = this.config.separate;
            }
            return labels.join(separate);
        },
        setFocus(value) {
            if (value) {
                this.$refs.myControl.$refs.input.focus();
                //this.$refs.myControl.$refs.input.autofocus = true;
            } else {
                this.$refs.myControl.$refs.input.blur();
                //this.$refs.myControl.$refs.input.autofocus = false;
            }
        }
    },
};
</script>
