--------------------------------
-- 文件名       :   jjcNewLadderDB.lua
-- 文件说明     :   天梯赛-DB数据
-- 创建时间     :   2025/05/06
-- 创建人       :   FC
--------------------------------

local LuaMongo = _G.lua_mongo
local Config = require("Config")
local DB = require("common.DB")
local Util = require("common.Util")
local CommonDB = require("common.CommonDB")
local CombatVideo = require("combat.CombatVideo")
local CreateRole = require("role.CreateRole")
local WarZoneConf = require("excel.WarZone")
local JjcExcel = require("excel.jjc")
local JjcNewLadderDefine = require("jjcnewladder.jjcNewLadderDefine")
local Timer = require("core.Timer")
local JjcNewLadderMiddle = require("jjcnewladder.jjcNewLadderMiddle")
local ObjHuman = require("core.ObjHuman")
local Log = require("common.Log")


local nServerOffSet = 810538  -- 配置中服务器ID偏移量

JJCNEWLADDERDB_PLAYER_RANK = {}     -- 天梯赛真人对应排名
JJCNEWLADDERDB_ROBOT_RANK = {}      -- 机器人对应排名信息
JJCNEWLADDERDB_ALL_RANK = {}        -- 天梯赛排行榜信息

UUID_2_RANK = {}

local JJCLADDER_RANDNUM = 50                 -- 随机次数，防止找到重复的
local JJCLADDER_FINDRIVALNUM = 5             -- 匹配的对手
local JJCLADDER_FINDBIGNUM = 4               -- 匹配大于当前排位人数
local JJCLADDER_SPECIALRANK = 5              -- 特殊处理的前五名

local Jjc_QueryByUuid = {uuid = nil}        -- DB查询数据

-------------------------------- 以下是战区归宿的第一个服操作 ---------------------------
-- 写日志
local function JjcNewLadderDB_WriteLog(szText)
    Log.write(Log.LOGID_OSS_JJCNEWLADDER, szText)
end

-- 获取战区服务器ID
function JjcNewLadderDB_ConfServerID2TrueServerID(nServerIDConf)
    return nServerIDConf + nServerOffSet - 1
end

-- 获取战区配置服务器ID
function JjcNewLadderDB_TrueServerID2ConfServerID(nServerID)
    return nServerID - nServerOffSet + 1
end

-- 判断是否是战区所属的第一个服
local function JjcNewLadderDB_IsFirstServer(nServerID)
    local nServerIDConf = JjcNewLadderDB_TrueServerID2ConfServerID(nServerID)

    local bRet = false
    for _, v in ipairs(WarZoneConf.group) do
        if v.nMinServerID == nServerIDConf then
            bRet = true
            break
        end

        -- 大于了，没必要找直接返回
        if v.nMinServerID > nServerIDConf then
            break
        end
    end

    return bRet
end

-- 设置结束时间
function JjcNewLadderDB_SetEndTime()
    local nNowTime = os.time()
    local tDate = os.date("*t",nNowTime)
    if tDate.wday >= JjcNewLadderDefine.JJC_NEWLADDER_OPENDAY and JjcNewLadderDefine.JJC_NEWLADDER_ENDDAY >= tDate.wday then
        local nDiffDay = JjcNewLadderDefine.JJC_NEWLADDER_ENDDAY - tDate.wday
        local nEndTime = nNowTime + nDiffDay * 86400
        local tEndDate = os.date("*t",nEndTime)
        tEndDate.hour = 23
        tEndDate.min = 0
        tEndDate.sec = 0
        nEndTime = os.time(tEndDate)
        CommonDB.SetJjcLadderEndTime(nEndTime)
    
        print("[JjcNewLadderDB_SetEndTime] 设置了活动结束时间 nEndTime = "..nEndTime)
        JjcNewLadderDB_WriteLog("[JjcNewLadderDB_SetEndTime] 设置活动结束时间 nEndTime = "..nEndTime)
    end
end

-- 移除对应排名中的数据
local function JjcNewLadderDB_RemoveCache(uuid)
    if 0 >= #JJCNEWLADDERDB_ALL_RANK then
        return
    end

    local nLen = #JJCNEWLADDERDB_ALL_RANK
    for i = nLen, 1, -1 do
        local tData = JJCNEWLADDERDB_ALL_RANK[i]
        if tData.uuid == uuid then
            print("[JjcNewLadderDB_RemoveCache] 移除缓存数据 uuid = "..uuid.." i = "..i)
            table.remove(JJCNEWLADDERDB_ALL_RANK, i)
        end
    end
