<!--
 - @Author XXX
 - @Link XXX
-->
<template>
    <div class="flex flex-col w-full h-full">
        <a-input-group class="mb-2 w-full" size="mini">
            <a-input :placeholder="props?.searchPlaceholder" allow-clear @input="changeKeyword" @clear="resetData" />
            <a-button
                @click="
                    () => {
                        isExpand ? maTree.expandAll(false) : maTree.expandAll(true)
                        isExpand = !isExpand
                    }
                "
                >{{ isExpand ? "折叠" : "展开" }}</a-button
            >
        </a-input-group>
        <a-tree
            blockNode
            ref="maTree"
            :data="treeData"
            class="h-full w-full"
            @select="handlerSelect"
            :field-names="props.fieldNames"
            v-model:selected-keys="modelValue"
            v-bind="$attrs"
        >
            <template #icon v-if="props.icon"><component :is="props.icon" /></template>
        </a-tree>
    </div>
</template>

<script setup>
import { ref, watch, computed } from "vue"

const treeData = ref([])
const maTree = ref()
const isExpand = ref(false)

const emit = defineEmits(["update:modelValue", "click"])

const props = defineProps({
    modelValue: { type: Array },
    data: { type: Array },
    searchPlaceholder: { type: String },
    fieldNames: {
        type: Object,
        default: () => {
            return { title: "label", key: "value" }
        }
    },
    icon: { type: String, default: undefined }
})

const modelValue = computed({
    get() {
        return props.modelValue
    },
    set(newVal) {
        emit("update:modelValue", newVal)
    }
})

watch(
    () => props.data,
    (val) => {
        treeData.value = val
    },
    { immediate: true, deep: true }
)

const handlerSelect = (item, data) => {
    modelValue.value = [item]
    emit("click", ...[item, data])
}

const resetData = () => (treeData.value = props.data)

const changeKeyword = (keyword) => {
    if (!keyword || keyword === "") {
        treeData.value = Object.assign(props.data, [])
        return false
    }
    treeData.value = searchNode(keyword)
}

const searchNode = (keyword) => {
    const loop = (data) => {
        let tree = []
        data.map((item) => {
            if (item.children && item.children.length > 0) {
                const temp = loop(item.children)
                tree.push(...temp)
            } else if (item[props.fieldNames["title"]].indexOf(keyword) !== -1) {
                tree.push(item)
            }
            return tree
        })

        return tree
    }
    return loop(treeData.value)
}

defineExpose({ maTree })
</script>

<style scoped lang="less">
:deep(.arco-tree-node:hover) {
    background-color: var(--color-fill-2);
    border-radius: 3px;
}
:deep(.arco-tree-node-switcher) {
    margin-left: 2px;
}
</style>
