<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]" />
        </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 v-slot="slotData">
              <slot v-bind="slotData" />
            </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]" />
        </div>
        <div class="ui-tree-item-child" v-if="stroke"></div>
      </li>
    </template>
  </ul>
</template>

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

const props = defineProps({
  data: {
    type: Array,
    require: true,
  },
  locals: {
    type: Array,
    default: () => []
  },
  level: {
    type: Number,
    default: 1
  },
  'max-tab': { 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>