<template>
    <!-- 可拖拽模式：子节点允许拖拽排序 -->
    <draggable
        v-if="!pluginManager.getComponentConfingByType(props.parentSchema?.type || '')?.childImmovable"
        v-model="modelSchemas"
        item-key="id"
        :component-data="{}"
        class="epic-draggable-range"
        v-bind="{
            animation: 200,
            tag: 'ul',
            group: 'tree-draggable',
            ghostClass: 'moveing',
            draggable: '.draggable-item',
            disabled: !treeProps.draggable || modelSchemas[0]?.type === 'page'
        }"
        @start="handleSelect($event.oldIndex)"
    >
        <template #item="{ element }">
            <!-- 绑定子组件的update:children事件，接收子节点更新 -->
            <ETreeNodeItem
                :class="isDraggable(element)"
                :key="element.id"
                :schema="element"
                @update:children="newChildren => handleChildrenUpdate(element.id, newChildren)"
            />
        </template>
    </draggable>

    <!-- 不可拖拽模式：仅静态渲染节点 -->
    <ul v-else class="epic-static-list">
        <ETreeNodeItem
            v-for="element in modelSchemas"
            :key="element.id"
            :schema="element"
            :class="isDraggable(element)"
            @update:children="newChildren => handleChildrenUpdate(element.id, newChildren)"
        />
    </ul>
</template>
<script lang="ts" setup>
import { computed, inject } from "vue";
import { ComponentSchema, Designer } from "../../../types/epic-designer";
import ETreeNodeItem from "./treeNodeItem.vue";
import draggable from "vuedraggable";
import { pluginManager } from "@/components/EpicDesigner/utils";

defineOptions({ name: "ETreeNodes" });

// 注入上层依赖（设计器实例、树配置）
const designer = inject("designer") as Designer;
const treeProps = inject("treeProps") as any;

// 父组件接收的props（从上层组件传递的节点列表）
const props = defineProps<{
    schemas: ComponentSchema[]; // 子节点列表
    parentSchema?: ComponentSchema; // 父节点配置（用于判断是否允许子节点拖拽）
}>();

// 父组件对外暴露的事件（向上层传递节点更新）
const emit = defineEmits(["update:schemas"]);

// 核心：响应式数据代理，避免直接修改props
const modelSchemas = computed({
    get() {
        return props.schemas || []; // 空值兜底，避免undefined
    },
    set(newSchemas) {
        emit("update:schemas", newSchemas); // 向上层同步更新
    }
});

// 拖拽开始时选中节点（设计器联动逻辑）
function handleSelect(index: number) {
    if (index >= 0 && index < modelSchemas.value.length) {
        designer.setDisableHover(true);
        designer.setCheckedNode(modelSchemas.value[index]);
    }
}

// 关键：处理子组件传递的“子节点更新”，同步到父组件响应式数据
function handleChildrenUpdate(targetId: any, newChildren: any[]) {
    // 1. 找到要更新的节点索引
    const targetIndex = modelSchemas.value.findIndex(item => item.id === targetId);
    if (targetIndex === -1) return;

    // 2. 复制数组+节点对象（避免直接修改响应式引用，确保Vue触发更新）
    const updatedSchemas = [...modelSchemas.value];
    updatedSchemas[targetIndex] = {
        ...updatedSchemas[targetIndex], // 保留原节点其他属性
        children: newChildren // 替换为子组件传递的新子节点
    };

    // 3. 触发响应式更新
    modelSchemas.value = updatedSchemas;
}

// 判断节点是否允许拖拽（禁止页面节点、配置为不可拖拽的节点）
function isDraggable(schema: ComponentSchema) {
    const componentConfig = pluginManager.getComponentConfingByType(schema.type);
    return schema.type === "page" || (componentConfig && componentConfig.immovable)
        ? "unmover-item" // 禁止拖拽的类
        : "draggable-item"; // 允许拖拽的类
}
</script>

<style scoped>
.epic-draggable-range,
.epic-static-list {
    padding: 0;
    margin: 0;
    list-style: none;
}
.draggable-item {
    cursor: move;
}
.unmover-item {
    cursor: default;
    opacity: 0.9;
}
.moveing {
    background-color: #f0f7ff;
    border: 1px dashed #1890ff;
}
</style>
