import { _decorator, Component, Node } from 'cc';
import { Singleton } from '../manager/Singleton';
const { ccclass, property } = _decorator;

/*
//注册事件
EventEmitter.instance.register(this, "PLAYER_DEAD", (reason: string) => {
    console.log("～～:", reason);
});
//派发事件
EventEmitter.instance.dispatch("PLAYER_DEAD", "被怪物击杀");
//注销事件
EventEmitter.instance.unregister(this, "PLAYER_DEAD");*/

/**事件数据接口*/
interface IEventData {
    func: Function;  // 回调函数
    target: any;     // 回调函数绑定的this对象
}

/**事件哈希表接口*/
interface IEventHash {
    [eventType: string]: IEventData[];  //事件类型到事件数据数组的映射
}

@ccclass('EventEmitter')
class EventEmitter extends Singleton {
    private eventHash: IEventHash = {};

    /**
     * 清空所有事件监听
     */
    public clearAll(): void {
        console.log("清空所有事件监听");
        this.eventHash = {};
    }

    /**
     * 注册事件监听
     * @param target 监听对象 (用于取消监听时识别)
     * @param type 事件类型
     * @param callback 回调函数
     */
    public register(target: any, type: string, callback: Function): void {
        if(!this.eventHash[type]) {
            this.eventHash[type] = [];
        }
        //检查是否已注册相同监听
        const exists = this.eventHash[type].some(
            event => event.func === callback && event.target === target
        );
        if(!exists) {
            this.eventHash[type].push({
                func: callback,
                target: target
            });
        }
    }

    /**
     * 注销事件监听
     * @param target 监听对象
     * @param type 事件类型
     */
    public unregister(target: any, type: string): void {
        const events = this.eventHash[type];
        if (events && events.length > 0) {
            for (let i = events.length - 1; i >= 0; i--) {
                if (events[i].target === target) {
                    events.splice(i, 1);
                }
            }
        }
    }

    /**
     * 派发事件
     * @param type 事件类型
     * @param data 事件数据 (可变参数)
     */
    public dispatch(type: string, ...data: any[]): void {
        const events = this.eventHash[type];
        if (events && events.length > 0) {
            // 使用slice创建副本，防止在回调中修改数组影响遍历
            events.slice().forEach(event => {
                try {
                    event.func.apply(event.target, data);
                } catch (error) {
                    console.error(`事件[${type}]处理错误:`, error);
                }
            });
        }
    }
}
//单例
export const eventEmitter = EventEmitter.ins();
