local ActPvpManager = class("ActPvpManager", BaseModule)

function ActPvpManager:showMainUI()
    if not DataManager.ActPvpData:getIsOpen() then
        GFunc.showToast(I18N:getGlobalText(I18N.GlobalConst.ACTIVITY_OVER_EDSC))
        return
    end

    if DataManager.ActPvpData:getNeedUpdateData() then
        self:reqActData()
    end
    if DataManager.ActPvpData:isPlaying() then
        UIManager:showUI("app/ui/activity/act_pvp/act_pvp_playing_ui")
    else
        UIManager:showUI("app/ui/activity/act_pvp/act_pvp_main_ui")
    end
end

function ActPvpManager:showMatchUI(forceShowMatchUI)
    if not DataManager.ActPvpData:getIsOpen() then
        GFunc.showToast(I18N:getGlobalText(I18N.GlobalConst.ACTIVITY_OVER_EDSC))
        return
    end
    if DataManager.ActPvpData:getNeedReMatch() or forceShowMatchUI then
        UIManager:showUI("app/ui/activity/act_pvp/act_pvp_match_ui")
        self:reqMatch()
    else
        self:showMatchResultUI()
    end
end

function ActPvpManager:showMatchResultUI()
    if not DataManager.ActPvpData:getIsOpen() then
        GFunc.showToast(I18N:getGlobalText(I18N.GlobalConst.ACTIVITY_OVER_EDSC))
        return
    end
    UIManager:showUI("app/ui/activity/act_pvp/act_pvp_match_result_ui")
end

function ActPvpManager:showHelpUI()
    UIManager:showUI("app/ui/activity/act_pvp/act_pvp_help_ui")
end

function ActPvpManager:showSelectUI()
    local curPairIds = DataManager.ActPvpData:getCurSelectPairId()
    if not curPairIds or not curPairIds[1] then
        return
    end
    UIManager:showUI("app/ui/activity/act_pvp/act_pvp_select_ui")
end

function ActPvpManager:showBountyUI()
    if not DataManager.ActPvpData:getIsOpen() then
        GFunc.showToast(I18N:getGlobalText(I18N.GlobalConst.ACTIVITY_OVER_EDSC))
        return
    end
    UIManager:showUI("app/ui/activity/act_pvp/act_pvp_bounty_ui")
end

function ActPvpManager:showRankUI()
    if not DataManager.ActPvpData:getIsOpen() then
        GFunc.showToast(I18N:getGlobalText(I18N.GlobalConst.ACTIVITY_OVER_EDSC))
        return
    end
    if DataManager.ActPvpData:getNeedUpdateRank() then
        self:reqRank()
    end
    UIManager:showUI("app/ui/activity/act_pvp/act_pvp_rank_ui")
end

function ActPvpManager:reqActData()
    self:sendMessage(ProtoMsgType.FromMsgEnum.ActivityPVPDataReq, {}, {}, self.rspActData)
end

function ActPvpManager:rspActData(result)
    if result.err_code == GConst.ERROR_STR.SUCCESS then
        DataManager.ActPvpData:updateData(result.activity_pvp)
    end
end

function ActPvpManager:reqEnter()
    if DataManager.ActPvpData:isFinalDay() then
        GFunc.showToast(I18N:getGlobalText(I18N.GlobalConst.ACT_PVP_DESC_24))
    end

    if not DataManager.ActPvpData:getIsOpen() then
        GFunc.showToast(I18N:getGlobalText(I18N.GlobalConst.ACTIVITY_OVER_EDSC))
        return
    end

    if DataManager.ActPvpData:isPlaying() then
        return
    end

    if DataManager.ActPvpData:getFreeEnterCount() <= 0 then
        local cost = DataManager.ActPvpData:getEnterCost()
        if not GFunc.checkCost(cost.id, cost.num, true) then
            return
        end
        local params ={
            content = I18N:getGlobalText(I18N.GlobalConst.ACT_PVP_DESC_1, cost.num),
            boxType = GConst.MESSAGE_BOX_TYPE.MB_OK_CANCEL,
            costId = cost.id,
            costNum = cost.num,
            okFunc = function()
                self:sendMessage(ProtoMsgType.FromMsgEnum.ActivityPVPBeginReq, {}, {}, self.rspEnter, BIReport.ITEM_GET_TYPE.ACT_PVP_ENTER)
            end,
        }
        GFunc.showMessageBox(params)
        return
    end

    self:sendMessage(ProtoMsgType.FromMsgEnum.ActivityPVPBeginReq, {}, {}, self.rspEnter, BIReport.ITEM_GET_TYPE.ACT_PVP_ENTER)
