local DungeonRuneManager = class("DungeonRuneManager", BaseModule)

function DungeonRuneManager:showMainUI()
    UIManager:showUI("app/ui/dungeon_rune/dungeon_rune_main_ui")
end

function DungeonRuneManager:showFightUI(id)
    local runeData = DataManager.DungeonData:getDungeonDataByType(ModuleManager.MODULE_KEY.RUNES_OPEN)
    if not runeData:canFight(id) then
        GFunc.showToast(I18N:getGlobalText(I18N.GlobalConst.PASS_REQUIRE))
        return
    end

    local params = {id = id}
    local isBoss = runeData:isBossChapter(id)
    if isBoss then
        UIManager:showUI("app/ui/dungeon_rune/dungeon_rune_boss_fight_ui", params)
    else
        UIManager:showUI("app/ui/dungeon_rune/dungeon_rune_fight_ui", params)
    end
end

function DungeonRuneManager:showTaskUI(id)
    local params = {id = id}
    UIManager:showUI("app/ui/dungeon_rune/dungeon_rune_task_ui", params)
end

function DungeonRuneManager:showRebirthUI(adCallback, closeCallback, isHpOver, roundIsOver)
    UIManager:showUI("app/ui/dungeon_rune/dungeon_rune_rebirth_ui",{adCallback = adCallback, refuseCallback = closeCallback, isHpOver = isHpOver, roundIsOver = roundIsOver})
end

function DungeonRuneManager:showRoundTipUI(round)
    UIManager:showUI("app/ui/dungeon_rune/dungeon_rune_round_tip_ui",{round = round, aniType = UIManager.ANI_TYPE.NON})
end

function DungeonRuneManager:reqFight(id)
    local runeData = DataManager.DungeonData:getDungeonDataByType(ModuleManager.MODULE_KEY.RUNES_OPEN)
    if not runeData:canFight(id) then
        GFunc.showToast(I18N:getGlobalText(I18N.GlobalConst.PASS_REQUIRE))
        return
    end

    local passed = runeData:passedChapter(id)
    if not passed and not GFunc.checkCost(GConst.ItemConst.ITEM_ID_GLOD_WING, 1, true) then
        return
    end

    local heroes = {}
    local formation = DataManager.FormationData:getDungeonRuneFormation()
    for matchType, heroId in pairs(formation) do
        if heroId > 0 then
            table.insert(heroes, heroId)
        end
    end
    self:sendMessage(ProtoMsgType.FromMsgEnum.ChapterRuneChallengeStartReq, {id = id, heroes = heroes}, {}, self.rspFight, BIReport.ITEM_GET_TYPE.DUNGEON_RUNE_START)
end

function DungeonRuneManager:rspFight(result)
    if result.err_code == GConst.ERROR_STR.SUCCESS then
        if not result.reqData then
            return
        end

        local runeData = DataManager.DungeonData:getDungeonDataByType(ModuleManager.MODULE_KEY.RUNES_OPEN)
        runeData:setCurFightChapterId(result.reqData.id)
        local params = {
            atkFormation = {}
        }
        local formation = DataManager.FormationData:getDungeonRuneFormation()
        for elementType, heroId in pairs(formation) do
            local heroEntity = DataManager.HeroData:getHeroById(heroId)
            if heroEntity then
                params.atkFormation[elementType] = heroEntity
            end
        end
        ModuleManager.BattleManager:playBattle(GConst.BattleConst.BATTLE_TYPE.DUNGEON_RUNE, params, function()
            UIManager:closeAllUI()
            ModuleManager.MaincityManager:showMainCityUI()
            self:showMainUI()
        end)
    end
end

function DungeonRuneManager:reqFightSettlement(chapterId, combatReport, taskProgress, remainRound)
    taskProgress[GConst.BattleConst.BATTLE_TASK_FIELD.PASS_WAVE] = 0-- 符文副本不需要波次数据
    local parmas = {
        id = chapterId,
        win = combatReport.victory,
        task_stat = taskProgress,
        combatReport = combatReport,
        remainRound = remainRound,
    }
    self:sendMessage(ProtoMsgType.FromMsgEnum.ChapterRuneChallengeSettlementReq, parmas, {}, self.rspFightSettlement, BIReport.ITEM_GET_TYPE.DUNGEON_RUNE_SETTLEMENT)
end

function DungeonRuneManager:rspFightSettlement(result)
    if result.err_code == GConst.ERROR_STR.SUCCESS then
        local runeData = DataManager.DungeonData:getDungeonDataByType(ModuleManager.MODULE_KEY.RUNES_OPEN)
        local passId = runeData:getPassedMaxId()
        if result.reqData then
            if result.reqData.win then
                runeData:updatePassedMaxId(result.max_id)
                runeData:updatePassRound(result.reqData.id, result.reqData.task_stat[GConst.BattleConst.BATTLE_TASK_FIELD.TOTAL_TURN] or 0)
            end
            ModuleManager.BattleManager:showBattleRuneResultUI(GConst.BattleConst.BATTLE_TYPE.DUNGEON_RUNE, result.rewards, result.reqData.combatReport, result.reqData.remainRound)
        end
        if passId ~= runeData:getPassedMaxId() then
            local data = {}
            data.dungeon_progress = DataManager.DungeonData:getDungeonBIStr()
            CS.ThinkingAnalytics.ThinkingAnalyticsAPI.UserSet(data)
        end

        if result.reqData then
            local taskStat = result.reqData.task_stat
            if taskStat then
                ModuleManager.TaskManager:addFightTaskProgress(taskStat)
            end
        end
        runeData:setDirty()
    end
