local TaskManager = class("TaskManager", BaseModule)
local BATTLE_TASK_FIELD = GConst.BattleConst.BATTLE_TASK_FIELD

function TaskManager:init()
    self:addEventListener(EventManager.CUSTOM_EVENT.DAILY_TASK_COMPLETE, function(id, taskId, from, to)
        if DataManager.DailyTaskData:getIsOpen() then
            ModuleManager.TaskToastManager:showToast(id, taskId, from, to)
        end
    end)
    self:addEventListener(EventManager.CUSTOM_EVENT.UI_SHOW_COMPLETE, function()
        ModuleManager.TaskToastManager:checkOnOpenUI()
    end)
end

function TaskManager:showTaskMainUI()
    UIManager:showUI("app/ui/task/task_main_ui")
end

function TaskManager:refreshDailyTask(dailyTaskId)
    SDKManager:showFullScreenAds(BIReport.ADS_CLICK_TYPE.TASK_DAILY_REFRESH, function()
        local parmas = {
            id = dailyTaskId,
        }
        self:sendMessage(ProtoMsgType.FromMsgEnum.TaskDailyRefreshReq, parmas, {}, self.onDailyTaskRefresh, BIReport.ITEM_GET_TYPE.TASK_DAILY_REFRESH)
    end)
end

function TaskManager:onDailyTaskRefresh(result)
    if result.err_code == GConst.ERROR_STR.SUCCESS then
        if result.task then
            DataManager.DailyTaskData:refreshDailyTask(result.task)
        end
    end
end

function TaskManager:claimDailyTask(dailyTaskId)
    local parmas = {
        id = dailyTaskId,
    }
    self:sendMessage(ProtoMsgType.FromMsgEnum.TaskDailyRewardReq, parmas, {}, self.onDailyTaskClaim, BIReport.ITEM_GET_TYPE.TASK_DAILY_REWARD)
end

function TaskManager:onDailyTaskClaim(result)
    if result.err_code == GConst.ERROR_STR.SUCCESS then
        if result.task then
            DataManager.DailyTaskData:refreshDailyTask(result.task)
        end
        if result.rewards then
            GFunc.showRewardBox(result.rewards)
        end
    end
end

function TaskManager:resetDailyTask()
    if DataManager.DailyTaskData:getIsInReset() then
        return
    end
    DataManager.DailyTaskData:setInReset(true)
    self:sendMessage(ProtoMsgType.FromMsgEnum.TaskDailyInfoReq, {}, {}, self.onResetDailyTask, BIReport.ITEM_GET_TYPE.NONE)
end

function TaskManager:onResetDailyTask(result)
    DataManager.DailyTaskData:setInReset(false)
    if result.err_code == GConst.ERROR_STR.SUCCESS then
        DataManager.DailyTaskData:init(result.info)
    end
end

function TaskManager:watchTaskSpecialAd()
    SDKManager:showFullScreenAds(BIReport.ADS_CLICK_TYPE.TASK_DAILY_TASK, function()
        self:sendMessage(ProtoMsgType.FromMsgEnum.TaskDailyAdReq, {}, {}, self.onWatchTaskSpecialAd, BIReport.ITEM_GET_TYPE.NONE)
    end)
end

function TaskManager:onWatchTaskSpecialAd(result)
    if result.err_code == GConst.ERROR_STR.SUCCESS then
        ModuleManager.TaskManager:addTaskProgress(GConst.TaskConst.TASK_TYPE.DAILY_TASK_WATCH_AD_SPECIAL)
    end
end

function TaskManager:registerTask(moduleName, taskType, callback)
    if not self.registerTaskInfo then
        self.registerTaskInfo = {}
    end

    if not self.registerTaskInfo[taskType] then
        self.registerTaskInfo[taskType] = {}
    end

    self.registerTaskInfo[taskType][moduleName] = callback
end

function TaskManager:unRegisterTask(moduleName, taskType)
    if not self.registerTaskInfo then
        return
    end

    if not self.registerTaskInfo[taskType] then
        return
    end

    self.registerTaskInfo[taskType][moduleName] = nil
end

