----------------------------------------------
-- 战斗录像 相关

-- db.combatVideos 			[index] = videoUuid
----------------------------------------------

local LuaMongo = _G.lua_mongo
local Config = require("Config")
local Msg = require("core.Msg")
local ObjHuman = require("core.ObjHuman")
local DB = require("common.DB")
local Util = require("common.Util")
local Lang = require("common.Lang")
local CombatDefine = require("combat.CombatDefine")
local CombatLogic = require("combat.CombatLogic")
local Broadcast = require("broadcast.Broadcast")
local RoleLogic = require("role.RoleLogic")
local InnerMsg = require("core.InnerMsg")
local MiddleManager = require("middle.MiddleManager")
local PanelDefine = require("broadcast.PanelDefine")


VIDEO_SINGLE_MAXCNT = 5 	-- 个人记录条数上限
TOWER_PER_MAXCNT = 3 		-- 通天塔每层保留3条记录
THRONE_RECORD_MAX_CNT = 10  -- 王者争霸记录条数
BATTLE_RECORD_MAX_CNT = 1   -- 战役战斗记录条数
GODSAREA_RECORD_MAX_CNT = 5  -- 诸神圣域每个排名战斗记录条数

-- 录像类型
VIDEOTYPE_COMMON = 1 		-- 个人记录
VIDEOTYPE_JJC = 2 			-- 单人竞技场
VIDEOTYPE_TOWER = 3 		-- 通天塔
VIDEOTYPE_THRONE = 4 		-- 王者争霸
VIDEOTYPE_BATTLE = 5 		-- 战役记录
VIDEOTYPE_JJCLODDER = 6		-- 天梯赛
VIDEOTYPE_GODSAREA = 7		-- 诸神圣域
VIDEOTYPE_AREABATTLE = 8	-- 战区争霸

--------------------------------------------- db ---------------------------------------------------
local QueryByUuid = {_id = nil}
local QueryByType = {videoType = nil, key = nil}

function createCombatVideo(videoType, combatInfo, key,evolveCnt)
	if not combatInfo then return end
	if combatInfo.isVideo then return end
	if combatInfo.isVideoSave then return end

    -- 优化帧数据 降低
    CombatLogic.killFrames(combatInfo)

	local combatVideo = {}
	combatVideo.videoType = videoType
	combatVideo.key = key
	combatVideo.evolveCnt = evolveCnt
	combatVideo.combatInfo = Util.copyTable(combatInfo) 
	LuaMongo.insert(DB.db_combat_video, combatVideo)
	return combatVideo
end

function updateCombatVideo(combatVideo)
	if not combatVideo._id then return end
	QueryByUuid._id = combatVideo._id
	LuaMongo.update(DB.db_combat_video, QueryByUuid, combatVideo)
end

function removeCombatVideo(videoUuid)
	if not videoUuid then return end
	QueryByUuid._id = videoUuid
	LuaMongo.remove(DB.db_combat_video, QueryByUuid)	
end

function getCombatVideo(videoUuid)
	if not videoUuid then return end
	QueryByUuid._id = videoUuid
	local combatVideo = {}
	LuaMongo.find(DB.db_combat_video, QueryByUuid)    
	if not LuaMongo.next(combatVideo) then 
		return 
	end
    return combatVideo	
end

local COMBATVIDEO_LIST_CACHE = {}
local FieldSimple = {["combatInfo.result"] = 0}
function getCombatVideosByType(videoType, key)
	QueryByType.videoType = videoType
    if videoType == VIDEOTYPE_THRONE or videoType == VIDEOTYPE_GODSAREA or videoType == VIDEOTYPE_AREABATTLE then
        FieldSimple = {}
    end
	QueryByType.key = key
	local len = 0
	Util.cleanTable(COMBATVIDEO_LIST_CACHE)
	LuaMongo.find(DB.db_combat_video, QueryByType, FieldSimple) 
    while true do
        local combatVideo = {}
        if not LuaMongo.next(combatVideo) then
			break
		end
        len = len + 1
        COMBATVIDEO_LIST_CACHE[len] = combatVideo
    end	
    return COMBATVIDEO_LIST_CACHE
