local EventManager = {
	listeners = {},
	listenerIndex = 0,
	dispatchCount = 0,
	waitRemoveMap = {},
	waitAddMap = {},
}

EventManager.CUSTOM_EVENT = {
	ON_BATTLE_START = "ON_BATTLE_START",					-- 战斗开始
	BATTLE_OPERATION_FINISH = "BATTLE_OPERATION_FINISH", 	-- 战斗中操作完毕
	BATTLE_OPERATION_START = "BATTLE_OPERATION_START",		-- 战斗中当玩家开始操作时
	BATTLE_END = "BATTLE_END",								-- 战斗结束
	UI_SHOW_COMPLETE = "UI_SHOW_COMPLETE",					-- UI打开完毕
	UI_CUSTOM_ANIMATION_COMPLETE = "UI_CUSTOM_ANIMATION_COMPLETE",	-- UI自定义动画完毕
	UI_CLOSE = "UI_CLOSE",									-- UI关闭
	MAIN_UI_CHECK_POP = "MAIN_UI_CHECK_POP",				-- 主界面检查弹出界面
	CHANGE_MAIN_CITY_PAGE = "CHANGE_MAIN_CITY_PAGE",		-- 切换主城页签
	TUTORIAL_TASK_REWARD = "TUTORIAL_TASK_REWARD",
	ATK_TRAIN_TUTORIAL_OVER = "ATK_TRAIN_TUTORIAL_OVER",
	TUTORIAL_TASK_STOP = "TUTORIAL_TASK_STOP",
	ELIMINATION_OVER = "ELIMINATION_OVER",
	SHOW_ELIMINATION_TUTORAIL = "SHOW_ELIMINATION_TUTORAIL",
	BOARD_FILL_OVER = "BOARD_FILL_OVER",
	LOGIN_REQ_SUCCESS = "LOGIN_REQ_SUCCESS",
	DAILY_TASK_COMPLETE = "DAILY_TASK_COMPLETE",				-- 每日任务完成
	BOSS_ENTER_ANI_OVER = "BOSS_ENTER_ANI_OVER",
	TIME_TRIGGERED_NEW_EMAIL = "TIME_TRIGGERED_NEW_EMAIL", 		-- 邮件到时间请求是否有新邮件
	SKILL_REFRESH_SUCC = "SKILL_REFRESH_SUCC",
	GO_SHOP = "GO_SHOP", -- 跳转商店
	UPDATE_MAIN_MALL_HEIGHT = "UPDATE_MAIN_MALL_HEIGHT", -- 更新主要商品的高度
	CHANGE_MAIN_COMP_MODULE = "CHANGE_MAIN_COMP_MODULE", -- 切换主界面模块
	CLOSE_BOX_HERO_UI = "CLOSE_BOX_HERO_UI",
	CLOSE_BOX_OPEN_UI = "CLOSE_BOX_OPEN_UI",
	BIND_ACCOUNT_SUCCESS = "BIND_ACCOUNT_SUCCESS",
	CDKEY_FINISH = "CDKEY_FINISH",								-- CDKEY
	DUNGEON_DAY_CHANGE = "DUNGEON_DAY_CHANGE",-- 副本跨天更新
	DUNGEON_CHALLENGE = "DUNGEON_CHALLENGE",-- 副本开始挑战
	DUNGEON_SWEEP = "DUNGEON_SWEEP",-- 副本开始扫荡
	PLAYER_INFO_CLICK_AVATAR = "PLAYER_INFO_CLICK_AVATAR",-- 个人信息选择头像
	PLAYER_INFO_CLICK_FRAME = "PLAYER_INFO_CLICK_FRAME",-- 个人信息选择头像框
	RENAME_SUCCESS = "RENAME_SUCCESS",-- 重命名成功
	GETED_REWARD_SUCCESS = "GETED_REWARD_SUCCESS",-- 获取奖励成功
	-- 竞技场
	ARENA_SEASON_SETTLEMENT = "ARENA_SEASON_SETTLEMENT",-- 赛季结算
	ARENA_SEASON_END = "ARENA_SEASON_END",-- 赛季结束
	ARENA_RECORD_SUCCESS = "ARENA_RECORD_SUCCESS",-- 战报获取成功
	ARENA_RANK_SUCCESS = "ARENA_RANK_SUCCESS",-- 排行榜获取成功
	ARENA_AD_BOX_SUCCESS = "ARENA_AD_BOX_SUCCESS",-- ad宝箱获取成功
	ARENA_BATTLE_SETTLEMENT = "ARENA_BATTLE_SETTLEMENT",-- 竞技场战斗结算
	-- 图鉴
	COLLECTION_CLICK_GET_POINT = "COLLECTION_CLICK_GET_POINT",
	-- 装备
	EQUIP_UPGRADE_SUCCESS = "EQUIP_UPGRADE_SUCCESS",
	EQUIP_UPSECTION_SUCCESS = "EQUIP_UPSECTION_SUCCESS",
	HERO_UPGRADE_SUCCESS = "HERO_UPGRADE_SUCCESS",
	GO_DUNGEON_UI = "GO_DUNGEON_UI",
	-- 皮肤
	SKIN_SELECT = "SKIN_SELECT",
	-- BORAD_TOUCH_BEGIN = "BORAD_TOUCH_BEGIN",
	-- BORAD_TOUCH_OVER = "BORAD_TOUCH_OVER"
	DUNGEON_ARMOR_TO_TARGET_ID = "DUNGEON_ARMOR_TO_TARGET_ID",
	ACTIVITY_SUMMER_END = "ACTIVITY_SUMMER_END",
	ACTIVITY_FULL_MOON_END = "ACTIVITY_FULL_MOON_END",
	ACTIVITY_TOURN_WAVE_END = "ACTIVITY_TOURN_WAVE_END",
	ACTIVITY_TOURN_ARENA_END = "ACTIVITY_TOURN_ARENA_END",
	MAIN_UI_CHECK_SIDE_BAR = "MAIN_UI_CHECK_SIDE_BAR",
	FORMATION_CHANGE = "FORMATION_CHANGE",
	BATTLE_REBIRTH = "BATTLE_REBIRTH",

	ACT_PVP_EVENT = "ACT_PVP_EVENT",
}

