// --- src/event/event-manager.ts ---
import { IEventPayload, IWorkflowContext } from '../types/index.js';

/**
 * MARK: 事件管理器接口
 * @interface IEventManager
 * @description 事件管理器接口，用于触发和监听事件
 */
export interface IEventManager {
    /**
     * 触发一个事件
     * @param eventName - 事件名称
     * @param data - 事件关联的数据 (可选)
     * @param triggerContext - 触发事件的工作流上下文 (可选)
     */
    emit(eventName: string, data?: Record<string, any>, triggerContext?: IWorkflowContext): Promise<void>;

    /**
     * 绑定一个工作流到指定事件
     * 当事件被触发时，将启动绑定的工作流
     * @param eventName - 要监听的事件名称
     * @param workflowDefinitionId - 要启动的工作流定义 ID
     * @param options - 绑定选项 (例如，输入映射)
     */
    bindWorkflowToEvent(eventName: string, workflowDefinitionId: string, options?: any): void;

    /**
     * 添加一个通用的事件监听器
     * @param eventName - 事件名称
     * @param listener - 监听函数
     */
    on(eventName: string, listener: (payload: IEventPayload) => void): void;

     /**
     * 移除事件监听器
     */
     off(eventName: string, listener: (payload: IEventPayload) => void): void;
}

/**
 * MARK: 内存事件管理器实现
 * @class InMemoryEventManager
 * @implements IEventManager
 * @description 简单的内存事件管理器实现 (示例)
 */
export class InMemoryEventManager implements IEventManager {
    private listeners: Map<string, Array<(payload: IEventPayload) => void>> = new Map();
    private workflowBindings: Map<string, { workflowDefinitionId: string; options?: any }[]> = new Map();
    // 需要注入 WorkflowExecutor 或类似机制来启动工作流
    // constructor(private workflowLauncher: (definitionId: string, input: any) => Promise<void>) {}

    async emit(eventName: string, data?: Record<string, any>, triggerContext?: IWorkflowContext): Promise<void> {
        const payload: IEventPayload = {
            eventName,
            data,
            timestamp: new Date(),
            source: triggerContext?.workflowId, // 记录事件来源
        };
        console.log(`[EventManager] 触发事件: ${eventName}`, data);

        // 触发通用监听器
        const eventListeners = this.listeners.get(eventName) || [];
        eventListeners.forEach(listener => {
            try {
                listener(payload);
            } catch (error) {
                console.error(`[EventManager] 执行事件 "${eventName}" 的监听器时出错:`, error);
            }
        });

        // 触发绑定的工作流
        const bindings = this.workflowBindings.get(eventName) || [];
        for (const binding of bindings) {
            console.log(`[EventManager] 事件 "${eventName}" 触发工作流: ${binding.workflowDefinitionId}`);
            // TODO: 实现启动工作流的逻辑
            // await this.workflowLauncher(binding.workflowDefinitionId, payload.data); // 将事件数据作为输入
             // 注意：需要处理输入映射、上下文传递等
        }
    }

    bindWorkflowToEvent(eventName: string, workflowDefinitionId: string, options?: any): void {
        if (!this.workflowBindings.has(eventName)) {
            this.workflowBindings.set(eventName, []);
        }
        this.workflowBindings.get(eventName)!.push({ workflowDefinitionId, options });
        console.log(`[EventManager] 工作流 "${workflowDefinitionId}" 已绑定到事件 "${eventName}"`);
    }

    on(eventName: string, listener: (payload: IEventPayload) => void): void {
        if (!this.listeners.has(eventName)) {
            this.listeners.set(eventName, []);
        }
        this.listeners.get(eventName)!.push(listener);
    }

    off(eventName: string, listener: (payload: IEventPayload) => void): void {
        const eventListeners = this.listeners.get(eventName);
        if (eventListeners) {
            const index = eventListeners.indexOf(listener);
            if (index > -1) {
                eventListeners.splice(index, 1);
            }
        }
    }
}