function TaskManager:unRegisterAllModuleTask(name)
    if not self.registerTaskInfo then
        return
    end
    for taskType, callbacks in pairs(self.registerTaskInfo) do
        for moduleName, callback in pairs(callbacks) do
            if moduleName == name then
                callbacks[moduleName] = nil
                break
            end
        end
    end
end

function TaskManager:clear()
    self.registerTaskInfo = nil
end

function TaskManager:addTaskProgress(type, ...)
    if not self.registerTaskInfo then
        return
    end

    local func = TaskManager.TYPE_DEAL_FUNC[type]
    if func then
        func(self, ...)
    end
end

function TaskManager:dispatchTask(type, count)
    if DataManager.DailyTaskData:getIfCanReset() then -- 跨天了
		ModuleManager.TaskManager:resetDailyTask()
	end
    if not self.registerTaskInfo then
        return
    end
    if not self.registerTaskInfo[type] then
        return
    end

    for module, callback in pairs(self.registerTaskInfo[type]) do
        if callback then
            callback(count)
        end
    end
end

------------------------------------------------------ 处理任务 ------------------------------------------------------
function TaskManager:xKillMonster(count)
    self:dispatchTask(GConst.TaskConst.TASK_TYPE.X_KILL_MONSTER, count)
end

function TaskManager:xWatchAd()
    self:dispatchTask(GConst.TaskConst.TASK_TYPE.X_WATCH_AD, 1)
end

function TaskManager:completeDailyTask()
    self:dispatchTask(GConst.TaskConst.TASK_TYPE.COMPLETED_DALY_TASK, 1)
end

function TaskManager:xGoldGot(count)
    self:dispatchTask(GConst.TaskConst.TASK_TYPE.X_GOLD_GOT, count)
end

function TaskManager:xGoldCost(count)
    self:dispatchTask(GConst.TaskConst.TASK_TYPE.X_GOLD_COST, count)
end

function TaskManager:xGemGot(count)
    self:dispatchTask(GConst.TaskConst.TASK_TYPE.X_GEM_GOT, count)
end

function TaskManager:xGemCost(count)
    self:dispatchTask(GConst.TaskConst.TASK_TYPE.X_GEM_COST, count)
end

function TaskManager:xBattleVictory()
    self:dispatchTask(GConst.TaskConst.TASK_TYPE.X_BATTLE_VICTORY, 1)
end

function TaskManager:xHeroLvUp(level)
    self:dispatchTask(GConst.TaskConst.TASK_TYPE.X_HERO_LV_UP, 1)
    local maxLv = DataManager.TaskData:getMaxHeroLv()
    if maxLv < level then
        DataManager.TaskData:setMaxHeroLv(level)
        self:dispatchTask(GConst.TaskConst.TASK_TYPE.X_HERO_MAX_LV_REACH, level - maxLv)
    end
end

function TaskManager:xHeroFragmentGot(count)
    self:dispatchTask(GConst.TaskConst.TASK_TYPE.X_HERO_FRAGMENT_GOT, count)
end

function TaskManager:dailyTaskWatchAdSpecial()
    self:dispatchTask(GConst.TaskConst.TASK_TYPE.DAILY_TASK_WATCH_AD_SPECIAL, 1)
end

function TaskManager:skillBoxGotInBattle(count)
    self:dispatchTask(GConst.TaskConst.TASK_TYPE.X_SKILL_BOX_GOT_IN_BATTLE, count)
end

function TaskManager:xKillBoss(count)
    self:dispatchTask(GConst.TaskConst.TASK_TYPE.X_KILL_BOSS, count)
end

function TaskManager:xEliminate(count)
    self:dispatchTask(GConst.TaskConst.TASK_TYPE.X_ELIMINATE, count)
end

function TaskManager:xEliminateSixOnce(count)
    self:dispatchTask(GConst.TaskConst.TASK_TYPE.X_ELIMINATE_SIX_ONCE, count)
end

function TaskManager:xEliminateEightOnce(count)
    self:dispatchTask(GConst.TaskConst.TASK_TYPE.X_ELIMINATE_EIGHT_ONCE, count)
end

function TaskManager:xComboTen(count)
    self:dispatchTask(GConst.TaskConst.TASK_TYPE.X_COMBO_TEN, count)
end

function TaskManager:xUseSkill(count)
    self:dispatchTask(GConst.TaskConst.TASK_TYPE.X_USE_SKILL, count)
