local ActBossRushManager = class("ActBossRushManager", BaseModule)

function ActBossRushManager:showMainUI()
    if not DataManager.ActBossRushData:getIsOpen() then
        GFunc.showToast(I18N:getGlobalText(I18N.GlobalConst.ACTIVITY_OVER_EDSC))
        return 
    end
    self:reqTopRank()
    UIManager:showUI("app/ui/activity/act_boss_rush/act_boss_rush_ui")
end

function ActBossRushManager:showFundUI()
    UIManager:showUI("app/ui/activity/act_boss_rush/act_boss_rush_fund_ui")
end

function ActBossRushManager:showRankUI()
    self:reqRankList()
    UIManager:showUI("app/ui/activity/act_boss_rush/act_boss_rush_rank_ui")
end

function ActBossRushManager:showShopUI()
    UIManager:showUI("app/ui/activity/act_boss_rush/act_boss_rush_shop_ui")
end

function ActBossRushManager:showPopUI()
    UIManager:showUI("app/ui/activity/act_boss_rush/act_boss_rush_pop_ui")
    return true
end

function ActBossRushManager:reqFight()
    if not DataManager.ActBossRushData:getIsOpen() then
        GFunc.showToast(I18N:getGlobalText(I18N.GlobalConst.ACTIVITY_OVER_EDSC))
        return 
    end

    if not DataManager.ActBossRushData:getFightFree() then
        local cost = DataManager.ActBossRushData:getFightCost()
        if not GFunc.checkCost(GConst.ItemConst.ITEM_ID_GEM, cost, true) then -- 消耗不足
            return
        else
            local params ={
				content = I18N:getGlobalText(I18N.GlobalConst.ACT_BOSS_RUSH_DESC_1, cost),
				boxType = GConst.MESSAGE_BOX_TYPE.MB_OK_CANCEL,
				costId = GConst.ItemConst.ITEM_ID_GEM,
				costNum = cost,
				okFunc = function()
                    self:sendMessage(ProtoMsgType.FromMsgEnum.BossRushStartReq, {}, {}, self.rspFight, BIReport.ITEM_GET_TYPE.ACT_BOSS_RUSH_FIGHT_START)
				end,
			}
			GFunc.showMessageBox(params)
            return
        end
    end

    self:sendMessage(ProtoMsgType.FromMsgEnum.BossRushStartReq, {}, {}, self.rspFight, BIReport.ITEM_GET_TYPE.ACT_BOSS_RUSH_FIGHT_START)
end

function ActBossRushManager:rspFight(result)
    if result.err_code == GConst.ERROR_STR.SUCCESS then
        DataManager.ActBossRushData:updateStageSeed(result.seed)

        local params = {
            atkFormation = {}
        }
        local formation = DataManager.FormationData:getBossRushFormation()
        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.ACT_BOSS_RUSH, params, function()
            UIManager:closeAllUI()
            ModuleManager.MaincityManager:showMainCityUI()
            ModuleManager.ActBossRushManager:showMainUI()
        end)
    end
end

function ActBossRushManager:reqEndBattle(chapterId, combatReport, taskProgress)
    local params = {
        chapterId = chapterId,
        combatReport = combatReport,
        task_stat = taskProgress
    }
    self:sendMessage(ProtoMsgType.FromMsgEnum.BossRushSettlementReq, params, {}, self.rspEndBattle, BIReport.ITEM_GET_TYPE.ACT_BOSS_RUSH_FIGHT)
end

function ActBossRushManager:rspEndBattle(result)
    if result.err_code == GConst.ERROR_STR.SUCCESS then
        if result.reqData then
            ModuleManager.TaskManager:addFightTaskProgress(result.reqData.task_stat)
            DataManager.ActBossRushData:addWaveCount(result.reqData.task_stat[GConst.BattleConst.BATTLE_TASK_FIELD.PASS_WAVE] or 0)
        end

        local wave = result.max_wave or 0
        local round = result.min_round or 0
        DataManager.ActBossRushData:updateWaveAndRound(wave, round)
        ModuleManager.BattleManager:showBossRushBattleResultUI(GConst.BattleConst.BATTLE_TYPE.ACT_BOSS_RUSH, result.reqData and result.reqData.combatReport, result.reqData and result.reqData.task_stat)
    end
