import { Basic, BasicOpt } from "../common/basic";

/**
 * 回调缓存管理
 */
export class Callbacks extends Basic {
  temp: {
    [index: string]: { [index: string]: any };
  };
  EventCBTag = "HYExeCallback_";
  _defEventType = "GlobalEvent"; // 默认事件类型

  constructor(logger: BasicOpt) {
    super(logger);
    this.temp = {};
  }

  /**
   * 判断参数是否是回调标记 `HYExeCallback_xxx`
   */
  isCbId(param: any) {
    return typeof param === "string" && param.startsWith(this.EventCBTag);
  }

  /**
   * 添加回调Id缓存
   * @param type 事件分类，可根据分类批量移除事件
   * @param cbId 事件ID
   * @param val
   */
  add(type: string = this._defEventType, cbId: string, val: any) {
    if (!this.temp[type]) {
      this.temp[type] = {};
    }
    this.temp[type][cbId] = val;
  }

  /**
   * 移除回调ID缓存，匹配后返回缓存的值
   * @param type 要移除的事件 type，可选，没有时遍历查找 cbId
   * @param cbId 要移除的 cbId，可选，没有时判断 type
   * @returns cb
   */
  remove(type?: string, cbId?: string) {
    try {
      // 没 cbId
      if (!cbId) {
        // 没 cbId 没 type 不移除
        if (!type) return;

        // 没 cbId 有 type 移除 type 所有
        this.logger.log(`remove by type ${type}`);
        delete this.temp[type];
        return;
      }

      // 有 cbId 有 type
      if (type) {
        // 找到并移除指定 cbId
        if (this.temp[type] && this.temp[type][cbId]) {
          this.logger.log(`remove cbId ${cbId}`);
          const cb = this.temp[type][cbId];
          delete this.temp[type][cbId];
          return cb;
        }
        // 有 cbId 但未找到不移除
        return;
      }

      // 有 cbId 没 type 遍历找 cbId
      let matchCB = undefined;
      Object.keys(this.temp).findIndex((tp) => {
        if (this.temp[tp] && this.temp[tp][cbId]) {
          this.logger.log(`remove cbId ${cbId} with tp ${tp}`);
          matchCB = this.temp[tp][cbId];
          delete this.temp[tp][cbId];
          return true;
        }
      });
      return matchCB;
    } catch (err) {
      this.logger.error("remove cb fail", err);
      return;
    }
  }

  /**
   * 清除所有缓存
   */
  clean() {
    this.temp = {};
  }
}