end

function TaskManager:xBattlePassWave(count)
    self:dispatchTask(GConst.TaskConst.TASK_TYPE.X_BATTLE_PASS_WAVE, count)
end

function TaskManager:xLoginDay()
    self:dispatchTask(GConst.TaskConst.TASK_TYPE.X_LOGIN_DAY, 1)
end

function TaskManager:xPlayerLvReach(count)
    self:dispatchTask(GConst.TaskConst.TASK_TYPE.X_PLAYER_LV_REACH, count)
end

function TaskManager:xPassChapter()
    self:dispatchTask(GConst.TaskConst.TASK_TYPE.X_PASS_CHAPTER, 1)
end

function TaskManager:xHeroMaxLvReach(maxlv)
    self:dispatchTask(GConst.TaskConst.TASK_TYPE.X_HERO_MAX_LV_REACH, maxlv)
end

function TaskManager:xVitCost(count)
    self:dispatchTask(GConst.TaskConst.TASK_TYPE.X_VIT_COST, count)
end

function TaskManager:xNewHeroGot()
    self:dispatchTask(GConst.TaskConst.TASK_TYPE.X_NEW_HERO_GOT, 1)
end

function TaskManager:xOpenShopBoxLevel1(count)
    self:dispatchTask(GConst.TaskConst.TASK_TYPE.X_OPEN_SHOP_BOX_LEVEL_1, count)
    self:dispatchTask(GConst.TaskConst.TASK_TYPE.X_OPEN_SHOP_BOX, count)
end

function TaskManager:xOpenShopBoxLevel2(count)
    self:dispatchTask(GConst.TaskConst.TASK_TYPE.X_OPEN_SHOP_BOX_LEVEL_2, count)
    self:dispatchTask(GConst.TaskConst.TASK_TYPE.X_OPEN_SHOP_BOX, count)
end

function TaskManager:xOpenShopBoxLevel3(count)
    self:dispatchTask(GConst.TaskConst.TASK_TYPE.X_OPEN_SHOP_BOX_LEVEL_3, count)
    self:dispatchTask(GConst.TaskConst.TASK_TYPE.X_OPEN_SHOP_BOX, count)
end

function TaskManager:xArenaChallenge()
    self:dispatchTask(GConst.TaskConst.TASK_TYPE.X_ARENA_CHALLENGE, 1)
end

function TaskManager:xArenaGradingScore(count)
    self:dispatchTask(GConst.TaskConst.TASK_TYPE.X_ARENA_GRADING, count)
end

function TaskManager:xDungeonShards(count)
    self:dispatchTask(GConst.TaskConst.TASK_TYPE.X_DUNGEON_SHARDS, count)
end

function TaskManager:xDungeonGold(count)
    self:dispatchTask(GConst.TaskConst.TASK_TYPE.X_DUNGEON_GOLD, count)
end

function TaskManager:xDungeonWeapon(count)
    self:dispatchTask(GConst.TaskConst.TASK_TYPE.X_DUNGEON_WEAPON, count)
end

function TaskManager:xDungeonArmor(count)
    self:dispatchTask(GConst.TaskConst.TASK_TYPE.X_DUNGEON_ARMOR, count)
end

function TaskManager:xDailyChallengeSuccess()
    self:dispatchTask(GConst.TaskConst.TASK_TYPE.X_DAILY_CHALLENGE_SUCCESS, 1)
end

function TaskManager:xOpenChapterBox()
    self:dispatchTask(GConst.TaskConst.TASK_TYPE.X_OPEN_CHAPTER_BOX, 1)
end

function TaskManager:xUpgradeWeapon()
    self:dispatchTask(GConst.TaskConst.TASK_TYPE.X_UPGRADE_WEAPON, 1)
end

function TaskManager:xUpgradeArmor()
    self:dispatchTask(GConst.TaskConst.TASK_TYPE.X_UPGRADE_ARMOR, 1)
end

function TaskManager:xBuyAnyone()
    self:dispatchTask(GConst.TaskConst.TASK_TYPE.X_BUY_ANYONE, 1)
end

