/* mitt事件相关 */
import mitt, { Emitter, Handler } from 'mitt';
// import tabStore from '@/store/modules/tabs';

/**
 * mitt事件枚举，分发和监听的事件类型必须在此定义
 */
export enum EmitterType {
  // 拖动拖拽布局
  DRAG_BAR_MOVE = 'dragBarMove',
  // sidebar侧边栏宽度变化
  SIDEBAR_WIDTH_CHANGE = 'sidebarWidthChange',
  // 点击了新建项目按钮
  CLICK_CREATE_PROJECT = 'clickCreateProject',
  // 重新加载建设项目
  RELOAD_CONSTRUCTION_PROJECTS = 'reload:construction',
  // 刷新项目管理-全部 表格
  REFRESH_ALL_TABLE = 'refresh:allTable',
  // 更改了项目管理-全部树
  UPDATE_ALL_TREE = 'update:allTree',
  // 更改了项目导航树
  UPDATE_SUBJECT_TREE = 'update:subjectTree',
  // 更改(恢复)回收站树
  UPDATE_RECYCLE_TREE = 'update:recycleTree',
  // 点击了回收站的恢复按钮
  RECYCLE = 'clickRecycle',
  // 点击了彻底删除
  COMPLETELY_REMOVE = 'clickCompletelyRemove',
  // 更改了造价书节点
  UPDATE_COST_NODE = 'update:costNode',
  // 更新了特征及内容文本
  UPDATE_CONTENT_CHARACTER = 'update:contentCharacter',
  // 更新造价书列设置
  UPDATE_COST_SETTING = 'update:costSetting',
  // 刷新造价书
  REFRESH_COST = 'refresh:cost',
  // 刷新造价书按钮有效性
  REFRESH_COST_BUTTON = 'refresh:costButton',
  // 选中造价书节点
  SELECT_COST = 'select:cost',
  // 设置造价书Loading
  SET_COST_LOADING = 'set:costLoading',
  // 刷新项目工料机表格
  REFRESH_PROJECT_GLJ = 'refresh:projectGlj',
  // 刷新关联材料表格
  REFRESH_RELATED_MATERIAL = 'refresh:relatedMaterial',
  // 刷新建设项目级工料机汇总
  REFRESH_SUMMARY_GLJ = 'refresh:summaryGlj',
  // 切换建设项目工料机汇总表格的loading状态
  TRIGGER_SUMMARY_LOADING = 'trigger:summaryLoading',
  // 刷新量价表格
  REFRESH_VOLUME_PRICE = 'refresh:volumePrice',
  // 刷新定额工料机表格
  REFRESH_RATION_GLJ = 'refresh:rationGlj',
  // 刷新定额安装增加费表格
  REFRESH_RATION_INSTALL = 'refresh:rationInstall',
  // 刷新费用修改表格
  REFRESH_EDIT_RULE = 'refresh:editRule',
  // 刷新计算程序表格
  REFRESH_CALC_PROGRAM = 'refresh:calcProgram',
  // 刷新定额子目换算表格
  REFRESH_RATION_CALC = 'refresh:rationCalc',
  // 刷新定额库定额列表
  REFRESH_LIB_RATION = 'refresh:libRation',
  // 刷新定额库定额列表列设置
  UPDATE_LIB_RATION_SETTING = 'refresh:libRationSetting',
  // 刷新定额模板子目
  RELOAD_RATION_TEMPLATE = 'refresh:rationTemplate',
  // 刷新信息价表格
  REFRESH_INFO_PRICE = 'refresh:infoPrice',
  // 刷新费率页面表格
  REFRESH_FEE_RATE = 'refresh:feeRate',
  // 刷新补充定额章节树按钮区有效性
  REFRESH_RATION_TREE_TOOLS = 'refresh:rationTreeTools',
  // 刷新补充定额表格
  REFRESH_CPT_RATION = 'refresh:cptRation',
  // 刷新安装增加费用项表格
  REFRESH_INSTALL_FEE_ITEM = 'refresh:installFeeItem',
  // 项目分享历史变更
  PROJECT_SHARE_HISTORY_CHANGED = 'projectShareHistoryChanged',
  // 定额库分享历史变更
  RATION_LIB_SHARE_HISTORY_CHANGED = 'rationLibShareHistoryChanged',
  // 人材机库分享历史变更
  GLJ_LIB_SHARE_HISTORY_CHANGED = 'gljLibShareHistoryChanged',
  // 更新了子目换算总表数据
  UPDATE_CPT_COE = 'update:cptCoe',
  // 关闭计算基数弹窗
  CLOSE_FORMULA_POPUP = 'close:formulaPopup',
  // 打开库标签
  OPEN_LIB_TAB = 'open:libTab',
  // 添加新成员
  ADD_NEW_MEMBER = 'addNewMember',
  // 打开消息中心
  OPEN_NOTIFICATION = 'openNotification',
  // 未读消息数量变化
  UNREAD_COUNT_CHANGE = 'unreadCountChange',
  // 新消息
  NEW_MESSAGE = 'newMessage',
  // 离开 socket 房间
  LEAVE_ROOM = 'leaveRoom',
  // 刷新工料机库显示(按选中类别)
  REFRESH_CPT_GLJ_LIB = 'refresh:cptGljLib',
  // 变更补充定额库
  CHANGE_CPT_RATION_LIB = 'change:cptRationLib',
  // 变更补充人材机库
  CHANGE_CPT_GLJ_LIB = 'change:cptGljLib',
  // 刷新书签批注
  REFRESH_BOOKMARK = 'refresh:bookmark',
  // 更新显示/隐藏特征按钮
  UPDATE_SHOW_FEATURE = 'update:isShowFeature',
  // 造价单书签批注用，hover事件计数器
  CLEAR_CELL_HOVER_LIST = 'clear:cellHoverList',
  // 清空人材机组成物
  CLEAR_GLJ_COMPONENT = 'clear:gljComponent',
  // 刷新建设项目分享标记
  REFRESH_CONSTRUCTION_SHARE_MARK = 'refresh:constructionShareMark',
  // 单位工程信息指标表格刷新
  REFRESH_TARGET_GRID = 'refresh:targetGrid',
  // 刷新建设项目汇总
  REFRESH_CONSTRUCTION_SUMMARY = 'refresh:constructionSummary',
  // 刷新分享项目数据
  REFRESH_SHARE_PROJECT = 'refresh:shareProject',
  // 刷新分享定额库数据
  REFRESH_SHARE_RATION_LIB = 'refresh:shareRationLib',
  // 刷新分享人材机库数据
  REFRESH_SHARE_GLJ_LIB = 'refresh:shareGljLib',
  // 追加定额库选项
  APPEND_RATION_LIB_OPTION = 'append:rationLibOption',
  // 追加人材机库选项
  APPEND_GLJ_LIB_OPTION = 'append:gljLibOption',
  // 移除定额库选项
  REMOVE_RATION_LIB_OPTION = 'remove:rationLibOption',
  // 移除人材机库选项
  REMOVE_GLJ_LIB_OPTION = 'remove:gljLibOption',
  // 刷新项目权限
  REFRESH_PROJECT_PERMISSION = 'refresh:projectPermission',
}