end

function ActPvpManager:rspEnter(result)
    if result.err_code == GConst.ERROR_STR.SUCCESS then
        DataManager.ActPvpData:updateData(result.activity_pvp)
        EventManager:dispatchEvent(EventManager.CUSTOM_EVENT.ACT_PVP_EVENT, {closeMainUI = true})
        self:showMainUI()
    end
end

function ActPvpManager:reqDecideHero(index)
    if not DataManager.ActPvpData:getIsOpen() then
        GFunc.showToast(I18N:getGlobalText(I18N.GlobalConst.ACTIVITY_OVER_EDSC))
        return
    end

    --int32 index = 1; // 0. 左边的、1.右边的
    local params = {
        index = index
    }
    self:sendMessage(ProtoMsgType.FromMsgEnum.ActivityPVPDecideHeroReq, params, {}, self.rspDecideHero)
end

function ActPvpManager:rspDecideHero(result)
    if result.err_code == GConst.ERROR_STR.SUCCESS then
        DataManager.ActPvpData:updateHerosInfo(result.heroes, result.pair_id, result.next_select_four_id)
        if not result.reqData then
            result.reqData = {index = 0}
        end
        EventManager:dispatchEvent(EventManager.CUSTOM_EVENT.ACT_PVP_EVENT, {selectIndex = result.reqData.index})
    end
end

function ActPvpManager:reqRefreshHero()
    if not DataManager.ActPvpData:getIsOpen() then
        GFunc.showToast(I18N:getGlobalText(I18N.GlobalConst.ACTIVITY_OVER_EDSC))
        return
    end

    if not DataManager.ActPvpData:getCanAdFlush() then
        local cost = DataManager.ActPvpData:getFlushCost()
        if not GFunc.checkCost(cost.id, cost.num, true) then
            return
        end

        local params ={
            content = I18N:getGlobalText(I18N.GlobalConst.ACT_PVP_DESC_13, cost.num),
            boxType = GConst.MESSAGE_BOX_TYPE.MB_OK_CANCEL,
            costId = cost.id,
            costNum = cost.num,
            okFunc = function()
                self:sendMessage(ProtoMsgType.FromMsgEnum.ActivityPVPFlushHeroesReq, {}, {}, self.rspRefreshHero, BIReport.ITEM_GET_TYPE.ACT_PVP_REFRESH_HERO)
            end,
        }
        GFunc.showMessageBox(params)
        return
    end
    self:sendMessage(ProtoMsgType.FromMsgEnum.ActivityPVPFlushHeroesReq, {}, {}, self.rspRefreshHero, BIReport.ITEM_GET_TYPE.ACT_PVP_REFRESH_HERO)
end

function ActPvpManager:rspRefreshHero(result)
    if result.err_code == GConst.ERROR_STR.SUCCESS then
        DataManager.ActPvpData:addFlushCount()
        DataManager.ActPvpData:updateSelectInfo(result.pair_id, result.next_select_four_id)
        EventManager:dispatchEvent(EventManager.CUSTOM_EVENT.ACT_PVP_EVENT, {refreshHero = true})
    end
end

function ActPvpManager:reqMatch()
    if not DataManager.ActPvpData:getIsOpen() then
        GFunc.showToast(I18N:getGlobalText(I18N.GlobalConst.ACTIVITY_OVER_EDSC))
        return
    end

    self:sendMessage(ProtoMsgType.FromMsgEnum.ActivityPVPMatchReq, {}, {}, self.rspMatch)
end

function ActPvpManager:rspMatch(result)
    if result.err_code == GConst.ERROR_STR.SUCCESS then
        DataManager.ActPvpData:updateRivalInfo(result.rival, result.match_cd_end_at)
        EventManager:dispatchEvent(EventManager.CUSTOM_EVENT.ACT_PVP_EVENT, {matchOver = true})
    end
end

function ActPvpManager:reqOverCD(isAd)
    if not DataManager.ActPvpData:getIsOpen() then
        GFunc.showToast(I18N:getGlobalText(I18N.GlobalConst.ACTIVITY_OVER_EDSC))
        return
    end

    if not isAd then
        local cost = DataManager.ActPvpData:getRematchConstGem()
        if not GFunc.checkCost(GConst.ItemConst.ITEM_ID_GEM, cost, true) then
            return
        end

        local params ={
            content = I18N:getGlobalText(I18N.GlobalConst.ARENA_DESC_25, cost),
            boxType = GConst.MESSAGE_BOX_TYPE.MB_OK_CANCEL,
            costId = GConst.ItemConst.ITEM_ID_GEM,
            costNum = cost,
            okFunc = function()
                self:sendMessage(ProtoMsgType.FromMsgEnum.ActivityPVPOverCDReq, {ad = isAd}, {}, self.rspOverCD, BIReport.ITEM_GET_TYPE.ACT_PVP_OVER_CD)
            end,
        }
        GFunc.showMessageBox(params)
        return
    end

    self:sendMessage(ProtoMsgType.FromMsgEnum.ActivityPVPOverCDReq, {ad = isAd}, {}, self.rspOverCD, BIReport.ITEM_GET_TYPE.ACT_PVP_OVER_CD)
