import baseUtil from '../../../utils/base';
import EventManager from '../../../manager/eventManager';
import { silenceLogger } from '../../../common/logger';

const foo = function () { };
/**
 * 管理注册到window 的事件及其触发器
 */
class Emiter {
  constructor() {
    this.eventer = new EventManager();
  }

  /**
   * 事件绑定
   * @param {string} cbName 
   * @param {function} cb 
   * @param {string} tp 绑定事件类型，一般为 moduleName 模块名
   * @param {boolean} needParse 是否需要转换返回数据
   * @param {boolean} once 是否触发即销毁
   */
  on(cbName, cb, tp, needParse, once) {
    if (!cbName || !cb) return;
    once ? this.eventer.once(cbName, cb, tp) : this.eventer.on(cbName, cb, tp);
    this._initEmiter(cbName, needParse, once);
  }

  /**
   * 事件解绑
   * @param {string} cbName 仅当tp有值时可选
   * @param {function} cb 可选
   * @param {string} tp 可选
   */
  off(cbName, cb, tp) {
    // 先尝试清除触发器，否则拿不到 this.eventer.tpMap
    if (window && !cb) { // 没传cb 才会尝试销毁触发器
      if (cbName) { // 传了cbName 则清除对应事件触发，防止内存泄漏
        this._clearEmiter(cbName);
      } else if (tp) { // 仅传tp 则清除该类型的所有事件触发，防止内存泄漏
        this.eventer.getNamesByTp().forEach(name => this._clearEmiter(name));
      }
    }
    this.eventer.off(cbName, cb, tp);
  }

  /**
   * 初始化事件触发器
   * @param {string} cbName 
   * @param {boolean} needParse 是否
   */
  _initEmiter(cbName, needParse, once) {
    if (!cbName || !window || (window[cbName] && window[cbName] !== foo)) return;
    window[cbName] = data => {
      silenceLogger.debug('triger msg', cbName, needParse, data);
      const params = needParse ? baseUtil.toObject(data, data) : data;
      this.eventer.emit(cbName, params);
      if (once) {
        this._clearEmiter(cbName)
      }
    };
  }

  /**
   * 销毁事件触发器
   * @param {string} cbName 
   */
  _clearEmiter(cbName) {
    try {
      if (cbName && window[cbName]) {
        delete window[cbName]
      }
    } catch (err) {
      // 
    }
  }
}

export default new Emiter();
