---
--- 竞技副本管理器
--- Generated by EmmyLua(https://github.com/EmmyLua)
--- Created by 0.
--- DateTime: 2019/5/9 11:31
---

XArenaManagerCreator = function()
    local XArenaManager = {}

    local SYNC_RANK_LIST_SECOND = 60 --获取排行榜List请求保护时间
    local SYNC_HALL_SECOND = 5       --获取其他请求保护时间
    local SYNC_OTHER_SECOND = 15     --获取其他请求保护时间

    local LastSyncRankListTime = 0   --排行榜List最后刷新时间
    local LastHallTeamListTime = 0   --大厅队伍列表最后刷新时间
    local LastHallPlayerListTime = 0 --大厅个人玩家列表最后刷新时间
    local LastFriendPlayerTime = 0   --请求好友竞技信息最后刷新时间

    --队伍数据
    local HallTeamMap = {}      --大厅队伍
    local HallPlayerMap = {}    --大厅玩家
    local FriendMap = {}        --好友列表
    local TeamInfo = nil    --队伍信息
    local ApplyMap = {}     --申请列表
    local InviteMap = {}    --邀请列表
    local HaveToRequestApplyData = -1

    local APPLY_TYPE = {
        TEAM = 1, --自己有队伍
        SINGLE = 2, --自己无队伍
    }

    --竞技全局数据
    local ActivityNo = 0            -- 活动编号
    local ActivityStatus = XArenaActivityStatus.Default   --当前活动状态
    local CountDownTime = 0         -- 进入下一阶段倒计时
    local TeamStartTime = 0         -- 组队期开始时间
    local FightStartTime = 0        -- 战斗期开始时间
    local ResultStartTime = 0       -- 结算期开始时间
    local WaveRate = 0              -- 波动指数

    --竞技排行数据
    local PlayerResultRankList = {}     -- 该段位玩家排行
    local TeamRankChallengeId = 0       -- 队伍排行榜的挑战ID
    local TeamRankData = {}             -- 队伍排行
    local TeamResultList = {}           -- 该段位队员成绩
    local AreaIdToStageDetailList = {}  -- 各战区玩家通关详情

    --竞技个人数据
    local ChallengeId = 0           -- 挑战Id（根据玩家等级与竞技段位决定）
    local ArenaLevel = 0            -- 竞技段位
    local IsJoinActivity = false    -- 是否已报名
    local UnlockCount = 0           -- 剩余解锁次数
    local TotalPoint = 0            -- 总分数
    local AreaDatas = {}            -- 战区信息列表

    local ArenaActivityResultData = nil  --竞技奖励缓存数据
    local ArenaStatusInFightChangeCache = false -- 竞技状态改变是否在战斗中缓存

    local EnterAreaStageInfo = {}   -- 进入战斗的区域信息

    local ArenaRequest = {
        RequestMyTeamInfo = "MyTeamRequest", -- 获取我的队伍信息
        RequestHallTeamList = "HallTeamRequest", -- 获取大厅队伍列表
        RequestHallPlayerList = "HallPlayerRequest", -- 获取大厅个人玩家列表
        RequestApplyData = "ApplyDataRequest", -- 获取邀请申请信息列表
        RequestFriendArenaInfo = "FriendPlayerRequest", -- 请求好友竞技信息
        RequestCreateTeam = "CreateTeamRequest", -- 请求创建队伍
        RequestApplyTeam = "ApplyTeamRequest", -- 申请入队
        RequestRefuseApply = "RefuseApplyRequest", -- 拒绝申请
        RequestAcceptApply = "AcceptApplyRequest", -- 接受申请
        RequestLeaveTeam = "LeaveTeamRequest", -- 请求离队
        RequestKickTeam = "KickTeamRequest", -- 请求踢人
        RequestInvitePlayer = "InvitePlayerRequest", -- 邀请玩家
        RequestRefuseInvite = "PersonalRefuseRequest", -- 拒绝邀请
        RequestAcceptInvite = "PersonalAcceptRequest", -- 接受邀请

        RequestSignUpArena = "JoinActivityRequest", -- 报名参加竞技活动

        RequestGroupMember = "GroupMemberRequest", -- 请求主页面成员信息
        RequestAreaData = "AreaDataRequest", -- 请求区域信息
        RequestStagePassDetail = "StagePassDetailRequest", -- 请求通关详情
        RequestUnlockArea = "UnlockAreaRequest", -- 请求解锁战区

        RequestTeamRankData = "TeamRankDataRequest", -- 请求队伍排行
    }

    ----------------------------Team start--------------------------

    --监听UI界面打开事件
    function XArenaManager.Init()
        CsXGameEventManager.Instance:RegisterEvent(CS.XEventId.EVENT_UI_ENABLE, function(evt, ui, ...)
            XArenaManager.OpenArenaActivityResult(ui[0].UiData.UiName)
        end)
    end

    -- 打开竞技奖励界面
    function XArenaManager.OpenArenaActivityResult(panelName)
        if ArenaActivityResultData == nil then
            return
        end

        if panelName ~= "UiArena" then
            return
        end

        XLuaUiManager.Open("UiArenaActivityResult", ArenaActivityResultData, function()
            ArenaActivityResultData = nil
        end)
    end

    -- 检测竞技奖励界面
    function XArenaManager.CheckOpenArenaActivityResult()
        if ArenaActivityResultData == nil then
            return false
        end

        XLuaUiManager.Open("UiArenaActivityResult", ArenaActivityResultData, function()
            ArenaActivityResultData = nil
        end, function()
            XEventManager.DispatchEvent(XEventId.EVENT_ARENA_RESULT_CLOSE)
        end)

        return true
    end

    -- 处理竞技活动结果
    function XArenaManager.HandleArenaActivityResult(data)
        ArenaLevel = data.NewArenaLevel
        ArenaActivityResultData = data
    end

    -- 获取我队队伍Id
    function XArenaManager.GetTeamId()
        if not TeamInfo then
            return 0
        end

        return TeamInfo.TeamId or 0
    end

    -- 检测指定玩家是否是我队队长
    function XArenaManager.CheckPlayerIsCaptain(Id)
        if not Id then
            return false
        end

        if Id == 0 then
            return false
        end

        if not TeamInfo then
            return false
        end

        local captain = TeamInfo.Captain or 0
        return captain == Id
    end

    -- 检测自己是否是我队队长
    function XArenaManager.CheckSelfIsCaptain()
        return XArenaManager.CheckPlayerIsCaptain(XPlayer.Id)
    end

    -- 获取我的队伍成员列表
    function XArenaManager.GetMyTeamMemberList()
        if not TeamInfo then
            return {}
        end

        return TeamInfo.ShowList
    end

    -- 获取大厅玩家列表
    function XArenaManager.GetHallPlayerList()
        local list = {}

        if HallPlayerMap then
            for _, v in pairs(HallPlayerMap) do
                table.insert(list, v)
            end
        end

        return list
    end

    -- 获取大厅队伍列表
    function XArenaManager.GetHallTeamList()
        local list = {}

        if HallTeamMap then
            for _, v in pairs(HallTeamMap) do
                table.insert(list, v)
            end
        end

        return list
    end

    -- 获取申请数据列表
    function XArenaManager.GetApplyDataList()
        local teamId = XArenaManager.GetTeamId()
        local list = {}
        if teamId > 0 then
            if XArenaManager.CheckSelfIsCaptain() then
                for _, v in pairs(ApplyMap) do
                    table.insert(list, v)
                end
                return list
            else
                return list
            end
        else
            for _, v in pairs(InviteMap) do
                table.insert(list, v)
            end
            return list
        end
    end

    -- 检测是否有申请数据
    function XArenaManager.CheckHaveApplyData()
        local list = XArenaManager.GetApplyDataList()
        return #list > 0 or HaveToRequestApplyData > 0
    end

    -- 获取竞技好友列表
    function XArenaManager.GetArenaFriendList()
        local list = {}

        if FriendMap then
            for _, v in pairs(FriendMap) do
                table.insert(list, v)
            end
        end

        table.sort(list, function(a, b)
            local isSameIdA = ChallengeId == a.ChallengeId
            local isSameIdB = ChallengeId == b.ChallengeId
            if isSameIdA ~= isSameIdB then 
                return isSameIdA
            end

            local isEnterFightA = a.ChallengeId > 0
            local isEnterFightB = b.ChallengeId > 0
            if isEnterFightA ~= isEnterFightB then 
                return isEnterFightB
            end

            return a.Info.Id > b.Info.Id
        end)

        return list
    end

    -- 处理被队长踢出队伍
    function XArenaManager.HandleIsKickedByCaptain()
        TeamInfo = {}
        XEventManager.DispatchEvent(XEventId.EVENT_ARENA_TEAM_CHANGE)
    end

    -- 收到新申请信息
    function XArenaManager.HandleNewApplyData(data)
        HaveToRequestApplyData = 1
        XEventManager.DispatchEvent(XEventId.EVENT_ARENA_TEAM_NEW_APPLY_ENTER)
    end

    -- 处理队伍信息
    function XArenaManager.HandleTeamInfo(info)
        if (not TeamInfo or not TeamInfo.TeamId) and info.TeamId > 0 and HaveToRequestApplyData > 0 then
            HaveToRequestApplyData = 0
        end

        TeamInfo = info

        XEventManager.DispatchEvent(XEventId.EVENT_ARENA_TEAM_CHANGE)
    end

    -- 处理大厅队伍列表
    function XArenaManager.HandleHallTeamList(data)
        HallTeamMap = {}
        for _, v in ipairs(data.TeamList) do
            HallTeamMap[v.Info.TeamId] = v
        end
    end

    -- 处理大厅玩家列表
    function XArenaManager.HandleHallPlayerList(data)
        HallPlayerMap = {}
        for _, v in ipairs(data.PlayerList) do
            HallPlayerMap[v.Info.Id] = v
        end
    end

    -- 处理好友列表
    function XArenaManager.HandleFriendList(data)
        FriendMap = {}
        if data and data.FriendPlayerList then
            for _, v in ipairs(data.FriendPlayerList) do
                --TODO 筛选相同段位的
                FriendMap[v.Info.Id] = v
            end
        end
    end

    -- 处理邀请申请信息列表
    function XArenaManager.HandleApplyData(data)
        if not data then
            return
        end

        ApplyMap = {}
        InviteMap = {}

        local map = {}
        for _, v in ipairs(data.ApplyList) do
            map[v.Id] = v
        end

        if data.ApplyType == APPLY_TYPE.SINGLE then
            --队伍邀请信息列表
            InviteMap = map
        elseif data.ApplyType == APPLY_TYPE.TEAM then
            --玩家请求消息列表
            ApplyMap = map
        end

        XEventManager.DispatchEvent(XEventId.EVENT_ARENA_TEAM_RECEIVE_APPLY_DATA)
    end

    -- 检查是否在组队期状态
    function XArenaManager.CheckInTeamState()
        return ActivityStatus == XArenaActivityStatus.Rest
    end

    -- 获取我的队伍信息
    function XArenaManager.RequestMyTeamInfo(cb)
        if ActivityStatus ~= XArenaActivityStatus.Rest then
            XUiManager.TipText("ArenaActivityStatusWrong")
            return
        end

        if TeamInfo then
            if cb then
                cb()
            end
            return
        end

        XNetwork.Call(ArenaRequest.RequestMyTeamInfo, nil, function(res)
            if res.Code ~= XCode.Success then
                XUiManager.TipCode(res.Code)
                return
            end

            XArenaManager.HandleTeamInfo(res.MyTeam)

            if cb then
                cb()
            end
        end)
    end

    -- 请求大厅队伍列表
    function XArenaManager.RequestHallTeamList(cb)
        if ActivityStatus ~= XArenaActivityStatus.Rest then
            XUiManager.TipText("ArenaActivityStatusWrong")
            return
        end

        -- 请求间隔保护
        local now = XTime.GetServerNowTimestamp()
        if LastHallTeamListTime + SYNC_HALL_SECOND >= now then
            if cb then
                cb()
            end
            return
        end
        LastHallTeamListTime = now

        --TODO 受刷新时间限制
        XNetwork.Call(ArenaRequest.RequestHallTeamList, nil, function(res)
            if res.Code ~= XCode.Success then
                XUiManager.TipCode(res.Code)
                return
            end

            XArenaManager.HandleHallTeamList(res.HallTeamData)

            if cb then
                cb()
            end
        end)
    end

    -- 请求大厅玩家列表
    function XArenaManager.RequestHallPlayerList(cb)
        if ActivityStatus ~= XArenaActivityStatus.Rest then
            XUiManager.TipText("ArenaActivityStatusWrong")
            return
        end

        -- 请求间隔保护
        local now = XTime.GetServerNowTimestamp()
        if LastHallPlayerListTime + SYNC_HALL_SECOND >= now then
            if cb then
                cb()
            end
            return
        end
        LastHallPlayerListTime = now

        --TODO 受刷新时间限制
        XNetwork.Call(ArenaRequest.RequestHallPlayerList, nil, function(res)
            if res.Code ~= XCode.Success then
                XUiManager.TipCode(res.Code)
                return
            end

            XArenaManager.HandleHallPlayerList(res.HallPlayerData)

            if cb then
                cb()
            end
        end)
    end

    -- 获取邀请申请信息列表
    function XArenaManager.RequestApplyData(cb)
        if ActivityStatus ~= XArenaActivityStatus.Rest then
            XUiManager.TipText("ArenaActivityStatusWrong")
            return
        end

        --TODO 受刷新时间限制
        XNetwork.Call(ArenaRequest.RequestApplyData, nil, function(res)
            HaveToRequestApplyData = 0
            if res.Code ~= XCode.Success then
                XUiManager.TipCode(res.Code)
                return
            end

            XArenaManager.HandleApplyData(res.ApplyData)

            if cb then
                cb()
            end
        end)
    end

    -- 获取所有好友竞技信息
    function XArenaManager.RequestFriendArenaInfo(cb)
        if ActivityStatus ~= XArenaActivityStatus.Rest then
            XUiManager.TipText("ArenaActivityStatusWrong")
            return
        end

        -- 请求间隔保护
        local now = XTime.GetServerNowTimestamp()
        if LastFriendPlayerTime + SYNC_OTHER_SECOND >= now then
            if cb then
                cb()
            end
            return
        end
        LastFriendPlayerTime = now

        XNetwork.Call(ArenaRequest.RequestFriendArenaInfo, nil, function(res)
            if res.Code ~= XCode.Success then
                XUiManager.TipCode(res.Code)
                return
            end

            XArenaManager.HandleFriendList(res.FriendPlayerData)

            if cb then
                cb()
            end
        end)
    end

    -- 请求创建队伍
    function XArenaManager.RequestCreateTeam(cb)
        if ActivityStatus ~= XArenaActivityStatus.Rest then
            XUiManager.TipText("ArenaActivityStatusWrong")
            return
        end

        XNetwork.Call(ArenaRequest.RequestCreateTeam, nil, function(res)
            if res.Code ~= XCode.Success then
                XUiManager.TipCode(res.Code)
                return
            end

            if cb then
                cb()
            end
        end)
    end

    -- 申请入队
    function XArenaManager.RequestApplyTeam(teamId, cb)
        if ActivityStatus ~= XArenaActivityStatus.Rest then
            XUiManager.TipText("ArenaActivityStatusWrong")
            return
        end

        XNetwork.Call(ArenaRequest.RequestApplyTeam, { TeamId = teamId }, function(res)
            if res.Code ~= XCode.Success then
                XUiManager.TipCode(res.Code)
                return
            end

            local info = HallTeamMap[teamId]
            if info then
                info.Apply = 1
            end

            if cb then
                cb()
            end
        end)
    end

    -- 拒绝申请
    function XArenaManager.RequestRefuseApply(targetId, cb)
        if ActivityStatus ~= XArenaActivityStatus.Rest then
            XUiManager.TipText("ArenaActivityStatusWrong")
            return
        end

        XNetwork.Call(ArenaRequest.RequestRefuseApply, { TargetId = targetId }, function(res)
            if res.Code ~= XCode.Success then
                XUiManager.TipCode(res.Code)
                return
            end

            ApplyMap[targetId] = nil
            XEventManager.DispatchEvent(XEventId.EVENT_ARENA_TEAM_APPLY_CHANGE)

            if cb then
                cb()
            end
        end)
    end

    -- 接受申请
    function XArenaManager.RequestAcceptApply(targetId, cb)
        if ActivityStatus ~= XArenaActivityStatus.Rest then
            XUiManager.TipText("ArenaActivityStatusWrong")
            return
        end

        XNetwork.Call(ArenaRequest.RequestAcceptApply, { TargetId = targetId }, function(res)
            if res.Code ~= XCode.Success then
                XUiManager.TipCode(res.Code)
                return
            end

            ApplyMap[targetId] = nil
            XEventManager.DispatchEvent(XEventId.EVENT_ARENA_TEAM_APPLY_CHANGE)

            if cb then
                cb()
            end
        end)
    end

    -- 请求离队
    function XArenaManager.RequestLeaveTeam(cb)
        if ActivityStatus ~= XArenaActivityStatus.Rest then
            XUiManager.TipText("ArenaActivityStatusWrong")
            return
        end

        XNetwork.Call(ArenaRequest.RequestLeaveTeam, nil, function(res)
            if res.Code ~= XCode.Success then
                XUiManager.TipCode(res.Code)
                return
            end

            TeamInfo = {}
            if HaveToRequestApplyData > 0 then
                HaveToRequestApplyData = 0
            end

            XEventManager.DispatchEvent(XEventId.EVENT_ARENA_TEAM_INITIATIVE_LEAVE)

            if cb then
                cb()
            end
        end)
    end

    -- 踢除队员
    function XArenaManager.RequestKickTeam(targetId, cb)
        if ActivityStatus ~= XArenaActivityStatus.Rest then
            XUiManager.TipText("ArenaActivityStatusWrong")
            return
        end

        XNetwork.Call(ArenaRequest.RequestKickTeam, { TargetId = targetId }, function(res)
            if res.Code ~= XCode.Success then
                XUiManager.TipCode(res.Code)
                return
            end

            if cb then
                cb()
            end
        end)
    end

    -- 邀请玩家入队
    function XArenaManager.RequestInvitePlayer(targetId, cb)
        if ActivityStatus ~= XArenaActivityStatus.Rest then
            XUiManager.TipText("ArenaActivityStatusWrong")
            return
        end

        XNetwork.Call(ArenaRequest.RequestInvitePlayer, { TargetId = targetId }, function(res)
            if res.Code ~= XCode.Success then
                XUiManager.TipCode(res.Code)
                return
            end

            local info = HallPlayerMap[targetId]
            if info then
                info.Invite = 1
            end

            local friend = FriendMap[targetId]
            if friend then
                friend.Invite = 1
            end

            if cb then
                cb()
            end
        end)
    end

    -- 拒绝邀请
    function XArenaManager.RequestRefuseInvite(targetId, cb)
        if ActivityStatus ~= XArenaActivityStatus.Rest then
            XUiManager.TipText("ArenaActivityStatusWrong")
            return
        end

        XNetwork.Call(ArenaRequest.RequestRefuseInvite, { TargetId = targetId }, function(res)
            if res.Code ~= XCode.Success then
                XUiManager.TipCode(res.Code)
                return
            end

            InviteMap[targetId] = nil
            XEventManager.DispatchEvent(XEventId.EVENT_ARENA_TEAM_APPLY_CHANGE)

            if cb then
                cb()
            end
        end)
    end

    -- 接受邀请
    function XArenaManager.RequestAcceptInvite(targetId, cb)
        if ActivityStatus ~= XArenaActivityStatus.Rest then
            XUiManager.TipText("ArenaActivityStatusWrong")
            return
        end

        XNetwork.Call(ArenaRequest.RequestAcceptInvite, { TargetId = targetId }, function(res)
            if res.Code ~= XCode.Success then
                XUiManager.TipCode(res.Code)
                return
            end

            InviteMap[targetId] = nil
            XEventManager.DispatchEvent(XEventId.EVENT_ARENA_TEAM_APPLY_CHANGE)

            if cb then
                cb()
            end
        end)
    end
    ----------------------------Team end--------------------------

    ----------------------------Arena start--------------------------
    -- 获取活动状态
    function XArenaManager.GetArenaActivityStatus()
        return ActivityStatus
    end

    -- 获取进入下一阶段时间戳
    function XArenaManager.GetEnterNextStatusTime()
        return CountDownTime
    end

    -- 获取功能开启时间
    local GetTimeStr = function(time)
        if not time or time <= 0 then
            return ""
        end
        local str = XTime.TimestampToGameDateTimeString(time, "yy/MM/dd  HH:mm")
        return str
    end

    -- 获取组队期开始时间
    function XArenaManager.GetTeamStartTime()
        return GetTimeStr(TeamStartTime)
    end

    -- 获取战斗期开始时间
    function XArenaManager.GetFightStartTime()
        return GetTimeStr(FightStartTime)
    end

    -- 获取结算期开始时间
    function XArenaManager.GetResultStartTime()
        return GetTimeStr(ResultStartTime)
    end

    -- 获取当前的竞技段位
    function XArenaManager.GetCurArenaLevel()
        return ArenaLevel
    end

    -- 获取波动指数
    function XArenaManager.GetWaveRate()
        return WaveRate
    end

    -- 获取当前挑战id
    function XArenaManager.GetCurChallengeId()
        return ChallengeId
    end

    -- 获取当前挑战配置
    function XArenaManager.GetCurChallengeCfg()
        return XArenaConfigs.GetChallengeArenaCfgById(ChallengeId)
    end

    -- 获取竞技挑战最高等级
    function XArenaManager.IsMaxArenaLevel(level)
        return level >= XArenaConfigs.GetChallengeMaxArenaLevel(ChallengeId)
    end

    -- 获取玩家竞技信息
    function XArenaManager.GetPlayerArenaInfo()
        for i, info in ipairs(TeamResultList) do
            if info.Id == XPlayer.Id then
                return info
            end
        end
    end

    -- 获取玩家竞技个人排名
    function XArenaManager.GetPlayerArenaRankAndRegion()
        local rank = 0
        local point = 0
        local region = XArenaPlayerRankRegion.DownRegion

        for i, info in ipairs(PlayerResultRankList) do
            if info.Id == XPlayer.Id then
                rank = i
                point = info.Point
            end
        end

        if point == 0 then
            if ArenaLevel <= 1 then
                region = XArenaPlayerRankRegion.KeepRegion
            end
            return rank, region
        end

        local challengeCfg = XArenaConfigs.GetChallengeArenaCfgById(ChallengeId)
        if challengeCfg then
            if rank <= challengeCfg.DanUpRank then
                region = XArenaPlayerRankRegion.UpRegion
            elseif rank > challengeCfg.DanUpRank and rank <= challengeCfg.DanKeepRank then
                region = XArenaPlayerRankRegion.KeepRegion                
            end
        end

        return rank, region
    end

    -- 获取队员竞技信息列表
    function XArenaManager.GetPlayerArenaTeamMemberInfo()
        local list = {}
        for i, info in ipairs(TeamResultList) do
            if info.Id ~= XPlayer.Id then
                table.insert(list, info)
            end
        end

        return list
    end

    -- 获取队伍竞技总分
    function XArenaManager.GetArenaTeamTotalPoint()
        local point = 0
        for i, info in ipairs(TeamResultList) do
            point = point + info.Point
        end

        return point
    end

    -- 获取玩家竞技排行数据
    function XArenaManager.GetPlayerArenaRankList()
        local challengeCfg = XArenaConfigs.GetChallengeArenaCfgById(ChallengeId)
        if not challengeCfg then
            return nil
        end

        local rankData = {}
        rankData.UpList = {}
        rankData.KeepList = {}
        rankData.DownList = {}

        for i, info in ipairs(PlayerResultRankList) do
            if info.Point > 0 then
                if (i - challengeCfg.DanUpRank <= 0) then
                    table.insert(rankData.UpList, info)
                elseif (i - challengeCfg.DanKeepRank <= 0) then
                    table.insert(rankData.KeepList, info)
                else
                    table.insert(rankData.DownList, info)
                end
            else
                if challengeCfg.ArenaLv <= 1 then
                    table.insert(rankData.KeepList, info)
                else
                    table.insert(rankData.DownList, info)
                end
            end
        end

        return rankData
    end

    -- 获取队伍排行榜的挑战配置
    function XArenaManager.GetTeamRankChallengeCfg()
        if TeamRankChallengeId <= 0 then
            return nil
        end

        return XArenaConfigs.GetChallengeArenaCfgById(TeamRankChallengeId)
    end

    -- 获取队伍排行统计时间
    function XArenaManager.GetArenaTeamRankTime()
        if not TeamRankData.BeginTime or not TeamRankData.BeginTime then
            return ""
        end

        local begin_time = XTime.TimestampToGameDateTimeString(TeamRankData.BeginTime, "yy.MM.dd")
        local end_time = XTime.TimestampToGameDateTimeString(TeamRankData.EndTime, "yy.MM.dd")
        local desc = CS.XTextManager.GetText("ArenaRankDesc")
        return begin_time .. "-" .. end_time .. desc
    end

    -- 获取竞技队伍排行列表
    function XArenaManager.GetTeamRankList()
        return TeamRankData.TeamRowList
    end

    -- 获取自己队伍排行百分比
    function XArenaManager.GetMyTeamRankRate()
        local rankRate = TeamRankData.RankRate or 0
        return rankRate / 10000
    end

    -- 获取竞技我的队伍排行及数据
    function XArenaManager.GetMyTeamRankAndData()
        return TeamRankData.MyRank, TeamRankData.TotalRank, TeamRankData.MyTeamInfo
    end

    -- 获取剩余解锁战区次数
    function XArenaManager.GetUnlockArenaAreaCount()
        return UnlockCount
    end

    -- 获取玩家战区总分
    function XArenaManager.GetArenaAreaTotalPoint()
        return TotalPoint
    end

    -- 通过战区Id获取战区信息
    function XArenaManager.GetArenaAreaDataByAreaId(areaId)
        return AreaDatas[areaId]
    end

    -- 通过战区Id获取战区当前关卡进度
    function XArenaManager.GetCurStageIndexByAreaId(areaId)
        local stageInfos = AreaDatas[areaId].StageInfos
        if not stageInfos then
            return 1
        end

        if #stageInfos >= XArenaConfigs.GetTheMaxStageCountOfArenaArea() then
            return #stageInfos
        else
            return #stageInfos + 1
        end
    end

    -- 通过战区Id、关卡Id获取关卡积分
    function XArenaManager.GetArenaStageScore(areaId, stageId)
        local stageInfos = AreaDatas[areaId].StageInfos
        if not stageInfos then
            return 0
        end

        for _, v in ipairs(stageInfos) do
            if v.StageId == stageId then
                return v.Point
            end
        end
        return 0
    end

    -- 通过战区Id、关卡Id修改关卡积分
    function XArenaManager.ChangeArenaStageScore(areaId, stageId, score)
        local stageInfos = AreaDatas[areaId].StageInfos
        if not stageInfos then
            return
        end

        for _, v in ipairs(stageInfos) do
            if v.StageId == stageId then
                v.Point = score
            end
        end
    end

    -- 设置正在战斗的竞技区域
    function XArenaManager.SetEnterAreaStageInfo(areaId, index)
        EnterAreaStageInfo = {}
        EnterAreaStageInfo.AreaId = areaId
        EnterAreaStageInfo.StageIndex = index

        local stageId = XArenaConfigs.GetArenaAreaStageCfgByAreaId(areaId).StageId[index]

        local chaperName, stageName = XArenaConfigs.GetChapterAndStageName(areaId, stageId)
        EnterAreaStageInfo.ChapterName = chaperName
        EnterAreaStageInfo.StageName = stageName
    end

    -- 获取竞技结算分数配置
    function XArenaManager.GetMarkCfg()
        if not EnterAreaStageInfo.AreaId or not EnterAreaStageInfo.StageIndex then
            return nil
        end

        local stageCfg = XArenaConfigs.GetArenaAreaStageCfgByAreaId(EnterAreaStageInfo.AreaId)
        if not stageCfg then
            return nil
        end

        local markCfg = XArenaConfigs.GetMarkCfgById(stageCfg.MarkId[EnterAreaStageInfo.StageIndex])
        return markCfg
    end

    -- 状态改变直接回到主界面
    local JudgeGotoMain = function()
        if not XLuaUiManager.IsUiLoad("UiArena") then
            return
        end

        if ActivityStatus == XArenaActivityStatus.Loading or ActivityStatus == XArenaActivityStatus.Default then
            return
        end

        -- 如果玩家在竞技战斗中 先做缓存
        if CS.XFight.IsRunning or XLuaUiManager.IsUiLoad("UiLoading") then
            ArenaStatusInFightChangeCache = true
            return
        end

        -- 如果玩家在好友宿舍中 退出宿舍
        if XLuaUiManager.IsUiLoad("UiDormSecond") then
            XHomeSceneManager.LeaveScene()
            XEventManager.DispatchEvent(XEventId.EVENT_DORM_CLOSE_COMPONET)
        end

        XUiManager.TipText("ArenaActivityStatusChange")
        XLuaUiManager.RunMain()
    end

    -- 竞技战斗结束后判断是否跳到主界面
    function XArenaManager.JudgeGotoMainWhenFightOver()
        if not XLuaUiManager.IsUiLoad("UiArena") then
            return false
        end

        if not ArenaStatusInFightChangeCache then
            return false
        end

        ArenaStatusInFightChangeCache = false
        XUiManager.TipText("ArenaActivityStatusChange")
        XLuaUiManager.RunMain()

        return true
    end

     -- 是否战斗中改变了状态
     function XArenaManager.IsChangeStatusInFight()
        return ArenaStatusInFightChangeCache
    end

    -- 处理竞技活动相关数据
    function XArenaManager.HandleArenaActivity(data)
        -- 清空数据
        HallTeamMap = {}
        HallPlayerMap = {}
        FriendMap = {}
        TeamInfo = nil
        ApplyMap = {}
        InviteMap = {}
        HaveToRequestApplyData = -1

        ActivityNo = 0
        ActivityStatus = XArenaActivityStatus.Default
        CountDownTime = 0
        TeamStartTime = 0
        FightStartTime = 0
        ResultStartTime = 0
        WaveRate = 0
        PlayerResultRankList = {}
        TeamRankChallengeId = 0
        TeamRankData = {}
        TeamResultList = {}
        AreaIdToStageDetailList = {}
        ChallengeId = 0
        ArenaLevel = 0
        UnlockCount = 0
        TotalPoint = 0
        AreaDatas = {}
        EnterAreaStageInfo = {}

        -- 重设数据
        ActivityNo = data.ActivityNo
        ChallengeId = data.ChallengeId
        ActivityStatus = data.Status
        CountDownTime = data.NextStatusTime
        TeamStartTime = data.TeamTime
        FightStartTime = data.FightTime
        ResultStartTime = data.ResultTime
        ArenaLevel = data.ArenaLevel
        IsJoinActivity = data.JoinActivity == 1 -- 是否参加过当前活动
        UnlockCount = data.UnlockCount

        if ActivityStatus == XArenaActivityStatus.Over then
            IsJoinActivity = false
        end

        local remainTime = CountDownTime - XTime.GetServerNowTimestamp()
        XCountDown.CreateTimer(XArenaConfigs.ArenaTimerName, remainTime)

        JudgeGotoMain()
    end

    -- 获取正在战斗的竞技区域
    function XArenaManager.GetEnterAreaStageInfo()
        return EnterAreaStageInfo
    end

    -- 获取是否参加过当前活动
    function XArenaManager.GetIsJoinActivity()
        return IsJoinActivity
    end

    -- 报名参加竞技活动
    function XArenaManager.RequestSignUpArena(cb)
        if ActivityStatus == XArenaActivityStatus.Over then
            if cb then
                cb()
            end
            return
        end

        if IsJoinActivity then
            if cb then
                cb()
            end
            return
        end

        XNetwork.Call(ArenaRequest.RequestSignUpArena, nil, function(res)
            if res.Code ~= XCode.Success then
                XUiManager.TipCode(res.Code)
                return
            end

            IsJoinActivity = true
            if res.ChallengeId then
                ChallengeId = res.ChallengeId
            end

            if cb then
                cb()
            end
        end)
    end

    -- 请求主页面成员信息
    function XArenaManager.RequestGroupMember(cb)
        if ActivityStatus ~= XArenaActivityStatus.Fight then
            XUiManager.TipText("ArenaActivityStatusWrong")
            return
        end

        XNetwork.Call(ArenaRequest.RequestGroupMember, nil, function(res)
            if res.Code ~= XCode.Success then
                XUiManager.TipCode(res.Code)
                return
            end

            WaveRate = res.WaveRate
            PlayerResultRankList = res.GroupPlayerList
            TeamResultList = res.TeamPlayerList

            XEventManager.DispatchEvent(XEventId.EVENT_ARENA_MAIN_INFO)

            if cb then
                cb()
            end
        end)
    end

    -- 请求区域信息
    function XArenaManager.RequestAreaData(cb)
        if ActivityStatus ~= XArenaActivityStatus.Fight then
            XUiManager.TipText("ArenaActivityStatusWrong")
            return
        end

        XNetwork.Call(ArenaRequest.RequestAreaData, nil, function(res)
            if res.Code ~= XCode.Success then
                XUiManager.TipCode(res.Code)
                return
            end

            TotalPoint = res.TotalPoint
            for i, areaShowData in ipairs(res.AreaList) do
                AreaDatas[areaShowData.AreaId] = areaShowData
            end
            XEventManager.DispatchEvent(XEventId.EVENT_ARENA_REFRESH_AREA_INFO)
            CsXGameEventManager.Instance:Notify(XEventId.EVENT_ARENA_REFRESH_AREA_INFO)

            if cb then
                cb()
            end
        end)
    end

    -- 请求通关详情
    function XArenaManager.RequestStagePassDetail(areaId, cb)
        if ActivityStatus ~= XArenaActivityStatus.Fight then
            XUiManager.TipText("ArenaActivityStatusWrong")
            return
        end

        XNetwork.Call(ArenaRequest.RequestStagePassDetail, { AreaId = areaId }, function(res)
            if res.Code ~= XCode.Success then
                XUiManager.TipCode(res.Code)
                return
            end

            local detailMap = {}
            for i, data in ipairs(res.StageDetailList) do
                detailMap[data.StageId] = data
            end
            AreaIdToStageDetailList[areaId] = detailMap

            if cb then
                cb(detailMap)
            end
        end)
    end

    -- 请求解锁战区
    function XArenaManager.RequestUnlockArea(areaId, cb)
        if ActivityStatus ~= XArenaActivityStatus.Fight then
            XUiManager.TipText("ArenaActivityStatusWrong")
            return
        end

        if UnlockCount <= 0 then
            XUiManager.TipError(CS.XTextManager.GetText("ArenaActivityUnlockCountNotEnough"))
            return
        end

        XNetwork.Call(ArenaRequest.RequestUnlockArea, { AreaId = areaId }, function(res)
            if res.Code ~= XCode.Success then
                XUiManager.TipCode(res.Code)
                return
            end

            UnlockCount = UnlockCount - 1
            local data = AreaDatas[areaId]
            data.Lock = 0

            XEventManager.DispatchEvent(XEventId.EVENT_ARENA_UNLOCK_AREA)
            CsXGameEventManager.Instance:Notify(XEventId.EVENT_ARENA_UNLOCK_AREA)

            if cb then
                cb()
            end
        end)
    end

    -- 请求队伍排行
    function XArenaManager.RequestTeamRankData(cb)
        -- 请求间隔保护
        local now = XTime.GetServerNowTimestamp()
        if LastSyncRankListTime + SYNC_RANK_LIST_SECOND >= now and TeamRankChallengeId > 0 then
            if cb then
                cb()
            end
            return
        end
        LastSyncRankListTime = now

        XNetwork.Call(ArenaRequest.RequestTeamRankData, nil, function(res)
            if res.Code ~= XCode.Success then
                XUiManager.TipCode(res.Code)
                return
            end

            TeamRankChallengeId = res.ChallengeId
            TeamRankData = res.RankData

            XEventManager.DispatchEvent(XEventId.EVENT_ARENA_REFRESH_TEAM_RANK_INFO)
            CsXGameEventManager.Instance:Notify(XEventId.EVENT_ARENA_REFRESH_TEAM_RANK_INFO)

            if cb then
                cb()
            end
        end)
    end

    function XArenaManager.InitStageInfo()
        local arenaStageInfo = XArenaConfigs.GetArenaStageCfg()
        for _, stageList in ipairs(arenaStageInfo) do
            for _, v in ipairs(stageList.StageId) do
                local stageInfo = XDataCenter.FubenManager.GetStageInfo(v)
                stageInfo.Type = XDataCenter.FubenManager.StageType.Arena
            end
        end
    end

    XArenaManager.Init()
    ----------------------------Arena start--------------------------

    return XArenaManager
end

XRpc.NotifyArenaActivity = function(data)
    XDataCenter.ArenaManager.HandleArenaActivity(data)
end

XRpc.NotifyMyTeam = function(data)
    XDataCenter.ArenaManager.HandleTeamInfo(data.MyTeam)
end

XRpc.NotifyPlayerKick = function(data)
    XDataCenter.ArenaManager.HandleIsKickedByCaptain()
end

XRpc.NotifyNewApply = function(data)
    XDataCenter.ArenaManager.HandleNewApplyData(data)
end

XRpc.ActivityResultNotify = function(data)
    XDataCenter.ArenaManager.HandleArenaActivityResult(data)
end