end

function ActPvpManager:rspOverCD(result)
    if result.err_code == GConst.ERROR_STR.SUCCESS then
        EventManager:dispatchEvent(EventManager.CUSTOM_EVENT.ACT_PVP_EVENT, {reqCDOver = true})
        local isAd = false
        if result.reqData and result.reqData.ad then
            isAd = true
        end
        DataManager.ActPvpData:setMatchCdEndAt(isAd)
        self:showMatchUI(true)
    end
end

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

    self:sendMessage(ProtoMsgType.FromMsgEnum.ActivityPVPStartReq, {}, {}, self.rspFight)
end

function ActPvpManager:rspFight(result)
    if result.err_code == GConst.ERROR_STR.SUCCESS then
        local atkFormation = {}
        local defFormation = {}
        local heroes = DataManager.ActPvpData:getRivalInfoHeroes()
        if not heroes then
            Logger.logHighlight("1")
            return
        end

        local count = 0
        for matchType, heroEntity in pairs(heroes) do
            local id = heroEntity:getCfgId()
            if DataManager.HeroData:isExistHeroById(id) then
                defFormation[matchType] = heroEntity
                count = count + 1
            end
        end

        if count <= 0 then
            Logger.logHighlight("2")
            return
        end

        count = 0
        heroes = DataManager.ActPvpData:getHeros()
        for matchType, heroEntity in pairs(heroes) do
            local id = heroEntity:getCfgId()
            if DataManager.HeroData:isExistHeroById(id) then
                atkFormation[matchType] = heroEntity
                count = count + 1
            end
        end

        if count <= 0 then
            Logger.logHighlight("3")
            return
        end

        local defInfo = DataManager.ActPvpData:getRivalInfo()
        local params = {
            defInfo = defInfo,
            atkFormation = atkFormation,
            defFormation = defFormation
        }
        ModuleManager.BattleManager:playBattle(GConst.BattleConst.BATTLE_TYPE.ACT_PVP, params, function()
            UIManager:closeAllUI()
            ModuleManager.MaincityManager:showMainCityUI()
            ModuleManager.ActPvpManager:showMainUI()
        end)
    end
end

function ActPvpManager:reqFightEnd(win, battleReport, taskProgress)
    local parmas = {
        win = win,
        task_stat = taskProgress,
        battleReport = battleReport,
    }
    self:sendMessage(ProtoMsgType.FromMsgEnum.ActivityPVPSettlementReq, parmas, {}, self.rspFightEnd, BIReport.ITEM_GET_TYPE.ACT_PVP_FIGHT_END)
end

function ActPvpManager:rspFightEnd(result)
    if result.err_code == GConst.ERROR_STR.SUCCESS then
        local herolv = DataManager.ActPvpData:getHeroLv()
        DataManager.ActPvpData:recordLastBountyLevel()
        DataManager.ActPvpData:updateData(result.activity_pvp)
        DataManager.ActPvpData:setLastTurnWin(nil) -- 默认不给状态
        DataManager.ActPvpData:setHeroLevelUp(false)
        -- 展示结算界面
        if result.reqData then
            local taskStat = result.reqData.task_stat
            if taskStat then
                taskStat[GConst.BattleConst.BATTLE_TASK_FIELD.KILL_BOSS] = 0 -- boss不算
                taskStat[GConst.BattleConst.BATTLE_TASK_FIELD.KILL_NORMAL_MONSTER] = 0 -- 击杀小怪数量不算
                taskStat[GConst.BattleConst.BATTLE_TASK_FIELD.PASS_WAVE] = 0 -- 通关波数不算
                ModuleManager.TaskManager:addFightTaskProgress(taskStat)
            end
            ModuleManager.BattleManager:showActPvpResultUI(GConst.BattleConst.BATTLE_TYPE.ACT_PVP, result.rewards, result.reqData.battleReport)
            if not DataManager.ActPvpData:isPlaying() then -- 进入下一轮
                DataManager.ActPvpData:setLastTurnWin(result.reqData.win)
            else
                local newHerolv = DataManager.ActPvpData:getHeroLv()
                if newHerolv > herolv then
                    DataManager.ActPvpData:setHeroLevelUp(true)
                end
            end
        end
    end
