import EventManager from '../../../manager/eventManager';
import topicListener from './topicListener';
import baseUtil from '../../../utils/base';
import errUtil from '../../../utils/error';
import { EVENT_NAME_NULL, EVENT_CALLBACK_INVALID, EVENT_UNSUPPORT } from '../../../common/consts';

export default class NativeEventer {
  constructor(opt) {
    this.eventer = new EventManager();
    const { topic, resReducer, supportEvents } = opt || {};
    this._sEvents = supportEvents

    const topics = baseUtil.isArray(topic) ? topic : [topic];
    topics.map(tpc => {
      topicListener.on(tpc, data => {
        const { event, content } = (baseUtil.isFun(resReducer) ? resReducer(data, tpc) : data) || {};
        if (event) {
          this.eventer.emit(event, content);
        }
      });
    });
  }

  on(topic, cb, tp) {
    if (baseUtil.isEmpty(topic)) throw errUtil.pkgErr(EVENT_NAME_NULL);
    if (!baseUtil.isFun(cb)) throw errUtil.pkgErr(EVENT_CALLBACK_INVALID);
    if (this._sEvents && this._sEvents.indexOf(topic) < 0) {
      throw errUtil.pkgErr(EVENT_UNSUPPORT, `${EVENT_UNSUPPORT.msg}: ${topic}`);
    }

    this.eventer.on(topic, cb, tp)
  }

  off(topic, cb, tp) {
    if (this.isClean(topic, tp)) return
    this.eventer.off(topic, cb, tp);
  }

  emit(topic, data) {
    return this.eventer.emit(topic, data);
  }

  /**
   * 事件是否清除干净
   * @param {string} topic 
   */
  isClean(topic, tp) {
    return this.eventer.isClean(topic, tp);
  }

  /**
   * 只触发一次的监听
   * @param {string} topic 事件名
   * @param {Function} cb 回调
   * @param {string} [tp] 类型
   * @returns 
   */
  once(topic, cb, tp) {
    const callback = (...params) => {
      try { cb && cb(...params) } catch (err) {
        //
      }
      this.off(topic, callback, tp)
    }

    return this.on(topic, callback, tp);
  }

  /**
   * 监听重置
   * @param {string} topic 事件名
   * @param {Function} cb 回调
   * @param {string} [tp] 类型
   * @returns 
   */
  reset(topic, cb, tp) {
    this.off(topic, null, tp);
    return this.on(topic, cb, tp)
  }
}