<template>
    <el-tree
        ref="treeRef"
        :data="treeData.data"
        :default-expand-all="attrs.showAll === undefined ? true : attrs.showAll"
        :default-expanded-keys="attrs.expanded || []"
        accordion
        :check-strictly="attrs.checkStrictly"
        :highlight-current="true"
        :show-checkbox="attrs.showCheckbox === undefined ? true : attrs.showCheckbox"
        :node-key="attrs.nodeKey || 'id'"
        :expand-on-click-node="attrs.expandClickNode === undefined ? true : attrs.expandClickNode"
        :props="defaultProps"
        @check="getCheckChange"
        @node-click="handleNodeClick"
    >
        <template #default="{node}">
            <span
                v-if="!slots.column"
                :id="node.label"
                class="custom-tree-node"
            >
                <span>{{ defaultProps.i18n ? $t(node.label) : node.label }}</span>
            </span>
            <slot name="column"
            :node="node" />
        </template>
    </el-tree>
</template>
<script lang="ts" setup>
import { ref, watch, reactive, nextTick, useSlots } from 'vue'
import { ObjectInterface } from '../../script/util'

const props = defineProps({
    treeData: {
        type: Object,
        default: () => {
        }
    },
    defaultProps: {
        type: Object,
        default: () => {
            return {
                i18n: true,
                children: 'children',
                label: 'name'
            }
        }
    },
    attrs: {
        type: Object,
        default: () => {
            return {}
        }
    }
})
const emit = defineEmits(['selectData', 'nodeClick'])
const selectData = reactive({
    list: []
})
const slots = useSlots()
const treeRef = ref()
const getCheckChange = (nodeData) => {
    // 选中的数据 全选
    let checkedNodes: ObjectInterface[] = []
    for (let item of treeRef.value!.getCheckedNodes()) {
        item.halfSelect = true
        checkedNodes.push(item)
    }
    // 半选数据 halfSelect = false
    if (props.attrs.includeHalfChecked) {
        for (let item of treeRef.value!.getHalfCheckedNodes()) {
            item.halfSelect = false
            checkedNodes.push(item)
        }
    }
    const node = treeRef.value.getNode(nodeData)
    // 上边是原始数据
    emit('selectData', checkedNodes, nodeData, node)
}
const handleNodeClick = (data, node) => {
    emit('nodeClick', data, node)
}
const remove = (node) => {
    treeRef.value.remove(node)
}
const insert = (data, ref, insert = 'after') => {
    if (insert === 'before') {
        treeRef.value.insertBefore(data, ref)
    } else {
        treeRef.value.insertAfter(data, ref)
    }
}
// 设置父子不互相关联又想父级有半选状态时使用
const setParent = (node) => {
    if (node.parent && props.attrs.checkStrictly && props.attrs.customCheck) {
        const checkedNodes = treeRef.value!.getCheckedNodes() // 所有已选中节点
        const checkedChildren = node.parent.childNodes.filter(node2 => node2.checked || node2.indeterminate) // 当前组选中的子节点
        if (checkedNodes.length === 0 || checkedChildren.length === 0) {
            node.parent.indeterminate = false
        } else if (!node.parent.checked) {
            node.parent.indeterminate = true
        }
        setParent(node.parent)
    }
}

defineExpose({
    remove, insert, treeRef, setParent
})
watch(props.treeData, (newdata, od) => {
    nextTick(() => {
        if (newdata?.selectData.length) {
            selectData.list = newdata.selectData
            for (const id of selectData.list) {
                treeRef.value!.setChecked(id, true)
                const node = treeRef.value!.getNode(id)
                setParent(node)
                // let children = node?.data.children
                // if (!children || children.length === 0) {
                //     treeRef.value!.setChecked(id, true)
                //     continue
                // }
                // children = children.map((item: ObjectInterface) => item.id)
                // const total = newdata.selectData.reduce((total: ObjectInterface, curr: ObjectInterface) => {
                //     children.includes(curr) && total.push(curr)
                //     return total
                // }, [])
                // if (children.length === total.length) {
                //     treeRef.value!.setChecked(id, true)
                // }
            }
        }
    })
}, {
    immediate: true,
    deep: true
})
</script>
