-------------------------------------------------------
-- 战报

-- 
-------------------------------------------------------
local LuaMongo = _G.lua_mongo
local Util = require("common.Util")
local Lang = require("common.Lang")
local Msg = require("core.Msg")
local ObjHuman = require("core.ObjHuman")
local Grid = require("bag.Grid")
local BagLogic = require("bag.BagLogic")
local Broadcast = require("broadcast.Broadcast")
local HeroLogic = require("hero.HeroLogic")
local RoleLogic = require("role.RoleLogic")
local CombatDefine = require("combat.CombatDefine")
local HeroGrid = require("hero.HeroGrid")
local CombatExcel = require("excel.combat").combat
local CombatLogic = require("combat.CombatLogic")
local InnerMsg = require("core.InnerMsg")
local ChatHandler = require("chat.Handler")
local Broadcast = require("broadcast.Broadcast")
local Json = require("common.Json")
local DB = require("common.DB")
local ChatLogic = require("chat.ChatLogic")
local WarReportMiddle = require("warReport.WarReportMiddle")
local RoleSystemLogic = require("roleSystem.RoleSystemLogic")
local RoleSystemDefine = require("roleSystem.RoleSystemDefine")
local ItemDefine = require("bag.ItemDefine")
local HeroGrowUp = require("absAct.HeroGrowUp")
local Config = require("Config")
local CombatVideo = require("combat.CombatVideo")

WAR_REPORT_1 = 1 -- 冠军联赛
WAR_REPORT_2 = 2 -- 王者争霸
WAR_REPORT_3 = 3 -- 天梯
WAR_REPORT_4 = 4 -- 切磋
WAR_COUNT_MAX  = 30    
WAR_COUNT_MAX1 = 20
WAR_JJC_RANK   = 20
WAR_FRIEND_RANK  = 30
WAR_ADMIRE = 3   -- 点赞次数
WAR_COMBATINFO_PLAYBACK = 1  -- 请求战斗数据用于回方
WAR_COMBATINFO_HARM     = 2  -- 请求战斗数据用于伤害列表
WAR_OP_CONFIRM = 1  --确认
WAR_OP_CANCEL = 0  --取消
WAP_OP_TYPE1 = 1 --点赞
WAP_OP_TYPE2 = 2 --收藏
WAP_REWARD_GOD = 3000

local war_report_count = {
    [WAR_REPORT_1] = 1,
    [WAR_REPORT_2] = 1,
    [WAR_REPORT_3] = 1,
    [WAR_REPORT_4] = 1,
}


local function makeReportNet(net, war_data)

   net.atkRole = war_data.combatInfo.attacker
   net.defRole = war_data.combatInfo.defender
   net.atkHeros = {}
   net.defHeros = {}
   net.time = war_data.time
   net.type = war_data.type
   net.admire = war_data.admire or 0
   net.collect = war_data.collect or 0
   net.atkRank = war_data.atkRank or 0
   net.defRank = war_data.defRank or 0
   net.id = war_data._id
   net.type = war_data.type
   net.admireList = war_data.admireList

   local combatInfo = war_data.combatInfo
   local result = combatInfo.result
   local frameCnt = result.frames and #result.frames or 0	
   local lastFrame = result.frames and result.frames[frameCnt] or nil

   net.result = combatInfo.isWin and 1 or 2
   net.round = lastFrame and lastFrame.round or 0
   net.roundMax = combatInfo.maxRound
   for i = 1,CombatDefine.COMBAT_HERO_CNT do
       local atkPos = CombatLogic.getPos(CombatDefine.ATTACK_SIDE, i)
       local atkObj = combatInfo.objList[atkPos]
       net.atkHeros[i] = {}
       if atkObj then
          net.atkHeros[i].id = atkObj.id
          net.atkHeros[i].lv = atkObj.lv
          net.atkHeros[i].star = atkObj.star
       else
          net.atkHeros[i].id = 0
       end

       local defPos = CombatLogic.getPos(CombatDefine.DEFEND_SIDE, i)
       local defObj = combatInfo.objList[defPos]
       net.defHeros[i] = {}
       if defObj then
          net.defHeros[i].id = defObj.id
          net.defHeros[i].lv = defObj.lv
          net.defHeros[i].star = defObj.star
       else
          net.defHeros[i].id = 0 
       end
   end

   net.atkFormation = combatInfo.atkFormation
   net.defFormation = combatInfo.defFormation
end




