import { MessageType } from '@/Frameworks/MessageType';

export type EventHandler<E = any> = (e: E) => void;
// export interface EventType {
//   [type: MessageType]: EventHandler<E>[];
// }
class EventAction<E = any> {
  private _events: { [type in MessageType]?: EventHandler<E>[] }; //Record<MessageType, EventHandler<E>[]>;
  constructor() {
    this._events = {};
  }

  private _getFns(type: MessageType) {
    return this._events[type] || (this._events[type] = []);
  }

  public on(type: MessageType, cb: EventHandler<E>): void {
    const fus = this._getFns(type);
    fus.push(cb);
  }

  public off(type: MessageType, cb?: EventHandler<E>): void {
    if (cb) {
      const fus = this._getFns(type);
      const index = fus.indexOf(cb);
      if (index != -1) {
        fus.splice(index, 1);
      }
    } else {
      delete this._events[type];
    }
  }

  public once(type: MessageType, cb: EventHandler<E>): void {
    const fn2: EventHandler<E> = (e) => {
      this.off(type, fn2);
      cb(e as any);
    };
    this.on(type, fn2);
  }

  //同步调用
  public emit(type: MessageType, params?: E): void {
    const fns = this._getFns(type);
    fns.forEach((item) => item(params as any));
  }
  /* 可以异步调用，返回一个Promise */
  public invoke(event: MessageType, param?: E): Promise<any> {
    const fns = this._getFns(event);

    for (let i = 0; i < fns.length; i++) {
      const fn = fns[i];
      return new Promise<any>((resolve, reject) => {
        resolve(fn(param as any));
      });
    }
    return Promise.reject();
  }
}

export default EventAction;
