<template>
    <Collapse v-model="activeNames" v-model:activeKey="activeNames" v-model:expanded-names="activeNames">
        <CollapseItem
            v-for="item in filterEventList"
            :key="item.title"
            :title="item.title"
            :header="item.title"
            :name="item.title"
        >
            <EActionEditorItem
                v-model="modelValueComputed"
                :item-events="item.events"
                :all-events="allEvents"
                :events="events"
                @add="handleOpen"
                @edit="handleOpenEdit"
            />
        </CollapseItem>
    </Collapse>
    <EActionModal ref="EActionModalRef" @add="handleAdd" @edit="handleEdit" />
</template>

<script lang="ts" setup>
import { PropType, computed, ref, toRaw, watch } from "vue";
import EActionEditorItem from "./src/EActionEditorItem.vue";
import { pluginManager } from "@/components/EpicDesigner/utils";
import EActionModal from "./src/EActionModal.vue";
const Collapse = pluginManager.getComponent("Collapse");
const CollapseItem = pluginManager.getComponent("CollapseItem");

const EActionModalRef = ref<any>(null);
let editIndex = 0;
const props = defineProps({
    eventList: {
        type: Array as PropType<any>,
        default: () => []
    },
    modelValue: {
        type: Object as PropType<any>
    }
});

const emit = defineEmits(["update:modelValue"]);
const modelValueComputed = computed({
    get() {
        return props.modelValue;
    },
    set(value) {
        emit("update:modelValue", value);
    }
});
const activeNames = ref<string[]>([]);

// 过滤无事件
const filterEventList = computed(() => {
    return props.eventList.filter((item: { events: string | any[] }) => item.events.length);
});

const allEvents = computed(() => {
    return props.eventList.map((item: { events: any }) => item.events).flat();
});

const events = ref<any>({});

allEvents.value.forEach((item: any) => {
    events.value[item.type] = computed({
        get() {
            return modelValueComputed.value?.[item.type] ?? [];
        },
        set(e) {
            if (e && e.length) {
                modelValueComputed.value[item.type] = e.map((item: any) => toRaw(item));
            } else {
                // 事件动作为空时，则清除该事件列表
                delete modelValueComputed.value[item.type];
            }
        }
    });
});

// 监视 filterEventList.value 的变化
watch(
    () => filterEventList.value,
    (e: any) => {
        // 当 filterEventList.value 变化时执行回调函数
        if (e.length) {
            // 如果 filterEventList.value 不为空数组
            // 过滤出满足条件的事件，并将它们的标题存储在 activeNames.value 中
            activeNames.value = e
                .filter((item: any) => {
                    // 对于每个事件项，检查其包含的事件类型
                    for (let i = 0; i < item.events.length; i++) {
                        const type = item.events[i].type;
                        // 如果 events.value[type] 不为空数组，则返回 true
                        if (events.value[type].length) {
                            return true;
                        }
                    }
                    // 如果事件项中没有任何一个事件类型满足条件，则返回 false
                    return false;
                })
                .map((item: any) => item.title); // 将满足条件的事件项的标题映射成一个新的数组
        }
    },
    {
        // 配置选项
        immediate: true // 立即执行一次回调函数
    }
);

let currentType: string = "";
/**
 * 打开动作配置窗口
 * @param type
 */
function handleOpen(type: string) {
    EActionModalRef.value?.handleOpen();
    currentType = type;
}

/**
 * 打开动作配置窗口-编辑
 * @param {number} index - 要编辑事件的索引
 * @param {string} type - 事件类型
 * @param {any} action - 要执行的动作
 */
function handleOpenEdit(index: number, type: string, action: any) {
    // 如果 EActionModalRef.value 不为 null 或 undefined，则调用其 handleOpenEdit 方法
    EActionModalRef.value?.handleOpenEdit(action);

    // 将要编辑的事件的索引赋值给 editIndex
    editIndex = index;

    // 将事件的类型赋值给 currentType
    currentType = type;
}

/**
 * 编辑事件的函数
 * @param {any} action - 动作数据
 */
function handleEdit(action: any) {
    // 将编辑后的动作替换掉 events.value[currentType][editIndex]
    events.value[currentType][editIndex] = action;

    // 更新 modelValueComputed.value[currentType]，使用新的数组代替原始数组
    modelValueComputed.value[currentType] = [...(events.value[currentType] ?? [])];
}

/**
 * 添加组件事件
 * @param {any} action - 要执行的动作
 */
function handleAdd(action: any) {
    // 如果 modelValueComputed.value 为 null 或 undefined，则创建一个新的对象
    if (!modelValueComputed.value) {
        modelValueComputed.value = { [currentType]: [...(events.value[currentType] ?? []), action] };
        return;
    }

    // 否则，直接在 modelValueComputed.value[currentType] 中添加新的动作
    modelValueComputed.value[currentType] = [...(events.value[currentType] ?? []), action];
}
</script>