end

function ActBossRushManager:purcharse(id)
    PayManager:purchasePackage(id, PayManager.PURCHARSE_TYPE.ACT_GIFT)
end

function ActBossRushManager:reqFundAward(level, rewardType)
    if not DataManager.ActBossRushData:getIsOpen() then
        GFunc.showToast(I18N:getGlobalText(I18N.GlobalConst.ACTIVITY_OVER_EDSC))
        return
    end
    -- -- 直接一键领取
    -- local curLevel = DataManager.ActBossRushData:getWaveLevel()
    -- local idWithLv = {}
    -- for id = 1, curLevel do
    --     if DataManager.ActBossRushData:getFreeCanGet(id) then
    --         table.insert(idWithLv, {id = id, grade = 0})
    --     end

    --     if DataManager.ActBossRushData:getProCanGet(id) then
    --         table.insert(idWithLv, {id = id, grade = 1})
    --     end

    --     if DataManager.ActBossRushData:getUtralCanGet(id) then
    --         table.insert(idWithLv, {id = id, grade = 2})
    --     end
    -- end

    -- if not idWithLv[1] then
    --     return
    -- end

    local params = {
        id = level,
        grade = rewardType
    }

    self:sendMessage(ProtoMsgType.FromMsgEnum.BossRushBountyClaimReq, params, {}, self.rspFundAward, BIReport.ITEM_GET_TYPE.ACT_BOSS_RUSH_FUND)
end

function ActBossRushManager:rspFundAward(result)
    if result.err_code == GConst.ERROR_STR.SUCCESS then
        if result.reqData then
            if result.reqData.id ~= 0 then
                DataManager.ActBossRushData:gotSingleFundReward(result.reqData.id, result.reqData.grade)
            end
        end
        GFunc.showRewardBox(result.rewards)
    end
end

function ActBossRushManager:reqBuyFundLevel()
    if not DataManager.ActBossRushData:getIsOpen() then
        GFunc.showToast(I18N:getGlobalText(I18N.GlobalConst.ACTIVITY_OVER_EDSC))
        return 
    end

    local cost = DataManager.ActBossRushData:getBuyBountyLevelCost()
    if not GFunc.checkCost(cost.id, cost.num, true) then
        return
    end

    self:sendMessage(ProtoMsgType.FromMsgEnum.BossRushBountyUnlockReq, {}, {}, self.rspBuyFundLevel, BIReport.ITEM_GET_TYPE.ACT_BOSS_RUSH_BUY_FUND)
end

function ActBossRushManager:rspBuyFundLevel(result)
    if result.err_code == GConst.ERROR_STR.SUCCESS then
        local addCount = result.accum_wave - DataManager.ActBossRushData:getWaveCount()
        if addCount > 0 then
            DataManager.ActBossRushData:addWaveCount(addCount)
        end
    end
end

function ActBossRushManager:reqExchange(id, count)
    if not DataManager.ActBossRushData:getIsOpen() then
        GFunc.showToast(I18N:getGlobalText(I18N.GlobalConst.ACTIVITY_OVER_EDSC))
        return 
    end

    if DataManager.ActBossRushData:getExchangeRemainCount(id) < count then
        return
    end

    local params = {
        id = id,
        count = count
    }

    self:sendMessage(ProtoMsgType.FromMsgEnum.BossRushExchangeReq, params, {}, self.rspExchange, BIReport.ITEM_GET_TYPE.ACT_BOSS_RUSH_SHOP)
end

function ActBossRushManager:rspExchange(result)
    if result.err_code == GConst.ERROR_STR.SUCCESS then
        if result.reqData then
            DataManager.ActBossRushData:setShopInfo(result.reqData.id, result.reqData.count)
        end
        GFunc.showRewardBox(result.rewards)
    end