function initAfterStart()
   -- �����ķ�����
   if _G.is_middle ~= true then
      --return
   end

   -- ���Ӽ�¼����
   local war_count_data = {}
   local war_count_query = { war = 1 }
   LuaMongo.find(DB.db_war_report, war_count_query)
   if LuaMongo.next(war_count_data) then
      return
   end

   local warReport = {}
   warReport.war = 1
   warReport.war_report_count = war_report_count
   LuaMongo.insert(DB.db_war_report, warReport)
end

-- db_war_report
-- - 添加记录 所有记录存中心服
function add(type, combatInfo, atkRank, defRank)
    -- 优化帧数据 降低
    CombatLogic.killFrames(combatInfo)

   if not _G.is_middle then
       WarReportMiddle.LW_WARREPORT_ADD(type, combatInfo, atkRank, defRank)
       return 
   end
   
   local msgInner = InnerMsg.lw.LW_WARREPORT_ADD
   msgInner.type = type
   msgInner.combatInfo = combatInfo
   msgInner.atkRank = atkRank
   msgInner.defRank = defRank
   InnerMsg.sendMsg(0, msgInner)
end

-- ��ѯ
function query(human, type, questType)
   if RoleSystemLogic.isOpen(human, RoleSystemDefine.ROLE_SYS_ID_202) ~= true then
	  return
   end

   -- �������������ķ� ���� �����ղ� ��ȥ���ķ�������
   --[[local msgInner = InnerMsg.lw.LW_WARREPORT_QUERY
   local msgInner = {}
   msgInner.uuid = human.db._id
   msgInner.type = type
   msgInner.questType = questType
   msgInner.warReport = human.db.warReport
   InnerMsg.sendMsg(0, msgInner)]]
   WarReportMiddle.LW_WARREPORT_QUERY(0,type,human.db._id,human.db.warReport,questType)
   human.db.warDot = nil
   RoleSystemLogic.onDot(human, RoleSystemDefine.ROLE_SYS_ID_202)
end

-- ���ս���б�
local makeReportQuery = {war_index = { ["$exists"] = 1}}
function makeReport(type)
   local len = 0
   makeReportQuery.type = type
   LuaMongo.find(DB.db_war_report, makeReportQuery)
   local war_data_list = {}
   while true do
       local war_data = {}
       if not LuaMongo.next(war_data) then
          break
       end
       if len >= WAR_COUNT_MAX then
          break
       end
       len = len + 1
       war_data_list[len] = {}

       local net = war_data_list[len]
       makeReportNet(net, war_data)
   end
   return war_data_list
end

-- ����ղ�
local makeCollectReportQuery = {_id = nil}
function makeCollectReport(collect)
   local war_data_list = {}
   local len = 0
   for _, list in pairs(collect) do
       for _id , v in pairs(list) do
          makeCollectReportQuery._id = _id
          LuaMongo.find(DB.db_war_report, makeCollectReportQuery)
          local war_data = {}
          if LuaMongo.next(war_data) then
              if len >= WAR_COUNT_MAX then
                 break
              end
              len = len + 1
              war_data_list[len] = {}

              local net = war_data_list[len]
              makeReportNet(net, war_data)
          end
       end
   end

   return war_data_list
end


-- ����ҵ�ս��
local makeMyReportQuery = {}
function makeMyReport(uuid)
   local len = 0
   makeMyReportQuery = {["$or"] = {{defUuid=uuid}, {atkUuid=uuid}}}
   LuaMongo.find(DB.db_war_report, makeMyReportQuery)
   local war_data_list = {}
   while true do
       local war_data = {}
       if not LuaMongo.next(war_data) then
          break
       end

       if len >= WAR_COUNT_MAX then
          break
       end
       len = len + 1
       war_data_list[len] = {}

       local net = war_data_list[len]
       makeReportNet(net, war_data)
   end
   return war_data_list
end