end
----------------------------------------------- msg -------------------------------------------------------
-- 个人录像数目
function getCombatVideoCnt(human)
	if not human.db.combatVideos then 
		return 0 
	end
	return #human.db.combatVideos
end

-- 获取录像索引
function getCombatVideoIndex(human, videoUuid)
	if not human.db.combatVideos then 
		return 
	end	
	for index, vuuid in ipairs(human.db.combatVideos) do
		if vuuid == videoUuid then
			return index
		end
	end
end

-- 保存个人录像
function saveCombatVideo(human, isShare)
	local combatInfo = human.combat
	if not combatInfo then return end

	if combatInfo.isVideo then
		return Broadcast.sendErr(human, Lang.COMBAT_ERR_IS_VIDEO) 
	end
	if combatInfo.videoUuid then  
		if not isShare then
            Broadcast.sendErr(human, Lang.SAVE_SUCCESS) 
        end
		return combatInfo.videoUuid
	end	
	local saveNum = getCombatVideoCnt(human)
	if saveNum >= VIDEO_SINGLE_MAXCNT then
		local videoUuid = human.db.combatVideos[1]
		deleteCombatVideo(human, videoUuid)
	end		
	local combatVideo = createCombatVideo(VIDEOTYPE_COMMON, combatInfo, human.db._id)
	if not combatVideo then return end
	if not combatVideo._id then return end

	human.db.combatVideos = human.db.combatVideos or {}
	local newIndex = #human.db.combatVideos + 1
	human.db.combatVideos[newIndex] = combatVideo._id
	combatInfo.videoUuid = combatVideo._id

    if not isShare then
        Broadcast.sendErr(human, Lang.SAVE_SUCCESS) 
    end
	return combatVideo._id
end

-- 查看录像
function sendCombatVideoQuery(human)
	local msgRet = Msg.gc.GC_COMBAT_VIDEO_QUERY
	local videoCnt = getCombatVideoCnt(human)
	msgRet.list[0] = 0
	for i = 1, videoCnt do
		local videoUuid = human.db.combatVideos[i]
		local combatVideo = getCombatVideo(videoUuid)
		local combatInfo = combatVideo and combatVideo.combatInfo
		if combatInfo then
			msgRet.list[0] = msgRet.list[0] + 1
			local net = msgRet.list[msgRet.list[0]]			
			net.videoUuid = combatVideo._id
			net.combatTime = combatInfo.time 
			net.isWin = combatInfo.isWin and CombatDefine.RESULT_WIN or CombatDefine.RESULT_FAIL	
			net.type  = combatInfo.type
	        RoleLogic.makeRoleBase(combatInfo.attacker, net.atkRoleBase)	    
	        RoleLogic.makeRoleBase(combatInfo.defender, net.defRoleBase)
	    end
	end
	--Msg.trace(msgRet)
	Msg.send(msgRet, human.fd)
end

-- 删除战斗记录
function deleteCombatVideo(human, videoUuid)
	if not videoUuid or videoUuid == "" then return end

	local videoIndex = getCombatVideoIndex(human, videoUuid)
	if not videoIndex then return end

	local combatVideo = getCombatVideo(videoUuid)
	if combatVideo then
		removeCombatVideo(combatVideo._id)
	end
	table.remove(human.db.combatVideos, videoIndex)
    ObjHuman.save(human)
	sendCombatVideoQuery(human)
end

-- 战斗回放
function lookCombatVideo(human, videoUuid, lookType)

    -- if CombatLogic.isCombating(human) then
	-- 	return Broadcast.sendErr(human, Lang.COMBAT_VIDEO_LOOK_ERR_ING)
	-- end

    if not videoUuid or videoUuid == "" then return end
    local combatVideo = getCombatVideo(videoUuid)
	if not combatVideo then
		-- return Broadcast.sendErr(human, Lang.COMBAT_ERR_NOT_VIDEO)
		local args = {
			playerUid = human.db._id,
			lookType = lookType,
			opType = 1,
		}
		NS_Video_Query(videoUuid, args)

		return
	end

	local combatInfo = combatVideo.combatInfo
	combatInfo.isVideo = true
	combatInfo.videoUuid = videoUuid
	combatInfo.lookType = lookType
	human.combat = combatInfo	
	CombatLogic.sendCombatData(human, combatInfo)
	CombatLogic.sendCombatFinish(human, combatInfo)
