<template>
    <div class="vx-tree-item" :style="itemStyle">
        <div @click.stop.prevent="selectItem" class="vx-tree-item__content">
            <span v-if="isLeaf" class="switch" :class="switchClass" />
            <span
                v-else
                @click.stop.prevent="toggle"
                class="switch"
                :class="switchClass"
            />
            <!-- <img
                :src="imgCheckSrc"
                @click.stop.prevent="check"
                class="image"
                v-if="showCheckbox"
            /> -->
            <i v-if="isLeaf" :class="iconClass" class="icon"></i>
            <i
                v-else
                :class="iconClass"
                class="icon"
                @click.stop.prevent="toggle"
            ></i>
            <span
                :class="{ 'vx-tree-item--selected': model.isSelected }"
                class="title"
                :style="model.color ? 'flex: 1;color:#f00;' : 'flex:1;'"
                >{{ model.title }}</span
            >
            <component
                :is="innerComponentName"
                :model="model"
                v-if="innerComponentName"
            ></component>
        </div>
        <div
            class="vx-tree-item__children"
            :class="childrenClass"
            v-show="model.isOpen"
        >
            <vx-tree-item
                :acceptNodeFn="acceptNodeFn"
                :iconClassFn="iconClassFn"
                :innerComponentName="innerComponentName"
                :key="index"
                :index="index"
                :level="level + 1"
                :model="child"
                :showCheckbox="showCheckbox"
                :siblingCount="model.children.length"
                v-for="(child, index) in model.children"
            ></vx-tree-item>
        </div>
    </div>
</template>

<script>
import Emitter from './emitter'
export default {
    name: 'VxTreeItem',
    data() {
        return {}
    },
    mixins: [Emitter],
    props: {
        /**
         * 显示次序
         */
        index: {
            type: Number,
        },
        /**
         * 显示checkbox
         */
        showCheckbox: {
            type: Boolean,
            default: false,
        },
        /**
         * 数据模型
         */
        model: {
            type: Object,
        },
        /**
         * 兄弟节点数量
         */
        siblingCount: {
            type: Number,
        },
        /**
         * 可接受节点函数
         */
        acceptNodeFn: {
            type: Function,
        },
        /**
         * 水平
         */
        level: {
            type: Number,
            require: true,
        },
        /**
         * 内部组件名
         */
        innerComponentName: {
            type: String,
        },

        /**
         * 图片 Class类函数，返回类名
         */
        iconClassFn: {
            type: Function,
        },
    },
    computed: {
        itemStyle() {
            if (this.model.isVisible) {
                return {
                    display: 'block',
                }
            } else {
                return {
                    display: 'none',
                }
            }
        },
        /**
         * 如果是顶层节点
         */
        isRoot() {
            return this.level === 0
        },
        /**
         * 只有一个Root节点
         */
        isOneRoot() {
            return this.level === 0 && this.siblingCount === 1
        },

        /**
         * 是否第一个
         */
        isFirst() {
            return this.index === 0
        },
        /**
         * 是否最后一个
         */
        isLast() {
            return this.index === this.siblingCount - 1
        },

        isLeaf() {
            return this.model.isLeaf
        },
        isOpen() {
            return this.model.isOpen
        },
        childrenClass() {
            if (!this.isLast) {
                return 'conn'
            }
        },
        switchClass() {
            if (this.isRoot) {
                if (this.isOneRoot) {
                    if (this.isLeaf) {
                        return 'root-docu'
                    }
                    if (this.isOpen) {
                        return 'root-open'
                    } else {
                        return 'root-close'
                    }
                } else {
                    if (this.isLeaf) {
                        if (this.isLast) {
                            return 'bottom-docu'
                        } else if (this.isFirst) {
                            return 'roots-docu'
                        } else {
                            return 'center-docu'
                        }
                    } else {
                        if (this.isLast) {
                            if (this.isOpen) {
                                return 'bottom-open'
                            } else {
                                return 'bottom-close'
                            }
                        } else if (this.isFirst) {
                            if (this.isOpen) {
                                return 'roots-open'
                            } else {
                                return 'roots-close'
                            }
                        } else {
                            if (this.isOpen) {
                                return 'center-open'
                            } else {
                                return 'center-close'
                            }
                        }
                    }
                }
            }

            if (this.isLast) {
                if (this.isLeaf) {
                    return 'bottom-docu'
                } else {
                    if (this.isOpen) {
                        return 'bottom-open'
                    } else {
                        return 'bottom-close'
                    }
                }
            } else {
                if (this.isLeaf) {
                    return 'center-docu'
                } else {
                    if (this.isOpen) {
                        return 'center-open'
                    } else {
                        return 'center-close'
                    }
                }
            }
        },

        iconClass() {
            if (this.iconClassFn) {
                return this.iconClassFn()
            }

            if (this.isLeaf) {
                return 'icon-leaf'
            }

            if (this.isOpen) {
                return 'icon-open'
            } else {
                return 'icon-close'
            }
        },

        imgCheckSrc() {
            if (this.model.checkStatus === 'F') {
                return this.checkedImg
            } else if (this.model.checkStatus === 'I') {
                return this.indeterminateImg
            } else {
                return this.uncheckedImg
            }
        },
        hasChildren() {
            return this.model.children && this.model.children.length > 0
        },
    },
    methods: {
        toggle() {
            console.log('点击');
            console.log(this.model);
            this.$set(this.model, 'isOpen', !this.model.isOpen)
        },
        check() {
            // F 选中， N 未选， I 部分选
            let status = this.model.checkStatus
            if (status === 'F') {
                status = 'N'
            } else {
                status = 'F'
            }

            this.$set(this.model, 'checkStatus', status)

            if (status === 'F') {
                this.setChildrenChecked(this.model)
            } else {
                this.setChildrenUnChecked(this.model)
            }

            this.setParentStatus(this.model)
        },
        selectItem() {
            if (this.acceptNodeFn && !this.acceptNodeFn(this.model)) {
                return
            }
            if (!this.model.isSelected) {
                this.dispatch('VxTree', 'evt-select-node', this.model)
            }
        },

        setChildrenChecked(model) {
            // 全部选中子节点
            if (model.children) {
                model.children.forEach((node) => {
                    this.$set(node, 'checkStatus', 'F')

                    this.setChildrenChecked(node)
                })
            }
        },
        setParentStatus(model) {
            // 父节点，FNI
            if (model.parentNode) {
                let parentNode = model.parentNode
                // 如果子节点全部选中，则选中
                // 如果子节点全部非选中，则非选中
                let children = parentNode.children
                let firstStatus = children[0].checkStatus
                if (firstStatus === 'I') {
                    this.$set(parentNode, 'checkStatus', 'I')
                } else if (firstStatus === 'F') {
                    for (let child of children) {
                        let isIndeterminate = false

                        if (child.checkStatus !== 'F') {
                            this.$set(parentNode, 'checkStatus', 'I')

                            isIndeterminate = true
                            break
                        }

                        if (!isIndeterminate) {
                            this.$set(parentNode, 'checkStatus', 'F')
                        }
                    }
                } else {
                    for (let child of children) {
                        let isIndeterminate = false

                        if (
                            child.checkStatus === 'F' ||
                            child.checkStatus === 'I'
                        ) {
                            this.$set(parentNode, 'checkStatus', 'I')

                            isIndeterminate = true
                            break
                        }

                        if (!isIndeterminate) {
                            this.$set(parentNode, 'checkStatus', 'N')
                        }
                    }
                }

                this.setParentStatus(parentNode)
            }
        },

        setChildrenUnChecked(model) {
            // 全部取消子节点
            if (model.children) {
                model.children.forEach((node) => {
                    this.$set(node, 'checkStatus', 'N')

                    this.setChildrenUnChecked(node)
                })
            }
        },
    },
}
</script>

