<template>
    <ul class="ui-tree" :style="style" :class="{ children: level > 1, stroke, flat: level > maxTab }">
        <template v-for="(item, index) in data" :key="item.id || index">
            <li
                v-if="item.children && item.children.length"
                class="ui-tree-item"
                :class="{
                    alone: data.length === 1,
                    put: animationsRef[index].value && !animationsRef[index].value.show,
                }"
            >
                <div class="ui-tree-content">
                    <span v-if="stroke && index !== item.children.lengt - 1" :class="{ first: !index }" class="ui-tree-auxiliary" />
                    <span class="ui-tree-ctrl" :class="{ open: animationsRef[index]?.value?.show }" @click="animationsRef[index].value.changeShow()" />
                    <slot :row="item" :locals="[...locals, index]" />
                </div>
                <UISizeAnimation :ref="animationsRef[index]" animation-style="scale" class="ui-tree-item-child">
                    <ui-tree :style="style" :stroke="stroke" :data="item.children" :max-tab="maxTab" :level="level + 1" :open="open" :locals="[...locals, index]">
                        <template #default="slotData">
                            <slot v-bind="slotData" />
                        </template>
                    </ui-tree>
                </UISizeAnimation>
            </li>
            <li v-else class="ui-tree-item un-children">
                <div class="ui-tree-content">
                    <slot :row="item" :locals="[...locals, index]" />
                </div>
                <div v-if="stroke" class="ui-tree-item-child" />
            </li>
        </template>
    </ul>
</template>

<script lang="ts" setup>
// computed
import { defineExpose, defineProps, ref, watchEffect } from 'vue'
import UISizeAnimation from '../size-animation'
// export default { name: 'UiTree' }

defineOptions({
    name: 'UITree',
})

const props = defineProps({
    data: {
        type: Array,
        require: true,
    },
    locals: {
        type: Array,
        default: () => [],
    },
    level: {
        type: Number,
        default: 1,
    },
    maxTab: { type: Number },
    open: { type: Boolean },
    stroke: { type: Boolean },
    style: { type: [Object, String] },
})

const animationsRef = ref(props.data.map(item => ref(null)))
const changeShowAll = isOpen => {
    for (const ranimationRef of animationsRef.value) {
        ranimationRef && ranimationRef.value?.changeShow(isOpen)
    }
}

watchEffect(() => changeShowAll(props.open))

defineExpose({
    openAll: () => changeShowAll(true),
    closeAll: () => changeShowAll(false),
})
</script>