end

function ActPvpManager:reqDailyReward(index)
    if not DataManager.ActPvpData:getIsOpen() then
        GFunc.showToast(I18N:getGlobalText(I18N.GlobalConst.ACTIVITY_OVER_EDSC))
        return
    end

    local params = {
        id = index
    }
    self:sendMessage(ProtoMsgType.FromMsgEnum.ActivityPVPDailyRewardsReq, params, {}, self.rspDailyReward, BIReport.ITEM_GET_TYPE.ACT_PVP_DAILY_REWARD)
end

function ActPvpManager:rspDailyReward(result)
    if result.err_code == GConst.ERROR_STR.SUCCESS then
        if result.reqData then
            DataManager.ActPvpData:setDailyReward(result.reqData.id)
        end
        GFunc.showRewardBox(result.rewards)
    end
end

function ActPvpManager:reqRank()
    self:sendMessage(ProtoMsgType.FromMsgEnum.ActivityPVPRankReq, {}, {}, self.rspRank)
end

function ActPvpManager:rspRank(result)
    if result.err_code == GConst.ERROR_STR.SUCCESS then
        DataManager.ActPvpData:updateRankInfo(result.ranks, result.own_rank)
    end
end

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

    self:sendMessage(ProtoMsgType.FromMsgEnum.ActivityPVPRankRewardsReq, {}, {}, self.rspRankReward, BIReport.ITEM_GET_TYPE.ACT_PVP_RANK_REWARD)
end

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

function ActPvpManager:reqBountyReward(id, bountyType)
    if not DataManager.ActPvpData:getIsOpen() then
        GFunc.showToast(I18N:getGlobalText(I18N.GlobalConst.ACTIVITY_OVER_EDSC))
        return
    end

    local typeNum = DataManager.ActPvpData.BOUNTY_TYPE_TO_NUM[bountyType]
    if not typeNum then
        return
    end
    local params = {
        id = id,
        grade = typeNum
    }
    self:sendMessage(ProtoMsgType.FromMsgEnum.ActivityPVPBountyClaimReq, params, {}, self.rspBountyReward, BIReport.ITEM_GET_TYPE.ACT_PVP_BOUNTY)
end

function ActPvpManager:rspBountyReward(result)
    if result.err_code == GConst.ERROR_STR.SUCCESS then
        DataManager.ActPvpData:setBountyCollected(result.success_id_grade)
        GFunc.showRewardBox(result.rewards)
    end
end

function ActPvpManager:reqBuyBountyLevel()
    if not DataManager.ActPvpData:getIsOpen() then
        GFunc.showToast(I18N:getGlobalText(I18N.GlobalConst.ACTIVITY_OVER_EDSC))
        return
    end

    local level = DataManager.ActPvpData:getBountyLevel()
    if level + 1 > DataManager.ActPvpData:getMaxBountyLevel() then
        return
    end
    local cost = DataManager.ActPvpData:getBuyBountyLevelCost()
    if not GFunc.checkCost(cost.id, cost.num, true) then
        return
    end
    local params ={
		titleTx = I18N:getGlobalText(I18N.GlobalConst.BOUNTY_BUY_LEVEL_TITLE),
		content = I18N:getGlobalText(I18N.GlobalConst.BOUNTY_BUY_LEVEL_COUNTENT),
		boxType = GConst.MESSAGE_BOX_TYPE.MB_OK_CANCEL,
		showToday = GConst.MESSAGE_BOX_SHOW_TODAY.ACT_PVP_BUY_BOUNTY_LEVEL,
		costId = cost.id,
		costNum = cost.num,
		okFunc = function()
            local params = {
                id = DataManager.ActPvpData:getBountyLevelId(level + 1)
            }
            self:sendMessage(ProtoMsgType.FromMsgEnum.ActivityPVPBountyClaimByDiamondReq, params, {}, self.rspBuyBountyLevel, BIReport.ITEM_GET_TYPE.ACT_PVP_BUY_BOUNTY_LEVEL)
		end,
	}
    GFunc.showMessageBox(params)
end

function ActPvpManager:rspBuyBountyLevel(result)
    if result.err_code == GConst.ERROR_STR.SUCCESS then
        DataManager.ActPvpData:setBountyLevel(result.reqData.id)
    end
end

return ActPvpManager