end

-- 移除数据
local function JjcNewLadderDB_RemoveDB(uuid)
    if not uuid then return end
    Jjc_QueryByUuid.uuid = tostring(uuid)
	LuaMongo.remove(DB.db_jjcLadder, Jjc_QueryByUuid)
end

-- 更新数据
local function JjcNewLadderDB_UpdateData(tRankData)
	if not tRankData.uuid then return end
	Jjc_QueryByUuid.uuid = tRankData.uuid
	LuaMongo.update(DB.db_jjcLadder, Jjc_QueryByUuid, tRankData)
end

-- 插入数据
local function JjcNewLadderDB_InsertData(tRankData)
    LuaMongo.insert(DB.db_jjcLadder, tRankData)
end

-- 判断是否是NPC
local function JjcNewLadderDB_isNpc(tRankData)
	if tRankData.nPoint and tRankData.nMonsterOutID then
		return true
	end

    return false
end

local function JjcNewLadderDB_AddNpc(tNpcConfig, nID)
    local jjcData = {}
	local r = math.random(1, #tNpcConfig.monsterOutID)
	jjcData.monsterOutID = tNpcConfig.monsterOutID[r]
	jjcData.lv = 50
    jjcData.head = CreateRole.getRandomHead()
	jjcData.name = CreateRole.getRandomName()
	jjcData.body = CreateRole.getRandomBody()
	jjcData.identity = CreateRole.getFakeIdentityMax()
	jjcData.point = tNpcConfig.initPoint
	jjcData.zhandouli = math.random(tNpcConfig.zhandouli[1], tNpcConfig.zhandouli[2])
	jjcData.time = os.time()
    jjcData.uuid = tostring(nID)
    jjcData.nIsHuman = 0
    jjcData.nServerID = Config.SVR_INDEX
    jjcData.szServerName = Config.NEW_SVR_INDEX.."区"
    jjcData.nInFight = 0
    jjcData.nLastFightTime = 0
    jjcData.nRank = nID
	LuaMongo.insert(DB.db_jjcLadder, jjcData)
	JJCNEWLADDERDB_ALL_RANK[#JJCNEWLADDERDB_ALL_RANK + 1] = jjcData
	
	if #JJCNEWLADDERDB_ROBOT_RANK < JjcNewLadderDefine.JJC_NEWLADDER_ROBOT_NUM then
		JJCNEWLADDERDB_ROBOT_RANK[#JJCNEWLADDERDB_ROBOT_RANK + 1] = jjcData
	end
    print("[JjcNewLadderDB_AddNpc] 初始化机器人成功 nID = "..nID)
end

-- 初始化机器人数据
local function JjcNewLadderDB_InitRobot()
    if false == JjcNewLadderDB_IsFirstServer(Config.SVR_INDEX) then
        return
    end

    print("[JjcNewLadderDB_InitRobot] 初始化机器人数据开始")
    -- 生成NPC数据
    local nID = 1
    for _, npcConfig in ipairs(JjcExcel.skyladdernpc) do
        for i = 1, npcConfig.cnt do
            JjcNewLadderDB_AddNpc(npcConfig, nID)
            nID = nID + 1
            if nID > JjcNewLadderDefine.JJC_NEWLADDER_ROBOT_NUM then
                break
            end
        end
    end
end

local function JjcNewLadderDB_ownCmp(a, b)
    if a.nRank and b.nRank then
        return a.nRank < b.nRank
    end

	if a.point ~= b.point then
		return a.point > b.point
	end
	return a.time < b.time
end

-- 进行排序
local function JjcNewLadderDB_SortRank()
    if #JJCNEWLADDERDB_ALL_RANK > 1 then
        print("[JjcNewLadderDB_SortRank] 进行排序")
		table.sort(JJCNEWLADDERDB_ALL_RANK, JjcNewLadderDB_ownCmp)
	end

    UUID_2_RANK = {}
    local nLen = 0
	for rank = 1, #JJCNEWLADDERDB_ALL_RANK do
		local uuid = JJCNEWLADDERDB_ALL_RANK[rank].uuid
		UUID_2_RANK[uuid] = rank
	end
end

-- 战区第一个服清理数据
local function JjcNewLadderDB_FirstServerRest(nOperate)
    JJCNEWLADDERDB_PLAYER_RANK = {}
    JJCNEWLADDERDB_ROBOT_RANK = {}
    JJCNEWLADDERDB_ALL_RANK = {}
    UUID_2_RANK = {}
    LuaMongo.remove(DB.db_jjcLadder)

    JjcNewLadderDB_WriteLog("[JjcNewLadderDB_FirstServerRest] 清理数据完成")
    -- for i = 1, nLen, 1 do
    --     local tRankData = JJCNEWLADDERDB_ALL_RANK[i]
    --     if false == JjcNewLadderDB_isNpc(tRankData) then
    --         JjcNewLadderDB_RemoveDB(tRankData.uuid)
    --     end
    --     JJCNEWLADDERDB_ALL_RANK[i] = nil
    -- end

    -- 
    -- 初始化机器人
    if true == nOperate then
        print("[JjcNewLadderDB_FirstServerRest] 初始化机器人数据")
        JjcNewLadderDB_InitRobot()
    end

    -- 进行排序和映射
    JjcNewLadderDB_SortRank()

    JjcNewLadderDB_WriteLog("[JjcNewLadderDB_FirstServerRest] 生成机器人,重新排序完成")
end

-- 根据 uuid从db中取data
local function JjcNewLadderDB_GetDBDataByUid(uuid)
    -- MiddleRankQueryForData = {nRankType = 1, nRankSubType = 1, nServerKey = 1 ,uuid = 1}
   
    Jjc_QueryByUuid.uuid = tostring(uuid)

    local data = {}
    LuaMongo.find(DB.db_jjcLadder, Jjc_QueryByUuid)
    return LuaMongo.next(data) and data
end

-- 更新DB数据
local function JjcNewLadderDB_UpdateDBData(data)
    local oldData = JjcNewLadderDB_GetDBDataByUid(data.uuid)
    if oldData then
        print("[JjcNewLadderDB_UpdateDBData] 存在旧数据直接开始进行更新")

        Jjc_QueryByUuid.uuid = tostring(data.uuid)
        -- print("[JjcNewLadderDB_UpdateDBData] 更新DB数据\n")
        -- table.print_lua_table(Jjc_QueryByUuid)

        LuaMongo.update(DB.db_jjcLadder, Jjc_QueryByUuid, data)
        print("[JjcNewLadderDB_UpdateDBData] 存在旧数据进行更新完成")
    else
        print("[JjcNewLadderDB_UpdateDBData] 不存在旧数据直接开始进行插入")

        LuaMongo.insert(DB.db_jjcLadder, data)
        print("[JjcNewLadderDB_UpdateDBData] 不存在旧数据直接结束进行插入")
    end
end

-- 初始化数据
function JjcNewLadderDB_Init()
    if true == JjcNewLadderDB_IsFirstServer(Config.SVR_INDEX) then
        JjcNewLadderDB_FirstServerRest(true)
    end

    -- 清理录像
    CombatVideo.cleanJJCLadderVideo()
end

-- 判断是否为空
local function JjcNewLadderDB_isEmpty()
    LuaMongo.find(DB.db_jjcLadder)
	local data = {}
	if not LuaMongo.next(data) then    
		return true
	end

    return false
end

-- 加载数据
local function JjcNewLadderDB_LoadData()
    LuaMongo.find(DB.db_jjcLadder)
    while true do
    	local data = {}
    	if not LuaMongo.next(data) then    
    		break
    	end	

    	if data.point then
    		JJCNEWLADDERDB_ALL_RANK[#JJCNEWLADDERDB_ALL_RANK + 1] = data
        else
            print("[JjcNewLadderDB_LoadData] 居然存在没有积分的 数据 uuid = "..data.uuid)
    	end
    end

    print("[JjcNewLadderDB_LoadData] 加载数据完成，共加载 "..#JJCNEWLADDERDB_ALL_RANK)

    JjcNewLadderDB_WriteLog("[JjcNewLadderDB_LoadData] 加载数据完成，共加载 "..#JJCNEWLADDERDB_ALL_RANK)

    -- 加载完排序
    JjcNewLadderDB_SortRank()

    print("[JjcNewLadderDB_LoadData] 排序完成")

    for i = 1, #JJCNEWLADDERDB_ALL_RANK do
    	if #JJCNEWLADDERDB_ROBOT_RANK >= JjcNewLadderDefine.JJC_NEWLADDER_ROBOT_NUM then
    		break
    	end

    	local tRankData = JJCNEWLADDERDB_ALL_RANK[i]
    	if tRankData.nIsHuman == 1 then
			JJCNEWLADDERDB_ROBOT_RANK[#JJCNEWLADDERDB_ROBOT_RANK + 1] = tRankData   		
    	end
    end
end

-- 起服操作
function JjcNewLadderDB_initAfterStart()
    if _G.is_middle == true then 
        return
    end

    -- 检查时间
    local bReset = JjcNewLadderDB_CheckIsReset()
    if true == bReset then
        print("[JjcNewLadderDB_initAfterStart] 需要重置时间, 进行重置时间操作")
        -- 重置时间
        JjcNewLadderDB_SetEndTime()

        -- 是首个服
        if true == JjcNewLadderDB_IsFirstServer(Config.SVR_INDEX) then
            -- 直接重置
            JjcNewLadderDB_Init()
            print("[JjcNewLadderDB_initAfterStart] 重置DB数据结束")
            JjcNewLadderDB_WriteLog("[JjcNewLadderDB_initAfterStart] 战区所属服 重置DB数据结束 ")
        else
            -- 清理录像
            CombatVideo.cleanJJCLadderVideo()
            JjcNewLadderDB_WriteLog("[JjcNewLadderDB_initAfterStart] 战区 清理录像 ")
        end
    else
        local nNowTime = os.time()
        local nEndTime = CommonDB.GetJjcLadderEndTime()
        if nNowTime < nEndTime then
            if true == JjcNewLadderDB_IsFirstServer(Config.SVR_INDEX) then
                if true == JjcNewLadderDB_isEmpty() then
                    print("[JjcNewLadderDB_initAfterStart] 在活动时间内 DB数据为空进行初始化机器人数据")
        
                    JjcNewLadderDB_Init()
                else
                    print("[JjcNewLadderDB_initAfterStart] 在活动时间内 DB数据不为空进行加载DB数据")
        
                    JjcNewLadderDB_LoadData()
                end
            end
        else
            if true == JjcNewLadderDB_IsFirstServer(Config.SVR_INDEX) then
                if true == JjcNewLadderDB_isEmpty() then
                    JjcNewLadderDB_Init()
                    print("[JjcNewLadderDB_initAfterStart] 不在活动时间内 DB数据为空进行初始化机器人数据")
                else
                    JjcNewLadderDB_LoadData()
                    print("[JjcNewLadderDB_initAfterStart] 不在活动时间内,存在DB数据，只加载数据")
                end
            end
        end

    end
end

-- 定时操作
function JjcNewLadderDB_OnHourOpen()
    JjcNewLadderDB_Init()
end

-------------------------------- 战区归宿的第一个服操作结束 ---------------------------

-------------------------------- 内部调用函数 ---------------------------
-- 加入匹配数据
local function JjcNewLadderDB_AddRival(uuid, tChoseRankID)
    local nNowRank = UUID_2_RANK[uuid]
    local tRankData = JJCNEWLADDERDB_ALL_RANK[nNowRank]
    if not tRankData then
        return false
    end

    tRankData.tRival = {}

    for nRank, _ in pairs(tChoseRankID) do
        local tChoseRankData = JJCNEWLADDERDB_ALL_RANK[nRank]
        local uuidChose, nIsHuman = tChoseRankData.uuid, tChoseRankData.nIsHuman
        if not uuidChose or not nIsHuman then
            tRankData.tRival = {}
            return false
        end

        table.insert(tRankData.tRival, {uuid = uuidChose, nIsHuman = nIsHuman})
    end

    return true
end

function JjcNewLadderDB_CheckIsReset()
    local nNowTime = os.time()
    local nEndTime = CommonDB.GetJjcLadderEndTime()
    local tDate = os.date("*t",nNowTime)
    print("[JjcNewLadderDB_CheckIsReset] 进入重置检测 nNowTime = "..nNowTime.." nEndTime = "..nEndTime)

    if 0 >= nEndTime then
        if tDate.wday >= JjcNewLadderDefine.JJC_NEWLADDER_OPENDAY and JjcNewLadderDefine.JJC_NEWLADDER_ENDDAY >= tDate.wday then
            return true
        end

        return false
    else
        -- 在活动时间内
        if tDate.wday >= JjcNewLadderDefine.JJC_NEWLADDER_OPENDAY and JjcNewLadderDefine.JJC_NEWLADDER_ENDDAY >= tDate.wday then
            return nNowTime > nEndTime
        end

        -- 不在不处理
        return false
    end
end

-- 加入人物
function JjcNewLadderDB_AddHuman(tData)
    local rank = JJCNEWLADDERDB_PLAYER_RANK[tData.uuid]
	if rank then
        return true
    end

    -- 存在久的数据
    local oldData = JjcNewLadderDB_GetDBDataByUid(tData.uuid)
    if oldData then
        print("[JjcNewLadderDB_AddHuman] 请求加入天梯赛, 存在该玩家旧的数据")

        JjcNewLadderDB_RemoveDB(tData.uuid)

        print("[JjcNewLadderDB_AddHuman] 请求加入天梯赛, 移除该玩家旧的数据完成")

        JjcNewLadderDB_RemoveCache(tData.uuid)
    end

    local nNowRank = #JJCNEWLADDERDB_ALL_RANK
    local nRank = nNowRank  + 1
    local JjcDBData = {
        nIsHuman = 1,       -- 是否是真人
        name = tData.name,
        uuid = tData.uuid,
        nServerID = tData.nSrcServerID,
        szServerName = tData.szServerName,
        headFrame = tData.headFrame,
        head = tData.head,
        time = os.time(),
        point = JjcNewLadderDefine.JJC_NEWLADDER_POINT,
        tRival = {},
        nInFight = 0,
        nLastFightTime = 0,
        zhandouli = tData.zhandouli,
        nRank = nRank
    }

	LuaMongo.insert(DB.db_jjcLadder, JjcDBData)

    JJCNEWLADDERDB_ALL_RANK[#JJCNEWLADDERDB_ALL_RANK + 1] = JjcDBData
	JjcNewLadderDB_SortRank()

    JjcNewLadderDB_WriteLog("[JjcNewLadderDB_AddHuman] 玩家加入天梯赛活动 name = "..tData.name.." uuid = "..tData.uuid.." nServerID = "..tData.nSrcServerID)

    return true
end

-- 匹配对手
function JjcNewLadderDB_MatchRival(uuid)
    local nNowRank = UUID_2_RANK[uuid]
    if not nNowRank then
        print("[JjcNewLadderDB_MatchRival] 匹配对手 不存在排行榜 重新匹配数据 uuid = "..uuid)
        nNowRank = 1000
    end
    local nMachRank = nNowRank
    if nNowRank > 1000 then
        nMachRank = 1000
    end
    local nMatchMinRank = math.max(nMachRank - 50, 1)
    local nMatchMaxRank = math.min(nMachRank + 10, 999)
    print("[JjcNewLadderDB_MatchRival] nMatchMinRank = "..nMatchMinRank.." nMatchMaxRank = "..nMatchMaxRank.." nMachRank = "..nMachRank)

    local tChoseID, nFindNum = {}, 0

    local bFindBig = true
    -- 前5特殊处理
    if nMachRank <= JJCLADDER_SPECIALRANK then
        bFindBig = false

        -- 不是第一名
        if nNowRank ~= 1 then
            for i = 1, JJCLADDER_SPECIALRANK, 1 do
                if i ~= nNowRank then
                    tChoseID[i] = 1
                    nFindNum = nFindNum + 1
                end
            end
        end
    end

    -- 找50次
    for i = 1, JJCLADDER_RANDNUM, 1 do
        local nFindRank = math.random(nMatchMinRank, nMatchMaxRank)
        if not tChoseID[nFindRank] and nFindRank ~= nNowRank then
            if bFindBig == true then
                if nFindRank < nMachRank then
                    tChoseID[nFindRank] = 1
                    nFindNum = nFindNum + 1
                end
            else
                tChoseID[nFindRank] = 1
                nFindNum = nFindNum + 1
            end
        end

        if nFindNum >= JJCLADDER_FINDBIGNUM then
            bFindBig = false
        end

        if nFindNum >= JJCLADDER_FINDRIVALNUM then
            break
        end 
    end

    if nFindNum < 5 then
        print("[JjcNewLadderDB_MatchRival] 查找到的数量不足 5 \n")
        table.print_lua_table(tChoseID)
        return nil
    end

    local bAddRival = JjcNewLadderDB_AddRival(uuid, tChoseID)
    if false == bAddRival then
        print("[JjcNewLadderDB_MatchRival] 加入缓存中的对战列表失败")
        return nil
    end

    return tChoseID
end

-- 匹配一次对手
function JjcNewLadderDB_MatchOneRival(uuid, tChoseRank)
    local nNowRank = UUID_2_RANK[uuid]
    local nMachRank = nNowRank
    if nNowRank < 1000 then
        nMachRank = 1000
    end
    local nMatchMinRank = math.max(nMachRank - 50, 1)
    local nMatchMaxRank = math.min(nMachRank + 10, 1000)

    for i = 1, JJCLADDER_RANDNUM, 1 do
        local nFindRank = math.random(nMatchMinRank, nMatchMaxRank)
        if not tChoseRank[nFindRank] then
            return nFindRank
        end
    end

    return -1
end

-- 通过uid获取对应的DB数据
function JjcNewLadderDB_GetDBDataByuid(uuid)
    local nRank = UUID_2_RANK[uuid]
    if not nRank then
        return nil
    end

    return JJCNEWLADDERDB_ALL_RANK[nRank]
end

-- 通过排名获取对应的DB数据
function JjcNewLadderDB_GetDBDataByRank(nRank)
    return JJCNEWLADDERDB_ALL_RANK[nRank]
end

function JjcNewLadderDB_GetRankByuid(uuid)
    return UUID_2_RANK[uuid]
end

function JjcNewLadderDB_GetPointByuid(uuid)
    local nRank = UUID_2_RANK[uuid]
    if not nRank then
        return 0
    end

    local tRankData = JJCNEWLADDERDB_ALL_RANK[nRank]
    if not tRankData then
        return 0
    end

    return tRankData.point
end

-- 增加积分点数
function JjcNewLadderDB_AddPoint(uuid, nAddPointNum)
    local tRankData = JjcNewLadderDB_GetDBDataByuid(uuid)
    if tRankData then
        table.print_lua_table(tRankData)
        print("[JjcNewLadderDB_AddPoint] 增加积分 uuid = "..uuid.."\n")
        tRankData.point = tRankData.point + nAddPointNum

        table.print_lua_table(tRankData)
        print("[JjcNewLadderDB_AddPoint] 增加积分后 uuid = "..uuid.."\n")

        local tNewData = Util.copyTable(tRankData)
        tNewData._id = nil

        -- 更新DB数据
        JjcNewLadderDB_UpdateDBData(tNewData)
        JjcNewLadderDB_SortRank()
    end

    print("[JjcNewLadderDB_AddPoint] 排序结束打印新的数据 uuid = "..uuid.."\n")

    local tNewRankData = JjcNewLadderDB_GetDBDataByuid(uuid)
    if tNewRankData then
        table.print_lua_table(tNewRankData)
        print("[JjcNewLadderDB_AddPoint] 打印新的数据 uuid = "..uuid.."\n")
    end
end

-- 交换排名
function JjcNewLadderDB_ExChangeRank(uuid, uuidEnemy)
    print("[JjcNewLadderDB_ExChangeRank] 进入交换排名")
    local tRankData = JjcNewLadderDB_GetDBDataByuid(uuid)
    local tRankEnemyData = JjcNewLadderDB_GetDBDataByuid(uuidEnemy)
    if not tRankData or not tRankEnemyData then
        print("[JjcNewLadderDB_ExChangeRank] 不存在对应的数据 uuid = "..uuid.." uuidEnemy = "..uuidEnemy)
        return
    end

    if tRankData.nRank > tRankEnemyData.nRank then
        print("[JjcNewLadderDB_ExChangeRank] 111 nRank = "..tRankData.nRank.." nRank2 = "..tRankEnemyData.nRank)

        local szText = "[JjcNewLadderDB_ExChangeRank] 开始交换排名 我方排名 nRank = "..tRankData.nRank.." 敌方排名 nEnemyRank = "..tRankEnemyData.nRank
                        .. " name = "..tRankData.name.." nServerID = "..tRankData.nServerID
        if tRankEnemyData.nIsHuman == 1 then
            szText = szText.." 敌方为真人 name = "..tRankEnemyData.name.." nServerID = "..tRankEnemyData.nServerID
        end
        JjcNewLadderDB_WriteLog(szText)

        local nNewRank = tRankEnemyData.nRank
        tRankEnemyData.nRank = tRankData.nRank
        tRankData.nRank = nNewRank

        print("[JjcNewLadderDB_ExChangeRank] 222 nRank = "..tRankData.nRank.." nRank2 = "..tRankEnemyData.nRank)

        local tNewData = Util.copyTable(tRankData)
        tNewData._id = nil
        -- 更新DB数据
        print("[JjcNewLadderDB_ExChangeRank] 更新DB数据1 ")
        JjcNewLadderDB_UpdateDBData(tNewData)

        local tNewEnemyData =  Util.copyTable(tRankEnemyData)
        tNewEnemyData._id = nil
        print("[JjcNewLadderDB_ExChangeRank] 更新DB数据2 ")
        -- 更新DB数据
        JjcNewLadderDB_UpdateDBData(tNewEnemyData)

        JjcNewLadderDB_SortRank()
    end
end

-- 发送对应的数据给奖励
function JjcNewLadderDB_OnSendPlayerRank(uuid, nServerID, nRank)
    JjcNewLadderDB_WriteLog("[JjcNewLadderDB_OnSendPlayerRank] 发送奖励 uuid = "..uuid.." nServerID = "..nServerID.." nRank = "..nRank)
    JjcNewLadderMiddle.JjcNewLadderMiddle_SendPrizeMail(uuid, nServerID, nRank)
end

-- 延迟时间 遍历排行榜 发送奖励
function JjcNewLadderDB_OnTimeSendMail()
    -- 再排序一次
    JjcNewLadderDB_SortRank()
    print("[JjcNewLadderDB_OnTimeSendMail] 最终排序结束")

    local tLastRankInfo, tQueryWorShip = {}, {}
    for nRank = 1, JjcNewLadderDefine.JJC_NEWLADDER_SEND_RANKPRIZE_LEN, 1 do
        local tRankData = JJCNEWLADDERDB_ALL_RANK[nRank]
        if tRankData.nIsHuman == 1 then
            local nLaterTime = math.random(5, 10)
            local uuid, nServerID = tRankData.uuid, tRankData.nServerID
            Timer.addLater(nLaterTime, JjcNewLadderDB_OnSendPlayerRank, uuid, nServerID, nRank)
            print("[JjcNewLadderDB_OnTimeSendMail] 发送真人玩家邮件奖励数据 uuid = "..uuid.." nServerID = "..nServerID.." nRank = "..nRank.." nLaterTime = "..nLaterTime)

            -- 处理上一轮排名前三的玩家
            if JjcNewLadderDefine.JJCN_NEWLADDER_LASTRANK_INFO >= nRank then
                local tInfo =
                {
                    head = tRankData.head,
                    headFrame = tRankData.headFrame or 0,
                    name = tRankData.name,
                    szServerName = tRankData.szServerName,
                    uuid = tRankData.uuid,
                    nIsHuman = tRankData.nIsHuman,
                    nServerID = tRankData.nServerID,
                    worshipCnt = 0,
                }

                JjcNewLadderDB_WriteLog("[JjcNewLadderDB_OnTimeSendMail] 插入前三排名是真人的玩家 name = "..tInfo.name.." uuid = "..tInfo.uuid.." nServerID = "..tInfo.nServerID)

                table.insert(tQueryWorShip, {uuid = tInfo.uuid, nServerID = tInfo.nServerID})
                table.insert(tLastRankInfo, tInfo)
                
                if JjcNewLadderDefine.JJCN_NEWLADDER_LASTRANK_INFO == nRank then
                    CommonDB.SetJjcLadderLast3RankInfo(tLastRankInfo)
                    JjcNewLadderDB_WriteLog("[JjcNewLadderDB_OnTimeSendMail] 插入前三数据完成")
                end
            end
        end
    end

    -- 请求对应的玩家的点赞数
    if nil ~= _G.next(tQueryWorShip) then
        JjcNewLadderMiddle.JjcNewLadderMiddle_QueryWorShip(tQueryWorShip)
    end
end

function JjcNewLadderDB_SendRankMail()
    if false == JjcNewLadderDB_IsFirstServer(Config.SVR_INDEX) then
        return
    end
    
    local nLaterTime = math.random(10, 60)
    Timer.addLater(nLaterTime, JjcNewLadderDB_OnTimeSendMail)
    print("[JjcNewLadderDB_SendRankMail] 延迟 "..nLaterTime.." 秒发放排行榜奖励")
end

-------------------------------- 内部调用函数 ---------------------------