end

-- 保存通天塔记录
function saveTowerVideo(towerId, combatInfo)
	if not towerId or not combatInfo then return end

	local list = getCombatVideosByType(VIDEOTYPE_TOWER, towerId)
	if #list < TOWER_PER_MAXCNT then
		createCombatVideo(VIDEOTYPE_TOWER, combatInfo, towerId)
	else
		local selectVideo = nil
		for _, combatVideo in ipairs(list) do
			local attacker = combatVideo.combatInfo.attacker
			local sattacker = selectVideo and selectVideo.combatInfo.attacker
			if sattacker == nil or attacker.lv > sattacker.lv then
				selectVideo = combatVideo
			end
		end
		selectVideo.combatInfo = combatInfo
		updateCombatVideo(selectVideo)
	end
end

-- 竞技计数减一
function delJJCVideoCnt(videoUuid)
	local combatVideo = getCombatVideo(videoUuid)
	if not combatVideo then return end
	if combatVideo.videoType ~= VIDEOTYPE_JJC then
		return
	end

	combatVideo.key = (combatVideo.key or 0) - 1
	if combatVideo.key > 0 then
		updateCombatVideo(combatVideo)
	else
		removeCombatVideo(combatVideo._id)
	end
end

-- 清空竞技场记录
function cleanJJCVideo()
	QueryByType.videoType = VIDEOTYPE_JJC
	LuaMongo.remove(DB.db_combat_video, QueryByType)		
end

-- 王者争霸记录
function saveThroneVideo(id, combatInfo,evolveCnt)
	local list = getCombatVideosByType(VIDEOTYPE_THRONE, id)
	if #list < THRONE_RECORD_MAX_CNT then
		createCombatVideo(VIDEOTYPE_THRONE, combatInfo, id,evolveCnt)
	else
		local selectVideo = {}
		for _, combatVideo in ipairs(list) do
			local time = combatVideo.combatInfo.time
			local stime = selectVideo.combatInfo and selectVideo.combatInfo.time
			if stime == nil or time < stime then
				selectVideo = combatVideo
			end
		end
		selectVideo.combatInfo = combatInfo
        selectVideo.evolveCnt = evolveCnt
		updateCombatVideo(selectVideo)
	end
end

-- 战役记录
function saveBattleVideo(uuid, combatInfo)
	local list = getCombatVideosByType(VIDEOTYPE_BATTLE, uuid)
	if #list < BATTLE_RECORD_MAX_CNT then
        local selectVideo = nil
		selectVideo = createCombatVideo(VIDEOTYPE_BATTLE, combatInfo, uuid)
        return selectVideo._id
	else
		local selectVideo = nil
		for _, combatVideo in ipairs(list) do
			local humanUuid = combatVideo.uuid
			local sUuid = selectVideo and selectVideo.uuid
			if sUuid == nil or sUuid == humanUuid then
				selectVideo = combatVideo
			end
		end
		selectVideo.combatInfo = combatInfo
		updateCombatVideo(selectVideo)
        return selectVideo._id
	end
end


-- 天梯赛竞技计数减一
function delJJCLadderVideoCnt(videoUuid)
	local combatVideo = getCombatVideo(videoUuid)
	if not combatVideo then return end
	if combatVideo.videoType ~= VIDEOTYPE_JJCLODDER then
		return
	end

	combatVideo.key = (combatVideo.key or 0) - 1
	if combatVideo.key > 0 then
		updateCombatVideo(combatVideo)
	else
		removeCombatVideo(combatVideo._id)
	end
end

-- 清空天梯赛记录
function cleanJJCLadderVideo()
	QueryByType.videoType = VIDEOTYPE_JJCLODDER
	LuaMongo.remove(DB.db_combat_video, QueryByType)		
end

-- 保存战斗录像(无数量限制)
function SaveCombatVideo(videoType, combatInfo, arg1, arg2)
	createCombatVideo(videoType, combatInfo, arg1, arg2)
end



