import { v4 } from 'uuid'

/**
 * 事件消息
 */
interface EventMessage {
    keys: (keyof typeof EventKey)[];
    callback: (data: unknown) => void;
}

/** 事件key */
enum EventKey {
    loadComplete, //加载状态名
    spotTrade,  // 挂牌成功，通知报价大厅更新数据
    blocsTrade, // 贸易圈 挂牌成功
    financing_manager, // 融资摘牌
    changeTheme, // 切换主题
    logout, //登出名:确认登出时不能进行其它操作了 暂时1s登出状态
    loginSuccess, // 登录成功
    loadAddressList, //加载地址列表
    loadMylieList, //加载闲置列表
    marketStatusChangeNtf, // 市场状态变更通知
    custOfflineNtf, //接收到账户离线通知
    userLogout, //接收到用户登出应答
    posChangedNtf, //接收到头寸变化通知
    moneyChangedNtf, //接收到资金变化通知
    taAccountChangedNtf, //接收到资金账户通知
    bargain, // 议价单
    orderCanceledNtf, //接收到委托单撤单通知
    orderDealedNtf, //接收到委托单成交通知
    quoteReceiveNtf, // 接收实时行情推送
    wrTradeDealedNtf, // 接收到仓单贸易成交通知
}

/**
 * 事件总线
 */
export default new (class {
    private eventMap = new Map<string, EventMessage>();

    /** 监听(订阅)事件 */
    $on(eventKey: keyof typeof EventKey | (keyof typeof EventKey)[], callback: EventMessage['callback']) {
        const uuid = v4();
        const keys = Array.isArray(eventKey) ? eventKey : [eventKey];

        this.eventMap.set(uuid, {
            keys,
            callback
        })

        /** 销毁事件，注意离开页面时要手动销毁当前页面的监听事件，防止事件重复触发 */
        return () => {
            this.eventMap.delete(uuid);
        }
    }

    /** 触发(发布)事件 */
    $emit(eventKey: keyof typeof EventKey, data?: unknown) {
        for (const message of this.eventMap.values()) {
            if (message.keys.includes(eventKey)) {
                message.callback(data);
            }
        }
    }

    /** 取消事件 */
    $off(...eventkeys: (keyof typeof EventKey)[]) {
        if (eventkeys.length) {
            for (const [uuid, message] of this.eventMap.entries()) {
                for (let i = message.keys.length - 1; i >= 0; i--) {
                    if (eventkeys.includes(message.keys[i])) {
                        message.keys.splice(i, 1);
                    }
                }
                if (!message.keys.length) {
                    this.eventMap.delete(uuid);
                }
            }
        } else {
            this.eventMap.clear();
        }
    }
})