<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
                class="ui-tree-item"
                :class="{
                    alone: data.length === 1,
                    put: animationsRef[index].value && !animationsRef[index].value.show,
                }"
                v-if="item.children && item.children.length"
            >
                <div class="ui-tree-content">
                    <span :class="{ first: !index }" class="ui-tree-auxiliary" v-if="stroke && index !== item.children.lengt - 1"> </span>
                    <span class="ui-tree-ctrl" :class="{ open: animationsRef[index]?.value?.show }" @click="animationsRef[index].value.changeShow()"> </span>
                    <slot :row="item" :locals="[...locals, index]"></slot>
                </div>
                <UISizeAnimation animationStyle="scale" :ref="animationsRef[index]" 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"></slot>
                        </template>
                    </ui-tree>
                </UISizeAnimation>
            </li>
            <li class="ui-tree-item un-children" v-else>
                <div class="ui-tree-content">
                    <slot :row="item" :locals="[...locals, index]"></slot>
                </div>
                <div class="ui-tree-item-child" v-if="stroke"></div>
            </li>
        </template>
    </ul>
</template>

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

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 (let ranimationRef of animationsRef.value) {
        ranimationRef && ranimationRef.value?.changeShow(isOpen)
    }
}

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

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