<style lang="less">
.vx-tree-item {
    &__content {
        height: 18px;
        line-height: 18px;
        position: relative;
        display: flex;
        align-items: center;
        cursor: default;

        .switch {
            flex-shrink: 0;
            width: 18px;
            height: 18px;
            cursor: pointer;
            background-image: url('./assets/tree.png');
        }

        .root-open {
            background-position: -92px -54px;
        }

        .root-close {
            background-position: -74px -54px;
        }

        .roots-open {
            background-position: -92px 0px;
        }

        .roots-close {
            background-position: -74px 0px;
        }
        .root_docu {
            background: none;
        }
        .roots-docu {
            background-position: -56px 0;
        }
        .center-open {
            background-position: -92px -18px;
        }

        .center-close {
            background-position: -74px -18px;
        }

        .bottom-open {
            background-position: -92px -36px;
        }

        .bottom-close {
            background-position: -74px -36px;
        }

        .center-docu {
            background-position: -56px -18px;
        }

        .bottom-docu {
            background-position: -56px -36px;
        }

        .icon {
            flex-shrink: 0;
            width: 16px;
            height: 16px;
            cursor: pointer;
            background-image: url('./assets/tree.png');
        }

        .icon-open {
            margin-right: 2px;
            background-position: -110px -16px;
        }

        .icon-close {
            margin-right: 2px;
            background-position: -110px 0;
        }

        .icon-leaf {
            margin-right: 2px;
            background-position: -110px -32px;
        }

        &:hover {
            text-decoration: underline;
            color: #2d8cf0;
            text-decoration-color: #2d8cf0;
            cursor: pointer;
        }

        .title {
            flex-shrink: 0;
            display: inline-block;
            padding: 0 6px;
            user-select: none;
            flex: 1;
        }

        /* 扩展使用开始 */
        .icon-org-open {
            background-image: url('./assets/1_open.png');
        }
        .icon-org-close {
            background-image: url('./assets/1_close.png');
        }
        .icon-org-leaf {
            background-image: url('./assets/1_leaf.png');
        }
        /* 扩展使用结束 */
    }

    &__children {
        padding-left: 18px;
    }

    .conn {
        background: url(./assets/line_conn.gif) 0 0 repeat-y;
    }

    &--selected {
        font-weight: bold;
        color: #2d8cf0;
    }

    &--filtered {
        font-weight: bold;
        color: #2d8cf0;
    }
}
</style>