function TaskManager:xRunesGetedMaterials(count)
    self:dispatchTask(GConst.TaskConst.TASK_TYPE.X_RUNES_GETED_MATERIALS, count)
end

function TaskManager:xRunesQuenching(count)
    self:dispatchTask(GConst.TaskConst.TASK_TYPE.X_RUNES_QUENCHING, count)
end

---- 没有特殊说明，方法均返回任务增量
TaskManager.TYPE_DEAL_FUNC = {
    [GConst.TaskConst.TASK_TYPE.X_WATCH_AD] = TaskManager.xWatchAd,
    [GConst.TaskConst.TASK_TYPE.X_GOLD_GOT] = TaskManager.xGoldGot,
    [GConst.TaskConst.TASK_TYPE.X_GEM_GOT] = TaskManager.xGemGot,
    [GConst.TaskConst.TASK_TYPE.X_GOLD_COST] = TaskManager.xGoldCost,
    [GConst.TaskConst.TASK_TYPE.X_GEM_COST] = TaskManager.xGemCost,
    [GConst.TaskConst.TASK_TYPE.X_BATTLE_VICTORY] = TaskManager.xBattleVictory,
    [GConst.TaskConst.TASK_TYPE.X_HERO_LV_UP] = TaskManager.xHeroLvUp,
    [GConst.TaskConst.TASK_TYPE.X_HERO_FRAGMENT_GOT] = TaskManager.xHeroFragmentGot,
    [GConst.TaskConst.TASK_TYPE.COMPLETED_DALY_TASK] = TaskManager.completeDailyTask,
    [GConst.TaskConst.TASK_TYPE.DAILY_TASK_WATCH_AD_SPECIAL] = TaskManager.dailyTaskWatchAdSpecial,
    [GConst.TaskConst.TASK_TYPE.X_SKILL_BOX_GOT_IN_BATTLE] = TaskManager.skillBoxGotInBattle,
    [GConst.TaskConst.TASK_TYPE.X_KILL_BOSS] = TaskManager.xKillBoss,
    [GConst.TaskConst.TASK_TYPE.X_KILL_MONSTER] = TaskManager.xKillMonster,
    [GConst.TaskConst.TASK_TYPE.X_ELIMINATE] = TaskManager.xEliminate,
    [GConst.TaskConst.TASK_TYPE.X_ELIMINATE_SIX_ONCE] = TaskManager.xEliminateSixOnce,
    [GConst.TaskConst.TASK_TYPE.X_ELIMINATE_EIGHT_ONCE] = TaskManager.xEliminateEightOnce,
    [GConst.TaskConst.TASK_TYPE.X_COMBO_TEN] = TaskManager.xComboTen,
    [GConst.TaskConst.TASK_TYPE.X_USE_SKILL] = TaskManager.xUseSkill,
    [GConst.TaskConst.TASK_TYPE.X_BATTLE_PASS_WAVE] = TaskManager.xBattlePassWave,
    [GConst.TaskConst.TASK_TYPE.X_LOGIN_DAY] = TaskManager.xLoginDay,
    [GConst.TaskConst.TASK_TYPE.X_PLAYER_LV_REACH] = TaskManager.xPlayerLvReach,
    [GConst.TaskConst.TASK_TYPE.X_PASS_CHAPTER] = TaskManager.xPassChapter,
    [GConst.TaskConst.TASK_TYPE.X_VIT_COST] = TaskManager.xVitCost,
    [GConst.TaskConst.TASK_TYPE.X_NEW_HERO_GOT] = TaskManager.xNewHeroGot,
    [GConst.TaskConst.TASK_TYPE.X_OPEN_SHOP_BOX_LEVEL_1] = TaskManager.xOpenShopBoxLevel1,
    [GConst.TaskConst.TASK_TYPE.X_OPEN_SHOP_BOX_LEVEL_2] = TaskManager.xOpenShopBoxLevel2,
    [GConst.TaskConst.TASK_TYPE.X_OPEN_SHOP_BOX_LEVEL_3] = TaskManager.xOpenShopBoxLevel3,
    [GConst.TaskConst.TASK_TYPE.X_ARENA_CHALLENGE] = TaskManager.xArenaChallenge,
    [GConst.TaskConst.TASK_TYPE.X_ARENA_GRADING] = TaskManager.xArenaGradingScore,
    [GConst.TaskConst.TASK_TYPE.X_DUNGEON_SHARDS] = TaskManager.xDungeonShards,
    [GConst.TaskConst.TASK_TYPE.X_DUNGEON_ARMOR] = TaskManager.xDungeonArmor,
    [GConst.TaskConst.TASK_TYPE.X_DUNGEON_GOLD] = TaskManager.xDungeonGold,
    [GConst.TaskConst.TASK_TYPE.X_DUNGEON_WEAPON] = TaskManager.xDungeonWeapon,
    [GConst.TaskConst.TASK_TYPE.X_DAILY_CHALLENGE_SUCCESS] = TaskManager.xDailyChallengeSuccess,
    [GConst.TaskConst.TASK_TYPE.X_OPEN_CHAPTER_BOX] = TaskManager.xOpenChapterBox,
    [GConst.TaskConst.TASK_TYPE.X_UPGRADE_WEAPON] = TaskManager.xUpgradeWeapon,
    [GConst.TaskConst.TASK_TYPE.X_UPGRADE_ARMOR] = TaskManager.xUpgradeArmor,
    [GConst.TaskConst.TASK_TYPE.X_BUY_ANYONE] = TaskManager.xBuyAnyone,
    [GConst.TaskConst.TASK_TYPE.X_RUNES_GETED_MATERIALS] = TaskManager.xRunesGetedMaterials,
    [GConst.TaskConst.TASK_TYPE.X_RUNES_QUENCHING] = TaskManager.xRunesQuenching,
}