-- ����ս���б�
local heroOther = {}
function sendReport(human, war_data_list, questType)
    local len = #war_data_list
    local msgRet = Msg.gc.GC_WAR_REPORT_QUERY
    msgRet.admireCnt = human.db.warAdmire or 0
    msgRet.admireMax = WAR_ADMIRE
    msgRet.questType = questType
    msgRet.isEnd = 0
    local sendLen = 0

    -- ˢ���ղ�
    if questType == WAP_OP_TYPE2 then
       human.db.warReport = {}
    end

    local warReport = human.db.warReport
    for i = 1, len do
        sendLen = sendLen + 1

        local net = msgRet.warReportList[sendLen]
        local war = war_data_list[i]

        local heroLen = 0
        net.round = war.round
        net.roundMax = war.roundMax

        net.atkFormation = war.atkFormation
        net.defFormation = war.defFormation or 0
        net.time = war.time
        net.admire = war.admire
        net.collect = war.collect
        net.atkRank = war.atkRank
        net.defRank = war.defRank
        RoleLogic.makeRoleBase(war.atkRole, net.atkRole)
        RoleLogic.makeRoleBase(war.defRole, net.defRole)
        net.result = war.result
        net.type = war.type
        net.id = war.id
        net.isCollect = 0
        net.isAdmire = 0

        -- �����ղ��б�
        if questType == WAP_OP_TYPE2 then
           warReport[net.type] = warReport[net.type] or {}
           warReport[net.type][net.id] = 1
        end

        -- �Ƿ��ѵ���
        if war.admireList and war.admireList[human.db._id] then
            net.isAdmire = 1
        end

        -- �Ƿ����ղ�
        for _, list in pairs(warReport) do
            if list[net.id] then
                net.isCollect = 1
                break
            end
        end
        heroLen = 0
        for k, v in pairs(war.atkHeros) do
            if v.id ~= 0 then
               heroLen = heroLen + 1
               heroOther.lv = v.lv or 0
               heroOther.star = v.star or 0
               HeroGrid.makeHeroOrMonster(net.atkHeros[heroLen], v.id, nil, heroOther)
            end
        end
        net.atkHeros[0] = heroLen

        heroLen = 0
        for k, v in pairs(war.defHeros) do
            if v.id ~= 0 then
               heroLen = heroLen + 1
               heroOther.lv = v.lv or 0
               heroOther.star = v.star or 0
               HeroGrid.makeHeroOrMonster(net.defHeros[heroLen], v.id, nil, heroOther)
            end
        end
        net.defHeros[0] = heroLen

        msgRet.isEnd = 0
        if sendLen >= 5 then
            msgRet.warReportList[0] = sendLen
            Msg.send(msgRet, human.fd)
            sendLen = 0
        end
    end

    msgRet.warReportList[0] = sendLen
    msgRet.isEnd = 1
    Msg.send(msgRet, human.fd)

end

-- �˺���¼
function harm(human, type, id)
   -- �������������ķ�
   local msgInner = {} --InnerMsg.lw.LW_WARREPORT_GET_COMBATINFO
   msgInner.uuid = human.db._id
   msgInner.type = type
   msgInner.id = id
   msgInner.mode = WAR_COMBATINFO_HARM
   --InnerMsg.sendMsg(0, msgInner)
   WarReportMiddle.LW_WARREPORT_GET_COMBATINFO(0,msgInner)
end

-- ս�����
function sendFinish(human, combatInfo)
    if not combatInfo then return end
	local msgRet = Msg.gc.GC_WAR_REPROT_HARM
    if not CombatLogic.fontCombatFinish(msgRet.data, combatInfo) then
       return
    end
	Msg.send(msgRet,human.fd)
end

-- 回放
function playBack(human, type, id, nDesServerID)
   print("[playBack] type = "..type.. " id = "..id.." nDesServerID = "..nDesServerID)


   if type == 5 then
      local extraArgs = {
         playerUid = human.db._id,
         opType = 2,
      }
      return CombatVideo.NS_Video_Query(id, extraArgs)
   end

   -- 本服
   if -1 >= nDesServerID then
      local msgInner = {} --InnerMsg.lw.LW_WARREPORT_GET_COMBATINFO
      msgInner.uuid = human.db._id
      msgInner.type = type
      msgInner.id = id
      msgInner.mode = WAR_COMBATINFO_PLAYBACK
      --InnerMsg.sendMsg(0, msgInner)
      WarReportMiddle.LW_WARREPORT_GET_COMBATINFO(0,msgInner)
   else
      -- 天梯赛请求中心服
      local tMsgData = InnerMsg.lw.LW_WARREPORT_GET_COMBATINFO
      tMsgData.nSrcUID = human.db._id
      tMsgData.type = type
      tMsgData.id = id
      tMsgData.nSrcServerID = Config.SVR_INDEX
      tMsgData.nDesServerID = nDesServerID
      tMsgData.mode = WAR_COMBATINFO_PLAYBACK
      InnerMsg.sendMsg(0, tMsgData)
   end
end


-- 操作结果
function opResult(human, opType, id, result)
   local msgRet = Msg.gc.GC_WAR_REPORT_OP_RESULT
   msgRet.opType = opType
   msgRet.result = result
   msgRet.id = id
   Msg.send(msgRet,human.fd)
end