-- 清空某个类型的录像数据
function ClearOutVideoByCombatType(combatType)
	if not combatType then
		return
	end
	local queryTb = {videoType = combatType}
	LuaMongo.remove(DB.db_combat_video, queryTb)
end

---------------------------------------------普通服处理------------------------------------------

local function lookCSCombatVideo(combatVideo, args)
	local combatInfo = combatVideo.combatInfo
	combatInfo.isVideo = true
	combatInfo.videoUuid = combatVideo._id
	combatInfo.lookType = args.lookType

	local human = ObjHuman.onlineUuid[args.playerUid]
	if not human then
		return
	end

	human.combat = combatInfo
	CombatLogic.sendCombatData(human, combatInfo)
	CombatLogic.sendCombatFinish(human, combatInfo)
end

local function videoPlayBack(combatVideo, args)
	local human = ObjHuman.onlineUuid[args.playerUid]
	if not human then
		return
	end
	combatVideo.combatInfo.panelID = PanelDefine.PANEL_ID_1018
	CombatLogic.repeatCombat(human, combatVideo.combatInfo)
end




-- 向跨服查询战斗录像数据
function NS_Video_Query(videoUuid, extraArgs)
	if not videoUuid then
		return
	end
	local msgData = InnerMsg.lw.LW_COMBAT_VIDEO_QUERY

    msgData.sourceServerId = Config.SVR_INDEX
	msgData.videoUuid = videoUuid or ""
	msgData.extraArgs = extraArgs

	InnerMsg.sendMsg(0, msgData)
end

-- 收到跨服发送的查询结果
function NS_Video_Query_Result(msg)
	if msg.res ~= 0 then
		return
	end

	local extraArgs = msg.extraArgs

	if extraArgs.opType == 1 then
		lookCSCombatVideo(msg.videoData, extraArgs)
	elseif extraArgs.opType == 2 then
		videoPlayBack(msg.videoData, extraArgs)
	end
end

-- 把战斗录像数据保存到跨服
function NS_Video_Save(vieoType, combatInfo, extraArgs)
	if not vieoType or not combatInfo then
		return
	end

	local msgData = InnerMsg.lw.LW_COMBAT_VIDEO_SAVE
    -- msgData.sourceServerId = Config.SVR_INDEX
	CombatLogic.killFrames(combatInfo)
	msgData.videoType = vieoType
	msgData.videoData = combatInfo
	msgData.extraArgs = extraArgs or {}

	InnerMsg.sendMsg(0, msgData)
end


-------------------------------------------------------------------------------------------


---------------------------------------------跨服处理---------------------------------------

local function saveGodsAreaVideo(combatInfo, extraArgs)
	local rank = extraArgs.rank
	local list = getCombatVideosByType(VIDEOTYPE_GODSAREA, rank)

	if #list < GODSAREA_RECORD_MAX_CNT then
		createCombatVideo(VIDEOTYPE_GODSAREA, combatInfo, rank)
	else
		local selectVideo = {}
		for _, combatVideo in ipairs(list) do
			local time = combatVideo.combatInfo.time
			local stime = selectVideo.combatInfo and selectVideo.combatInfo.time
			if stime == nil or time < stime then
				selectVideo = combatVideo
			end
		end

		selectVideo.combatInfo = combatInfo
		updateCombatVideo(selectVideo)
	end
end


-- 普通服向跨服查询录像数据
function CS_Video_Query(msg)
	if _G.is_middle ~= true then return end

	local fd = MiddleManager.getFDBySvrIndex(msg.sourceServerId)
	local msgData = InnerMsg.wl.WL_COMBAT_VIDEO_QUERY
	msgData.res = -1
	msgData.extraArgs = msg.extraArgs

	local combatVideo = getCombatVideo(msg.videoUuid)
	if combatVideo then
		msgData.res = 0
		msgData.videoData = combatVideo
	end

	InnerMsg.sendMsg(fd, msgData)
end


-- 普通服通知跨服保存录像数据
function CS_Video_Save(msg)
	if _G.is_middle ~= true then return end
	if msg.videoType == VIDEOTYPE_GODSAREA then
		saveGodsAreaVideo(msg.videoData, msg.extraArgs)
	end
end


-------------------------------------------------------------------------------------------