end

function ActBossRushManager:reqRankReward()
    if not DataManager.ActBossRushData:getIsOpen() then
        GFunc.showToast(I18N:getGlobalText(I18N.GlobalConst.ACTIVITY_OVER_EDSC))
        return 
    end

    self:sendMessage(ProtoMsgType.FromMsgEnum.BossRushRankRewardReq, {}, {}, self.rspRankReward, BIReport.ITEM_GET_TYPE.ACT_BOSS_RUSH_RANK)
end

function ActBossRushManager:rspRankReward(result)
    if result.err_code == GConst.ERROR_STR.SUCCESS then
        DataManager.ActBossRushData:setGotRankReward()
        GFunc.showRewardBox(result.rewards)
    end
end

function ActBossRushManager:reqActData()
    self:sendMessage(ProtoMsgType.FromMsgEnum.BossRushInfoReq, {}, {}, self.rspActData)
end

function ActBossRushManager:rspActData(result)
    if result.err_code == GConst.ERROR_STR.SUCCESS then
        DataManager.ActBossRushData:init(result.boss_rush)
    end
end

function ActBossRushManager:reqRankList()
    if not DataManager.ActBossRushData:getIsOpen() then
        GFunc.showToast(I18N:getGlobalText(I18N.GlobalConst.ACTIVITY_OVER_EDSC))
        return 
    end

    if not DataManager.ActBossRushData:getNeedUpdateRank() then
        return
    end
    self:sendMessage(ProtoMsgType.FromMsgEnum.BossRushRankReq, {}, {}, self.rspRankList)
end

function ActBossRushManager:rspRankList(result)
    if result.err_code == GConst.ERROR_STR.SUCCESS then
        DataManager.ActBossRushData:updateRankInfo(result)
    end
end

function ActBossRushManager:reqTopRank()
    if not DataManager.ActBossRushData:getIsOpen() then
        GFunc.showToast(I18N:getGlobalText(I18N.GlobalConst.ACTIVITY_OVER_EDSC))
        return 
    end

    if not DataManager.ActBossRushData:getIsOpen() then
        return false
    end
    self:sendMessage(ProtoMsgType.FromMsgEnum.BossRushTopReq, {}, {}, self.rspTopRank)
end

function ActBossRushManager:rspTopRank(result)
    if result.err_code == GConst.ERROR_STR.SUCCESS then
        DataManager.ActBossRushData:updateTopRankInfo(result.top3)
    end
end

function ActBossRushManager:reqFormation(formation)
    if not DataManager.ActBossRushData:getIsOpen() then
        GFunc.showToast(I18N:getGlobalText(I18N.GlobalConst.ACTIVITY_OVER_EDSC))
        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.BossRushFormationReq, params, {}, self.rspFormation)
end

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

function ActBossRushManager:rspBossRushBoughtNtf(result)
    if result.bought then
        DataManager.ActBossRushData:setProBought()
    end

    if result.bought_max then
        DataManager.ActBossRushData:setUtralBought()
    end
end

---- 特殊callback, 引用的话，需要注意callback中如果有baseobj需要判定null或销毁状态
function ActBossRushManager:reqOtherPlayerInfo(playerId, callback)
	self.reqOtherPlayerInfoCallback = callback
	local params = {
		id = playerId
	}
	self:sendMessage(ProtoMsgType.FromMsgEnum.BossRushPlayerInfoReq, params, {}, self.rspOtherPlayerInfo)
end

function ActBossRushManager:rspOtherPlayerInfo(result)
	if result.err_code == GConst.ERROR_STR.SUCCESS then
		local callback = self.reqOtherPlayerInfoCallback
		self.reqOtherPlayerInfoCallback = nil
        local formation = GFunc.formatPlayerFormationInfo(result)
		if callback then
			callback(formation)
		end
	end
	self.reqOtherPlayerInfoCallback = nil
end

return ActBossRushManager