-- �ղ�
function collect(human, type, id, op)
   if op ~= WAR_OP_CONFIRM and op ~= WAR_OP_CANCEL then
      return
   end

   local warReport = human.db.warReport
   if op == WAR_OP_CONFIRM then
      -- �Ѿ����ղ��б�
      if warReport[type] and warReport[type][id] then
         return
      end

      -- �ղ�����
      local collectCnt = 0
      for k, v in pairs(warReport) do
         for _, data in pairs(v) do
            collectCnt = collectCnt + 1
         end
      end

      if collectCnt >= WAR_COUNT_MAX1 then
         return Broadcast.sendErr(human, Lang.WAR_REPORT_COLLECT_CNT_ERR) 
      end

   elseif op == WAR_OP_CANCEL then
      if not warReport[type] or not warReport[type][id] then
         return
      end
   end

   local msgInner = {} --InnerMsg.lw.LW_WARREPORT_COLLECT
   msgInner.uuid = human.db._id
   msgInner.type = type
   msgInner.id = id
   msgInner.op = op
   --InnerMsg.sendMsg(0, msgInner)
   WarReportMiddle.LW_WARREPORT_COLLECT(0,msgInner)
end

-- �ղػ���
function collectHumanDo(human, type, id, op)
   if op ~= WAR_OP_CONFIRM and op ~= WAR_OP_CANCEL then
      return
   end

   local warReport = human.db.warReport
   warReport[type] = warReport[type] or {}

   if op == WAR_OP_CONFIRM then
      warReport[type][id] = 1
   elseif op == WAR_OP_CANCEL then
      warReport[type][id] = nil
   end

   opResult(human, WAP_OP_TYPE2, id, op)
end

-- ����
function admire(human, type, id)
   if human.db.warAdmire == nil then
      return Broadcast.sendErr(human, Lang.WAR_REPORT_ADMIRE_NOT_ENOUGH) 
   end

   human.db.warAdmire = human.db.warAdmire - 1
   if human.db.warAdmire <= 0 then
      human.db.warAdmire = nil
   end

   
	HeroGrowUp.onCallback(human, HeroGrowUp.TASKTYPE6, 1)

   local msgInner = {} --InnerMsg.lw.LW_WARREPORT_ADMIRE
   msgInner.uuid = human.db._id
   msgInner.id = id
   --InnerMsg.sendMsg(0, msgInner)
   WarReportMiddle.LW_WARREPORT_ADMIRE(0,msgInner)
end

-- ���޻���
function admireDo(human, id)
   BagLogic.cleanMomentItemList()
   BagLogic.updateMomentItem(BagLogic.ADDITEM_TYPE_1, ItemDefine.ITEM_JINBI_ID, WAP_REWARD_GOD)
   BagLogic.addMomentItemList(human, "war_report")
   opResult(human, WAP_OP_TYPE1, id, WAR_OP_CONFIRM)
end

--
function updateDaily(human)
   human.db.warAdmire = human.db.warAdmire or WAR_ADMIRE
   human.db.warDot = true
end

function isDot(human)
    return human.db.warDot
end


local function getWarReportIdxByRand(warReportArr, excludeIdxList)
   local warReportCnt = #warReportArr

   local len = 0
   local randArr = {}
   for i = 1, warReportCnt do
      if not excludeIdxList or not excludeIdxList[i] then
         len = len + 1
         randArr[len] = i
      end
   end

   if len == 0 then
      return
   end

   local idx = randArr[math.random(1, len)]
   return idx
end


-- 冠军联赛录像一键点赞
function AdmireByOneTouch(human)
   if human.db.warAdmire == nil then
      return Broadcast.sendErr(human, Lang.WAR_REPORT_ADMIRE_NOT_ENOUGH)
   end

   local warAdmireSubCnt = human.db.warAdmire

   local len = 0
   local queryCond = {war_index = { ["$exists"] = 1}, type = WAR_REPORT_1}
   LuaMongo.find(DB.db_war_report, queryCond)


   local war_data_list = {}
   while true do
      local war_data = {}
      if not LuaMongo.next(war_data) then
         break
      end

      if len >= WAR_COUNT_MAX then
         break
      end

      if not war_data.admireList or not war_data.admireList[human.db._id] then
         len = len + 1
         war_data_list[len] = war_data
      end
   end

   warAdmireSubCnt = math.min(warAdmireSubCnt, len)
   if warAdmireSubCnt <= 0 then
      print("=========================没有符合的录像数据=========================")
      return
   end


   local excludeIdxList
   for i = 1, warAdmireSubCnt do
      local idx =  getWarReportIdxByRand(war_data_list, excludeIdxList)
      if not idx then
         break
      end

      local warReportUuid = war_data_list[idx]._id
      excludeIdxList =  excludeIdxList or {}
      excludeIdxList[idx] = true

      -- 通过原有接口进行点赞
      admire(human, WAR_REPORT_1, warReportUuid)
   end

   query(human, WAR_REPORT_1, 1)
end