-- 此方法不能直接在外部调用，请使用例如BaseUI，BaseModule等封装好的接口
function EventManager:addEventListener(name, func, priority)
    if self.listeners[name] == nil then
		self.listeners[name] = {}
	end
	local tag = self.listenerIndex + 1
	self.listenerIndex = tag
	priority = priority or 0
	if self.dispatchCount > 0 then
		if not self.waitAddMap[name] then
			self.waitAddMap[name] = {}
		end
		table.insert(self.waitAddMap[name], {func, tag, priority})
	else
		local insert = false
		if priority > 0 then
			for k, v in ipairs(self.listeners[name]) do
				if priority <= v[3] then
					insert = true
					table.insert(self.listeners[name], k, {func, tag, priority})
					break
				end
			end
		end
		if not insert then
			table.insert(self.listeners[name], {func, tag, priority})
		end
	end
	return tag
end

function EventManager:removeEventListener(name, tag)
	if self.listeners[name] then
		for k, v in ipairs(self.listeners[name]) do
			if v[2] == tag then
				if self.dispatchCount > 0 then
					v[4] = 1
					self.waitRemoveMap[name] = 1
				else
					table.remove(self.listeners[name], k)
				end
				break
			end
		end
    end

	if self.waitAddMap[name] then
		local listenerList = self.waitAddMap[name]
		for index, listener in ipairs(listenerList) do
			if listener[2] == tag then
				table.remove(listenerList, index)
				break
			end
		end
	end
end

function EventManager:removeEventListenersByEvent(name)
	self.listeners[name] = nil
	self.waitAddMap[name] = nil
	self.waitRemoveMap[name] = nil
end

function EventManager:dispatchEvent(name, ...)
	self.dispatchCount = self.dispatchCount + 1
	local listenerList = self.listeners[name]
	if listenerList then
		local continue = nil
		for k, v in ipairs(listenerList) do
			if v[4] == nil then
				continue = v[1](...)
				if continue == false then
					break
				end
			end
        end
	end
	self.dispatchCount = self.dispatchCount - 1

	if self.dispatchCount > 0 then
		return
	end

	-- 处理等待移除
	for removeName, v in pairs(self.waitRemoveMap) do
		local listenerList = self.listeners[removeName]
		if listenerList then
			local count = #listenerList
			for i = count, 1, -1 do
				if listenerList[i] and listenerList[i][4] then
					table.remove(listenerList, i)
				end
			end
		end
		self.waitRemoveMap[removeName] = nil
	end

	-- 处理等待添加
	for addName, v in pairs(self.waitAddMap) do
		for i = 1, #v do
			local insert = false
			local listener = table.remove(v)
			local listenerPriority = listener[3]
			if listenerPriority > 0 then
				for k, existListener in ipairs(self.listeners[addName]) do
					if listenerPriority <= existListener[3] then
						insert = true
						table.insert(self.listeners[addName], k, listener)
						break
					end
				end
			end
			if not insert then
				table.insert(self.listeners[addName], listener)
			end
		end
		self.waitAddMap[addName] = nil
	end
end

function EventManager:removeAllEventListeners()
	self.listeners = {}
	self.waitRemoveMap = {}
	self.waitAddMap = {}
	self.listenerIndex = 0
end

function EventManager:clear()
    self:removeAllEventListeners()
end

if NOT_PUBLISH then
    function EventManager:_checkDebugAddEventListenerFuncMap()
        if self._debugAddEventListenerFuncMap == nil then
            self._debugAddEventListenerFuncMap = {
                [BaseUI.addEventListener] = true,
				[BaseScene.addEventListener] = true,
                [BaseModule.addEventListener] = true,
            }
        end
    end

    EventManager._releaseAddEventListener = EventManager.addEventListener
    function EventManager:addEventListener(...)
        self:_checkDebugAddEventListenerFuncMap()
        local currFunc = debug.getinfo(2, "f").func
        if self._debugAddEventListenerFuncMap[currFunc] == nil then
            Logger.logFatal("you can not call EventManager:addEventListener directly")
        end
        return self:_releaseAddEventListener(...)
    end
end

return EventManager