<template>
  <el-tree class="classify-list-side-tree" accordion ref="treeRef" :data="treeData" :style="style" node-key="_id"
    :expand-on-click-node="false" @node-click="onNodeClick">
    <template #default="{ node, data }">
      <div class="flex-grow flex items-center text-14px py-12px px-5px border-b whitespace-normal border-gray-200">
        <div class="w-16px flex-shrink-0 box-content"
          :style="{textWrap:'wrap', paddingLeft: (data.level || 0) *5 +'px'}">
          <template v-if="data.children && data.children.length">
            <el-icon v-if="node.expanded" class="text-14px text-gray-500">
              <CaretBottom />
            </el-icon>
            <el-icon v-else class="text-14px text-gray-500">
              <CaretRight />
            </el-icon>
          </template>
        </div>
        <div class="w-0 flex-grow  break-all text-14px leading-20px"
          :class="checkedCate && checkedCate._id === data._id ?'text-blue-500':''">
          {{ node.label }}
        </div>
        <div v-if="enableSelect" class="flex-shrink-0 w-30px ml-10px" @click.stop="toggle(data)">
          <el-checkbox value="Value 1" :model-value="data.value && Boolean(selectMap[data.value])" />
        </div>
      </div>
    </template>
  </el-tree>


</template>
<script setup>
import { computed, nextTick, ref, watch } from 'vue';
import { useVModel, watchDebounced } from "@vueuse/core";
import { getCateTreeData } from '@/utils/index'

const emits = defineEmits(['change', 'update:modelValue', 'cateChange']);
const props = defineProps({
  appendAll: {
    type: Boolean,
    default: false
  },
  checkedCate: {
    type: Object,
    default: () => ({})
  },
  enableSelect: { type: Boolean, default: false },
  data: {
    type: Array,
    default: () => []
  },
  link: { type: Boolean, default: false },
  modelValue: { type: Array, default: () => [] },
  mult: { type: Boolean, default: true }, // 是否多选
})

const treeRef = ref();
const treeExpandMap = ref({});
const treeData = ref([]);
const selections = useVModel(props, "modelValue", emits);
const selectMap = computed(() => {
  return selections.value.reduce((acc, id) => {
    acc[id] = true;
    return acc;
  }, {})
})

function toggle(data) {
  const selected = selectMap.value[data.value];
  if (props.mult) {
    const ids = [data.value];
    if (props.link && Array.isArray(data.childrenIds)) {
      ids.push(...data.childrenIds);
    }
    if (selected) {
      selections.value = selections.value.filter(i => !ids.includes(i))
      emits('cateChange', ids, 'cancel')
    } else {
      selections.value = [...selections.value, ...ids];
      emits('cateChange', ids, 'add')
    }
  } else {
    selections.value = selected ? [] : [data.value];
    emits('cateChange', selections.value, selected ? 'cancel' : 'add')
  }
}

async function onNodeClick(data, node, treenode, event) {
  if (data._id !== props.checkedCate._id) {
    emits('change', { label: data.label, _id: data._id, childrenIds: data.childrenIds })
  }
  const nodesMap = treeRef.value.store.nodesMap;
  if (!nodesMap[data._id]) return;
  if (data.children && data.children.length) {
    nodesMap[data._id].expanded = !nodesMap[data._id].expanded;
    treeExpandMap.value = Object.keys(nodesMap).reduce((acc, key) => {
      const node = nodesMap[key];
      if (node.expanded) {
        acc[key] = node.expanded;
      }
      return acc;
    }, {});
  } else {
    nodesMap[data._id].checked = !nodesMap[data._id].checked;
  }
}
watch(() => props.visible, n => {
  if (n) {
    selections.value = [...props.value];
  }
})

watchDebounced(() => props.data, async n => {
  treeExpandMap.value = {};
  const tree = getCateTreeData(n);
  treeData.value = props.appendAll ? [{ label: '全部', _id: 'ALL', childrenIds: props.data.map(i => i._id) }, ...tree] : tree
  if (treeData.value.length === 0) {
    emits('change', {})
    return
  }
  const currentNode = props.data.find(i => i._id === props.checkedCate._id && i._id) || treeData.value[0];
  emits('change', { label: currentNode.label, _id: currentNode._id, childrenIds: currentNode.childrenIds })
  await nextTick();
}, { immediate: true })

</script>
<style lang="scss" scoped>
:deep(.el-tree-node__expand-icon) {
  display: none;
}

:deep(.el-tree-node__content) {
  height: auto;
  padding-left: 0 !important;
}
</style>