// 单例的emitter(有些事件不能用单例，可能会有多建设项目页面)
const singletonEmitter = mitt();

const emitterMap = new Map<string, Emitter>();

// 已出现的监听枚举
const listenedMap: Record<string, Handler> = {};

// 获取mitt事件处理方法，如果不传入key，则处理事件的对象为singletonEmitter。即不需要区分emitter的时候，不传入key
export const getEmitter = (key?: string) => {
  let emitter: Emitter;
  if (key) {
    if (!emitterMap.get(key)) {
      emitterMap.set(key, mitt());
    }
    emitter = emitterMap.get(key) as Emitter;
  } else {
    emitter = singletonEmitter;
  }
  return {
    /**
     * !!!注意!!!：emit监听时，按需增加监听事件名称，同一类型下，不可有重复监听事件名称
     * 由于组件可能多次渲染（多次进入setup方法），为了避免重复监听事件。
     */
    on<T = any>(emitterType: EmitterType, handler: Handler<T>, listenerName?: string) {
      const listenerKey = `${emitterType}-${listenerName}`;
      if (listenedMap[listenerKey]) {
        this.off(emitterType, listenedMap[listenerKey]);
      }
      listenedMap[listenerKey] = handler;
      emitter.on<T>(emitterType, handler);
    },
    off<T = any>(emitterType: EmitterType, handler: Handler<T>) {
      emitter.off<T>(emitterType, handler);
    },
    emit<T = any>(emitterType: EmitterType, payload?: T) {
      emitter.emit<T>(emitterType, payload);
    },
  };
};

// 获取当前建设项目的emitter
// export const getActiveEmitter = () => {
//   return getEmitter(tabStore.activeKey || '');
// };
