<!-- Created by henian.xu on 2017/4/18. -->
<template>
    <div
        :class="{
            'el-select':true,
            'tree-select':clean
        }"
        v-clickoutside="onClose"
    >
        <el-input
            ref="reference"
            type="text"
            v-model="selectedLabel"
            :placeholder="currentPlaceholder"
            :name="name"
            :size="size"
            :disabled="disabled"
            :readonly="!filter"
            :validate-event="false"
            :icon="iconClass"

            :on-icon-click="onIconClick"
            @focus="onFocus"
            @mousedown.native="onMouseDown"
            @keydown.native.tab="visible = false"
            @keydown.native.esc.prevent="visible = false"
        >
            <el-button
                v-if="clean"
                slot="append"
                icon="close"
                @click.native.prevent.stop="onClean"
            />
        </el-input>

        <transition
            name="el-zoom-in-top"
        >
            <el-select-menu
                ref="popper"
                v-show="visible"
            >
                <el-scrollbar
                    tag="ul"
                    wrap-class="el-select-dropdown__wrap"
                    view-class="el-select-dropdown__list"
                >
                    <el-tree
                        ref="tree"
                        node-key="id"
                        :data="treeData"
                        :load="loadNode"
                        :props="props"
                        :lazy="lazy"
                        :highlight-current="true"
                        :expand-on-click-node="false"

                        :filter-node-method="filterNode"
                        @node-click="onNodeClick"
                    />
                </el-scrollbar>
                <!--<p class="el-select-dropdown__empty" v-if="emptyText">{{ emptyText }}</p>-->
            </el-select-menu>
        </transition>
    </div>
</template>

<script>
import emitter from 'element-ui/src/mixins/emitter';
import Clickoutside from 'element-ui/src/utils/clickoutside';
import { addClass, removeClass } from 'element-ui/src/utils/dom';
import { addResizeListener } from 'element-ui/src/utils/resize-event';
import { t as i18nt } from 'element-ui/src/locale';
import ElSelectMenu from './select-dropdown.vue';
// import API from '@/api/api';
// import { HttpBase as API } from '@/api/base/HttpBase';

export default {
    name: 'ElTreeSelect',
    mixins: [emitter],
    data() {
        return {
            treeData: [],
            selectedLabel: this.value.label,
            noUpDataSelectedLabel: false,
            visible: false,
            inputWidth: 0,
            oldValue: {
                id: '',
                name: '',
            },
        };
    },
    computed: {
        iconClass() {
            const criteria = false;
            return criteria ? 'circle-close is-show-close' : 'caret-top';
        },
        emptyText() {
            return this.t('el.select.noData');
        },
    },
    props: {
        label: {
            type: String,
            default: '',
        },
        value: {
            type: Object,
            default() {
                return {
                    label: '',
                    value: [String, Number],
                };
            },
        },
        props: {
            type: Object,
            default() {
                return {
                    children: 'children',
                    label: 'label',
                    isLeaf: 'isLeaf',
                    icon: 'icon',
                };
            },
        },
        currentPlaceholder: {
            type: [String, Number],
            default() {
                return this.$$t('vmf_placeholder', '请选择');
            },
        },
        name: {
            type: String,
            default: '',
        },
        size: {
            type: String,
            default: '',
        },
        clean: {
            type: Boolean,
            default: false,
        },
        disabled: {
            type: Boolean,
            default: false,
        },
        filter: {
            type: Boolean,
            default: true,
        },
        lazy: {
            type: Boolean,
            default: false,
        },
        remoteUrl: {
            type: String,
            default: '',
        },
    },
    watch: {
        visible(val) {
            const icon = this.$el.querySelector('.el-input__icon');
            if (val) {
                if (icon) addClass(icon, 'is-reverse');
                this.onExpand();
            } else {
                if (icon) removeClass(icon, 'is-reverse');
                this.onCollapse();
            }
        },
        selectedLabel(val) {
            if (this.noUpDataSelectedLabel) {
                this.noUpDataSelectedLabel = false;
                return;
            }
            if (this.lazy) {
                this.resetTree({ name: val });
            } else {
                this.$refs.tree.filter(val);
                this.collapseAll();
            }
        },
        value(val) {
            this.selectedLabel = val.label;
            // 如果要双向绑定在这里赋值
        },
    },
    methods: {
        // 清空
        onClean() {
            // 要清空旧数据以避免收缩时 回填旧数据
            this.oldValue = {
                label: '',
                value: '',
            };
            this.$emit('input', this.oldValue);
            this.dispatch('ElFormItem', 'el.form.change', [this.oldValue]);
        },
        onExpand() {
            if (this.lazy) {
                this.resetTree({ name: this.selectedLabel });
            } else {
                this.$refs.tree.filter(this.selectedLabel);
                this.collapseAll();
            }
            this.oldValue = this.value;
        },
        onCollapse() {
            if (!this.isNodeCollapse) {
                this.selectedLabel = this.oldValue.label;
            }
            this.isNodeCollapse = false;
        },
        onFocus() {
            this.visible = true;
        },
        onClose() {
            this.visible = false;
        },
        onMouseDown(event) {
            if (event.target.tagName === 'INPUT') {
                this.visible = true;
            }
        },
        onIconClick() {
            this.visible = !this.visible;
        },
        onNodeClick(data) {
            this.noUpDataSelectedLabel = true;
            this.isNodeCollapse = true;
            this.selectedLabel = data[this.props.label];
            console.log(data);
            const value = {
                label: data[this.props.label],
                value: data.id,
            };
            this.$emit('input', value);
            this.dispatch('ElFormItem', 'el.form.change', [value]);
            this.visible = false;
        },
        expandAll() {
            const rootNode = this.$refs.tree.store._getAllNodes();
            Object.values(rootNode).forEach(node => {
                node.expanded = true;
            });
        },
        collapseAll() {
            const rootNode = this.$refs.tree.store._getAllNodes();
            Object.values(rootNode).forEach(node => {
                node.expanded = false;
            });
        },
        handleResize() {
            this.inputWidth = this.$refs.reference.$el.getBoundingClientRect().width;
        },
        loadNode(node, resolve) {
            this.$http
                .get(this.remoteUrl, { pId: node.key, lv: node.level, name: this.selectedLabel })
                .then(res => resolve(res.data.data));
        },
        resetTree(option) {
            const rootNode = this.$refs.tree.root;
            this.$http.get(this.remoteUrl, option).then(res => {
                if (!res.data.data.length && !!rootNode.childNodes.length) {
                    const { data } = rootNode.childNodes[0];
                    rootNode.store.remove(data);
                    rootNode.childNodes.length = 0;
                    return;
                }
                rootNode.childNodes.length = 0;
                Object.values(res.data.data).forEach(val => rootNode.store.append(val));
            });
        },
        filterNode(value, data) {
            if (!value) return true;
            return data[this.props.label].indexOf(value) !== -1;
        },
    },
    created() {
        this.t = i18nt;
        if (!this.lazy) {
            this.$http.get(this.remoteUrl, {}).then(res => {
                this.treeData = res.data.data;
            });
        }
    },
    mounted() {
        addResizeListener(this.$el, this.handleResize);
    },
    components: {
        ElSelectMenu,
    },
    directives: {
        Clickoutside,
    },
};
</script>
