<template>
    <view class="hc-tree-node" :class="[nodeItem.level > 1 ? 'pl': '']">
        <view class="content-bar" :id="'tree-' + nodeItem.key" :class="currentNodeKey===nodeItem.key?'current-node-key':''" @click="nodeTap(nodeItem)">
            <view class="expand-icon" @click.stop="expandTap(nodeItem)" :class="nodeItem.isExpand?'is-expanded':''">
                <text class="i-ri-arrow-right-s-fill" v-if="!nodeItem.isLeaf"/>
            </view>
            <view class="tree-check" @click.stop="checkClick" v-if="isCheck">
                <text class="i-ri-checkbox-blank-line c1" v-if="nodeItem.isCheck === 0"/>
                <text class="i-ri-checkbox-fill c2" v-if="nodeItem.isCheck === 1"/>
                <text class="i-ri-checkbox-indeterminate-fill c3" v-if="nodeItem.isCheck === 2"/>
            </view>
            <view class="tree-radio" v-if="isRadio">
                <text class="i-ri-checkbox-blank-circle-line c1" v-if="!nodeItem.isRadio"/>
                <text class="i-ri-checkbox-circle-fill c2" v-else/>
            </view>
            <view class="i-ri-loader-line cuIconfont-spin" v-if="nodeItem.loading"/>
            <view class="label">{{nodeItem.label?.replace(/\r|\n/ig,"")}} {{ isCounts? `【${nodeItem.data?.submitCounts ?? 0}】` : '' }}</view>
        </view>
        <template v-if="nodeItem.isExpand">
            <view class="children-bar" v-if="nodeItem.childNodes && nodeItem.childNodes.length > 0">
                <template v-for="items in nodeItem.childNodes">
                    <hc-tree-node :item="items"
                                  :check="isCheck"
                                  :strictly="isStrictly"
                                  :radio="isRadio"
                                  :currentKey="currentNodeKey"
                                  :counts="isCounts"
                                  @nodeLoad="getLazyLoad"
                                  @nodeTap="nodeTaps"
                    />
                </template>
            </view>
        </template>
    </view>
</template>

<script setup>
import {ref, watch} from "vue";
import {getArrValue} from "js-fast-way";

//参数
const props = defineProps({
    item: {
        type: Object,
        default: () => ({}),
    },
    check: {
        type: Boolean,
        default: false,
    },
    radio: {
        type: Boolean,
        default: false,
    },
    strictly: {
        type: Boolean,
        default: false,
    },
    currentKey: {
        type: String,
        default: '',
    },
    counts: {
        type: Boolean,
        default: false,
    },
})

//事件
const emit = defineEmits(['nodeLoad', 'nodeTap'])

//变量
const nodeItem = ref(props.item)
//参数配置
const isCheck = ref(props.check)
const isRadio = ref(props.radio)
const isStrictly = ref(props.strictly)
const isCounts = ref(props.counts)
const currentNodeKey = ref(props.currentKey)

//监听
watch(() => [
    props.item
], ([item]) => {
    nodeItem.value = item
}, {deep: true})

//监听
watch(() => [
    props.currentKey
], ([val]) => {
    currentNodeKey.value = val
})

//节点被点击
const nodeTap = (item) => {
    expandTap(item)
    nodeTaps(item)
}

//展开和收缩节点
const expandTap = (item) => {
    const {isLoad, isExpand, childNodes} = item
    const children = getArrValue(childNodes)
    //加载状态
    if (!isLoad) {
        item.loading = true
    }
    //展开和折叠
    if (children.length > 0) {
        setBrotherExpand(item, item.parentNodes)
        item.isExpand = !isExpand
    }
    //触发事件
    emit('nodeLoad', item)
}

//设置兄弟节点展开状态
const setBrotherExpand = (item, nodes) => {
    const children = getArrValue(nodes.childNodes)
    for (let i = 0; i < children.length; i++) {
        if (children[i].key !== item.key) {
            nodes.childNodes[i].isExpand = false
        }
    }
}

//子节点被点击
const nodeTaps = (item) => {
    currentNodeKey.value = item.key
    emit('nodeTap', item)
}

//懒加载子节点数据
const getLazyLoad = (item) => {
    emit('nodeLoad', item)
}

//复选框被点击 0未选中 1选中 2半选
const checkClick = () => {
    const {isCheck} = nodeItem.value
    if (isStrictly.value) {
        //父子级节点不关联选择
        nodeItem.value.isCheck = isCheck !== 1 ? 1 : 0
    } else {
        // 先设置自己的状态，选中或不选中
        nodeItem.value.isCheck = isCheck !== 1 ? 1 : 0
        // 设置子节点状态
        setChildrenCheck(nodeItem.value.childNodes)
        // 设置父节点状态
        setParentCheck(nodeItem.value.parentNodes)
    }
}

//设置子节点复选框状态
const setChildrenCheck = (children) => {
    for (let i = 0; i < children.length; i++) {
        children[i].isCheck = nodeItem.value.isCheck
        if (children[i].childNodes.length > 0) {
            setChildrenCheck(children[i].childNodes)
        }
    }
}

//设置父节点复选框状态 0未选中 1选中 2半选
const setParentCheck = (nodes) => {
    if (nodes.level <= 0) return
    const children = getArrValue(nodes.childNodes)
    const { isCheck } = nodeItem.value
    const result = children.every((item)=> {
        return item.isCheck === isCheck
    })
    if (isCheck === 1) {
        nodes.isCheck = result ? 1 : 2
    } else {
        nodes.isCheck = result ? 0 : 2
    }
    // 递归设置父节点
    if (nodes.parentNodes) {
        setParentCheck(nodes.parentNodes)
    }
}
</script>