function TaskManager:taskGoto(taskType)
    if TaskManager.gotoFunc[taskType] then
        TaskManager.gotoFunc[taskType](self)
    end
end

function TaskManager:gotoMainUI()
    ModuleManager.MaincityManager:showMainCityUI()
end

TaskManager.gotoFunc = {
    [GConst.TaskConst.TASK_TYPE.X_KILL_MONSTER] = TaskManager.gotoMainUI,
}

function TaskManager:dealTaskType(taskType, callback, onlyGet)
    if taskType == GConst.TaskConst.TASK_TYPE.X_KILL_MONSTER then
        if onlyGet then
            return taskType
        else
            ModuleManager.ChapterManager:calculateFightImmediately(callback)
        end
    else
        if callback and not onlyGet then
            callback()
        end
    end
end

function TaskManager:addFightTaskProgress(fightTaskProgress)
    for fieldName, value in pairs(fightTaskProgress) do
        local taskType = TaskManager.fightTaskProgressToTaskType[fieldName]
        if taskType then
            self:addTaskProgress(taskType, value)
        end
    end
end

TaskManager.fightTaskProgressToTaskType = {
    [BATTLE_TASK_FIELD.SKILL_BOX_OPEN] = GConst.TaskConst.TASK_TYPE.X_SKILL_BOX_GOT_IN_BATTLE,
    [BATTLE_TASK_FIELD.KILL_BOSS] = GConst.TaskConst.TASK_TYPE.X_KILL_BOSS,
    [BATTLE_TASK_FIELD.KILL_NORMAL_MONSTER] = GConst.TaskConst.TASK_TYPE.X_KILL_MONSTER,
    [BATTLE_TASK_FIELD.ELIMINATION_COUNT] = GConst.TaskConst.TASK_TYPE.X_ELIMINATE,
    [BATTLE_TASK_FIELD.LINK_COUNT_OVER_6] = GConst.TaskConst.TASK_TYPE.X_ELIMINATE_SIX_ONCE,
    [BATTLE_TASK_FIELD.LINK_COUNT_OVER_8] = GConst.TaskConst.TASK_TYPE.X_ELIMINATE_EIGHT_ONCE,
    [BATTLE_TASK_FIELD.COMBO_OVER_10] = GConst.TaskConst.TASK_TYPE.X_COMBO_TEN,
    [BATTLE_TASK_FIELD.BOARD_SKILL_RELEASE_COUNT] = GConst.TaskConst.TASK_TYPE.X_USE_SKILL,
    [BATTLE_TASK_FIELD.PASS_WAVE] = GConst.TaskConst.TASK_TYPE.X_BATTLE_PASS_WAVE,
}

return TaskManager