/**
 * 事件总线
 */

// 事件处理函数类型
type EventHandler = (data?: any) => void

// 事件映射
const eventMap = new Map<string, EventHandler[]>()

/**
 * 事件总线
 */
export const useEventBus = () => {
    /**
     * 监听事件
     */
    const on = (event: string, handler: EventHandler): void => {
        if (!eventMap.has(event)) {
            eventMap.set(event, [])
        }
        const handlers = eventMap.get(event)
        if (handlers != null) {
            handlers.push(handler)
        }
    }

    /**
     * 触发事件
     */
    const emit = (event: string, data?: any): void => {
        const handlers = eventMap.get(event)
        if (handlers != null) {
            handlers.forEach((handler) => {
                handler(data)
            })
        }
    }

    /**
     * 移除事件监听
     */
    const off = (event: string, handler?: EventHandler): void => {
        if (handler == null) {
            // 移除所有监听
            eventMap.delete(event)
        } else {
            // 移除指定监听
            const handlers = eventMap.get(event)
            if (handlers != null) {
                const index = handlers.indexOf(handler)
                if (index > -1) {
                    handlers.splice(index, 1)
                }
            }
        }
    }

    /**
     * 只监听一次
     */
    const once = (event: string, handler: EventHandler): void => {
        const onceHandler = (data?: any): void => {
            handler(data)
            off(event, onceHandler)
        }
        on(event, onceHandler)
    }

    return {
        on,
        emit,
        off,
        once
    }
}