end

function DungeonRuneManager:reqSweep(id)
    if not GFunc.checkCost(GConst.ItemConst.ITEM_ID_SLIVER_WING, 1, true) then
        return
    end

    local runeData = DataManager.DungeonData:getDungeonDataByType(ModuleManager.MODULE_KEY.RUNES_OPEN)
    if not runeData:canSweep(id) then
        return
    end

    self:sendMessage(ProtoMsgType.FromMsgEnum.ChapterRuneFarmReq, {id = id}, {}, self.rspSweep, BIReport.ITEM_GET_TYPE.DUNGEON_RUNE_SWEEP)
end

function DungeonRuneManager:rspSweep(result)
    if result.err_code == GConst.ERROR_STR.SUCCESS then
        GFunc.showRewardBox(result.rewards)
        local runeData = DataManager.DungeonData:getDungeonDataByType(ModuleManager.MODULE_KEY.RUNES_OPEN)
        runeData:setDirty()
    end
end

function DungeonRuneManager:reqRebirth(isHpOver)
    self:sendMessage(ProtoMsgType.FromMsgEnum.ChapterRuneAdReq, {}, {}, self.rspRebirth)
end

function DungeonRuneManager:rspRebirth(result)
    if result.err_code == GConst.ERROR_STR.SUCCESS then
        EventManager:dispatchEvent(EventManager.CUSTOM_EVENT.BATTLE_REBIRTH)
    end
end

function DungeonRuneManager:reqFormation(formation)
    if not DataManager.FormationData:formationIsFull(GConst.BattleConst.FORMATION_TYPE.DUNGEON_RUNE) then
        GFunc.showToast(I18N:getGlobalText(I18N.GlobalConst.BATTLE_DESC_8))
        return
    end

    local heroes = {}
    for matchType, heroId in pairs(formation) do
        if heroId and heroId > 0 then
            table.insert(heroes, heroId)
        end
    end
    local params = {
        heroes = heroes
    }
    self:sendMessage(ProtoMsgType.FromMsgEnum.ChapterRuneChallengeHeroesReq, params, {}, self.rspFormation)
end

function DungeonRuneManager:rspFormation(result)
    if result.err_code == GConst.ERROR_STR.SUCCESS then
        EventManager:dispatchEvent(EventManager.CUSTOM_EVENT.FORMATION_CHANGE, {type = GConst.BattleConst.FORMATION_TYPE.DUNGEON_RUNE})
    end
end

function DungeonRuneManager:getTaskStatus(battleControllerRune, taskInfo)
    local taskProgress = {}
    for index, condition in ipairs(taskInfo) do
        local progress = battleControllerRune:getRuneTaskNumByType(condition)
        if condition[1] ==  GConst.DungeonRuneConst.TASK_TYPE.PASS_ROUND then
            taskProgress[index] = {
                progress = battleControllerRune.dungeonRuneMaxRoundCount - battleControllerRune.dungeonRuneRemainRoundCount,
                totalProgress = battleControllerRune.dungeonRuneMaxRoundCount,
                over = false
            }
        else
            if progress then
                taskProgress[index] = {
                    progress = progress,
                    totalProgress = condition[3],
                    over = progress >= condition[3]
                }
            end
        end
    end

    return taskProgress
end

function DungeonRuneManager:reqBuySliverWing(count)
    if not count then
        return
    end
    local runeData = DataManager.DungeonData:getDungeonDataByType(ModuleManager.MODULE_KEY.RUNES_OPEN)
    local cost = runeData:getBuySliverCost()
    if not GFunc.checkCost(cost.id, cost.num * count, true) then
        return
    end
    self:sendMessage(ProtoMsgType.FromMsgEnum.ChapterRuneBuySliverReq, {buy_count = count}, {}, self.rspBuySliverWing, BIReport.ITEM_GET_TYPE.DUNGEON_RUNE_BUY_WING)
end

function DungeonRuneManager:rspBuySliverWing(result)
    if result.err_code == GConst.ERROR_STR.SUCCESS then
        GFunc.showRewardBox(result.rewards)
        if result.reqData then
            local runeData = DataManager.DungeonData:getDungeonDataByType(ModuleManager.MODULE_KEY.RUNES_OPEN)
            runeData:addSliverWingBuyCount(result.reqData.buy_count)
        end
    end
end

return DungeonRuneManager