---- 冰龙巢穴 版本2

--[[
    db.dragonCopy = {
        time          =    1
        hurt          =    1
        dayHurt       =    1
        maxHurt       =    1
    }
]]
local Lang = require("common.Lang")
local Msg = require("core.Msg")
local ObjHuman = require("core.ObjHuman")
local Util = require("common.Util")
local CopyExcel = require("excel.copy")
local Grid = require("bag.Grid")
local BagLogic = require("bag.BagLogic")
local CombatDefine = require("combat.CombatDefine")
local CombatLogic = require("combat.CombatLogic")
local RoleSystemDefine = require("roleSystem.RoleSystemDefine")
local RoleSystemLogic = require("roleSystem.RoleSystemLogic")
local Broadcast = require("broadcast.Broadcast")
local MonsterExcel = require("excel.monster")
local HeroLogic = require("hero.HeroLogic")
local BRoleLogic = require("billboard.BRoleLogic")
local BillboardDB = require("billboard.BillboardDB")
local BillboardDefine = require("billboard.BillboardDefine")
local RoleLogic = require("role.RoleLogic")
local CommonDB = require("common.CommonDB")
local ChengjiuLogic = require("chengjiu.ChengjiuLogic")
local ChengjiuDefine = require("chengjiu.ChengjiuDefine")
local CombatImpl = require("combat.CombatImpl")
local BeSkill = require("combat.BeSkill")
local SkillExcel = require("excel.skill").skill
local HeroGrowUp = require("absAct.HeroGrowUp")
local MengxinLogic = require("present.MengxinLogic")
local RoleDBLogic = require("role.RoleDBLogic")
local YunYingLogic = require("yunying.YunYingLogic")
local WeekTaskLogic = require("dailyTask.WeekTaskLogic")
local TriggerLogic = require("trigger.TriggerLogic")
local TriggerDefine = require("trigger.TriggerDefine")
CITIAO_BY_ATTACK =  1     -- 词条对玩家生效
CITIAO_BY_DEFEND =  2     -- 词条对BOSS生效

function updateDaily(human)
    if human.db.dragonCopy and not Util.isSameDay(human.db.dragonCopy.time) then 
        human.db.dragonCopy.time = os.time()
        human.db.dragonCopy.hurt = 0
        human.db.dragonCopy.dayHurt = 0
        human.db.dragonCopy.dayGet = nil
        human.db.dragonCopy.read   = nil
        human.db.dragonCopy.getDay = nil
        human.db.dragonCopy.maxCombatInfo = nil
    end
end
function init(human)
    if not human.db.dragonCopy then
        human.db.dragonCopy = {}
        human.db.dragonCopy.time = os.time()
        human.db.dragonCopy.hurt = 0
        human.db.dragonCopy.dayHurt = 0
        human.db.dragonCopy.historyGet = {}
    end
end

DRAGON_CITIAO_RARE_MAX = nil
function randomCiTiao()
    if not DRAGON_CITIAO_RARE_MAX then
        -- 防止策划删减 词条
        DRAGON_CITIAO_RARE_MAX = 0
        for k, v in pairs(CopyExcel.dragoncitiao) do
            if v then
                DRAGON_CITIAO_RARE_MAX = DRAGON_CITIAO_RARE_MAX + v.quanzhong
            end
        end
    end

    local list = {}
    local getRare = 0
    for i = 1 , 3 do 
        local random = math.random(1, DRAGON_CITIAO_RARE_MAX - getRare)
        for k, v in pairs(CopyExcel.dragoncitiao) do
            if not list[k] and random <= v.quanzhong then
                list[k] = i
                getRare = getRare + v.quanzhong
                break
            elseif not list[k] then
                -- 防止循环最后一个是 已经随机过的  导致 随机不出来
                random = random - v.quanzhong
            end
        end
    end    

    return list
end

function getSvrCiTiao()
    local list = CommonDB.getDragonNestCitiao()

    local weekTime = Util.getWeekStartTime(os.time())
    if not list or not list.time or list.time ~= weekTime then
        local list = randomCiTiao()

        CommonDB.setDragonNestCitiao(list, weekTime)
        return CommonDB.getDragonNestCitiao()
    else
        return list
    end

end

function getNextCiTiaoTime()
    local now = os.time()
    local weekTime = Util.getWeekStartTime(now + 7 * 24 * 60 * 60)
    return weekTime - now
end
local function fontRank(msgRet, human)
    local board = BillboardDB.getBoard(BillboardDefine.TYPE_DRAGON)
	if board then 
        for i = 1 ,  3 do
            local rankData = board.rank2data[i]
			if rankData then
				msgRet.topRank[0] = msgRet.topRank[0] + 1
				local net = msgRet.topRank[msgRet.topRank[0]]
                net.rank = i
				if rankData and rankData.roleBase then
					RoleLogic.makeRoleBase(rankData.roleBase, net.roleBase)
				else
					local roleUuid = rankData and rankData.uuid or ""
					RoleLogic.getRoleBaseByUuid(roleUuid, net.roleBase)
				end
				net.hurt = rankData and rankData.value1 or 0
			end      
        end
    end

    local myRank = BillboardDB.getRank(BillboardDefine.TYPE_DRAGON, human.db._id)
    if myRank then
        local rankData = BillboardDB.getRankData(BillboardDefine.TYPE_DRAGON, myRank)
        if rankData then
            msgRet.myRank[0] =  msgRet.myRank[0] + 1
            local net =   msgRet.myRank[msgRet.myRank[0]]
            net.rank = myRank
            if rankData and rankData.roleBase then
                RoleLogic.makeRoleBase(rankData.roleBase, net.roleBase)
            else
                local roleUuid = rankData and rankData.uuid or ""
                RoleLogic.getRoleBaseByUuid(roleUuid, net.roleBase)
            end
            net.hurt = rankData and rankData.value1 or 0
        end

        -- 自己在前四名 不显示 自己的前一名
        if myRank and myRank > 4 then
            local lastData = BillboardDB.getRankData(BillboardDefine.TYPE_DRAGON, myRank - 1)
            if lastData then
                msgRet.myRank[0] =  msgRet.myRank[0] + 1
                local net =   msgRet.myRank[msgRet.myRank[0]]
                net.rank = myRank - 1
                if lastData and lastData.roleBase then
                    RoleLogic.makeRoleBase(lastData.roleBase, net.roleBase)
                else
                    local roleUuid = lastData and lastData.uuid or ""
                    RoleLogic.getRoleBaseByUuid(roleUuid, net.roleBase)
                end
                net.hurt = lastData and lastData.value1 or 0
            end          
        end
       
    end
end

function fontNextItem(msgRet, human)
    local list = {}
    local get
    msgRet.nextSanbei = 1 
    for k, v in ipairs(CopyExcel.dragonReward) do
        if msgRet.dayHurt < v.need and not get then
            get = 1
            msgRet.nextHurt = v.need
            for j, h in ipairs(v.reward) do
                local net = msgRet.items[j]
                Grid.makeItem(net, h[1], h[2])
            end
            msgRet.items[0] = #v.reward
            if human.db.dragonCopy.historyGet and human.db.dragonCopy.historyGet[k] then
               msgRet.nextSanbei = 0
            end

        elseif msgRet.dayHurt >= v.need then
            local beiShu = human.db.dragonCopy.getDay and human.db.dragonCopy.getDay[k] or nil
            if not beiShu then
                if human.db.dragonCopy.historyGet and human.db.dragonCopy.historyGet[k] then
                    beiShu = 1
                else
                    beiShu = 3
                end
            end
            beiShu = beiShu or 1
            for j, h in ipairs(v.reward) do
                list[h[1]] = list[h[1]] or 0
                list[h[1]] = list[h[1]] + (h[2] * beiShu)
            end
        end
    end

    local len = 0
    for k, v in pairs(list) do
        len = len + 1 
        local net = msgRet.dayReward[len]
        Grid.makeItem(net, k, v)
    end
    msgRet.dayReward[0] = len 
end

-- 封装 BOSS 技能详情
function fontDragonSkill(msgRet, monsterOutID)
    local monsterID = MonsterExcel.monsterOut[monsterOutID].member[1][1]
    local monsterConfig = MonsterExcel.monster[monsterID]

    local len = 0
    for k, v in ipairs(monsterConfig.skillList) do
        len = len + 1
        HeroLogic.makeSkillNet(msgRet.skillList[len], v)
    end

    for k , v in ipairs(monsterConfig.beSkillList) do
        if len < 4 then
            len = len + 1
            HeroLogic.makeSkillNet(msgRet.skillList[len], v)
        end
    end       
    msgRet.skillList[0] = len 
end



function fontCiTiao(msgRet, human)
    local list = getSvrCiTiao()
    for k, index in pairs(list.citiao) do
        local config = CopyExcel.dragoncitiao[k]
        if index == 1 then
            msgRet.ciTiaoA = config.citiao
        elseif index == 2 then
            msgRet.ciTiaoB =  config.citiao
        else
            msgRet.ciTiaoC =  config.citiao
        end
    end
end

function ciTiaoQuery(human)
    init(human)

    local list = getSvrCiTiao()
    local dragon = human.db.dragonCopy
    local msgRet = Msg.gc.GC_COPY_DRAGON_BOSS_CITIAO
    msgRet.time = dragon.time
    msgRet.read = dragon.read and 1 or 0
    msgRet.isGuide = human.db.dragonCopy and human.db.dragonCopy.isGuide or 1
    msgRet.ctEndTime = getNextCiTiaoTime()
    human.db.dragonCopy.isGuide = 0
    local len = 0
    for id in pairs(list.citiao) do
        len = len + 1
        local config = CopyExcel.dragoncitiao[id]
        local net = msgRet.list[len]
        net.id   = id
        net.name = config.citiao
        net.desc = config.miaoshu
    end
    msgRet.list[0] = len
    Msg.send(msgRet, human.fd)
    dragon.read = 1
end

function query(human, isFight)
    init(human)
    
    if not human.db.dragonCopy.read then 
        ciTiaoQuery(human)
        return 
    end
    
    local msgRet = Msg.gc.GC_COPY_DRAGON_QUERY
    msgRet.dayGet = 0
    msgRet.topRank[0] = 0
    msgRet.myRank[0] = 0
    msgRet.dayHurt = 0
    msgRet.nextHurt = 0 
    msgRet.items[0] = 0
    msgRet.ciTiaoA = ""
    msgRet.ciTiaoB = ""
    msgRet.ciTiaoC = ""
    msgRet.dayReward[0] = 0
    msgRet.ctEndTime = getNextCiTiaoTime()
    msgRet.isFight = isFight and 1 or 0
    if human.db.dragonCopy then
        msgRet.dayHurt = human.db.dragonCopy.dayHurt
        msgRet.dayGet = human.db.dragonCopy.dayGet and 1 or 0
    end
    fontCiTiao(msgRet)
    fontNextItem(msgRet, human)
    fontRank(msgRet, human)

    human.dragonfirstLogin = 1
    RoleSystemLogic.onDot(human, RoleSystemDefine.ROLE_SYS_ID_1202)
    RoleSystemLogic.onDot(human, RoleSystemDefine.ROLE_SYS_ID_1209)
   -- Msg.trace(msgRet)
    Msg.send(msgRet, human.fd)
end

-- BOSS查询    
function bossQuery(human)
    local msgRet = Msg.gc.GC_COPY_DRAGON_BOSS_QUERY
    local config = CopyExcel.dragon[1]
    msgRet.id = 1
    msgRet.desc = config.desc
    fontDragonSkill(msgRet, config.monsterOutID)
    Msg.send(msgRet, human.fd)
end

-- 伤害排名 查询
function rankQuery(human)
    local msgRet = Msg.gc.GC_COPY_DRAGON_RANK_QUERY
    msgRet.rankList[0] = 0
    local board = BillboardDB.getBoard(BillboardDefine.TYPE_DRAGON)
	if board then 
        for i = 1, #board.rank2data do
            local rankData = board.rank2data[i]
            if rankData then
                msgRet.rankList[0] = msgRet.rankList[0] + 1
                local net = msgRet.rankList[msgRet.rankList[0]]
                net.rank = i
                if rankData and rankData.roleBase then
                    RoleLogic.makeRoleBase(rankData.roleBase, net.roleBase)
                else
                    local roleUuid = rankData and rankData.uuid or ""
                    RoleLogic.getRoleBaseByUuid(roleUuid, net.roleBase)
                end
                net.hurt = rankData and rankData.value1 or 0
            end           
        end
    end

    -- 获取排行区间 奖励  给予前端处理 放到各个名词后面  显示排名奖励
    for k, v in ipairs(CopyExcel.dragonRank) do
        local net = msgRet.rankItem[k]
        net.minRank = v.minRank
        net.maxRank = v.maxRank
        for j, h in ipairs(v.reward) do
            Grid.makeItem(net.item[j], h[1], h[2])
        end
        net.item[0] = #v.reward
    end
    msgRet.rankItem[0] = #CopyExcel.dragonRank
    Msg.send(msgRet, human.fd)
end

function hurtRewardQuery(human)
    local msgRet = Msg.gc.GC_COPY_DRAGON_HURT_QUERY
    msgRet.isEnd = 0
    msgRet.maxHurt = human.db.dragonCopy and human.db.dragonCopy.maxHurt or 0
    local len = 0
    for k, v in ipairs(CopyExcel.dragonReward) do
        len = len + 1
        local net = msgRet.list[len]
        net.id = k
        net.need = v.need
        net.sanbei = 1
        net.isGet = 0
        if human.db.dragonCopy.historyGet and human.db.dragonCopy.historyGet[k] then
           net.sanbei = 0
        end

        if human.db.dragonCopy.getDay and human.db.dragonCopy.getDay[k] then
            net.isGet = 1
        end
        for j, h in ipairs(v.reward) do
            Grid.makeItem(net.reward[j], h[1], h[2])
        end
        net.reward[0] = #v.reward
        if len >= 30 then
            msgRet.list[0] = len
            Msg.send(msgRet, human.fd)
            len = 0
        end
    end
    msgRet.isEnd = 1 
    msgRet.list[0] = len
    Msg.send(msgRet, human.fd)
end

------------------------------------ combat ----------------
function getCombatMonsterOutID(human, side, args)
	if side ~= CombatDefine.DEFEND_SIDE then return end
    local config = CopyExcel.dragon[1]
	return config.monsterOutID
end

function getCombatObjList(human, side, args)
	if side ~= CombatDefine.DEFEND_SIDE then return end
    local monsterOutID = getCombatMonsterOutID(human, side)
    return CombatLogic.getMonsterObjList(monsterOutID, CombatDefine.COMBAT_OBJ_TYPE3 , args)
end

function getMapID()
    local config = CopyExcel.dragon[1]
    return config.mapID
end

function fight(human)
    -- 今日已经领取 不让继续挑战  前端已做置灰处理
    --if human.db.dragonCopy and human.db.dragonCopy.dayGet then
        --return
    --end
    local config = CopyExcel.dragon[1]
    CombatLogic.combatBegin(human, config.mapID, 1 , CombatDefine.COMBAT_TYPE20)

	HeroGrowUp.onCallback(human, HeroGrowUp.TASKTYPE9, 1)
    YunYingLogic.onCallBack(human, "onBinglong",1)   
end

function setSkillAndBeskill(human,combatInfo)
    local list = getSvrCiTiao()
    
    local myList = {}
    local bossList = {}

    for k, v in pairs(list.citiao) do
        local config = CopyExcel.dragoncitiao[k]
        if config.shengxiao == CITIAO_BY_ATTACK then
            myList[#myList+1] = config.skillID
        elseif config.shengxiao == CITIAO_BY_DEFEND then
            bossList[#bossList+1] = config.skillID
        end
    end

    if #myList > 0 then
        for _,pos in ipairs(CombatDefine.SIDE2POS[CombatDefine.ATTACK_SIDE]) do
            local obj = CombatImpl.objList[pos]
            if obj then
                for _, skillID in ipairs(myList) do      
                    local skillConfig = SkillExcel[skillID]
                    if skillConfig.beSkillType == BeSkill.BESKILL_TYPE24 then
                        for _,skillID in ipairs(skillConfig.args) do
                            local skillConfig = SkillExcel[skillID]
                            obj.beSkillList[skillConfig.beSkillType] = obj.beSkillList[skillConfig.beSkillType] or {}
                            obj.beSkillList[skillConfig.beSkillType][#obj.beSkillList[skillConfig.beSkillType] + 1] = {
                            skillID,
                            skillConfig.beSkillLimit > 0 and skillConfig.beSkillLimit,skillConfig.cd[1] or 0,
                            skillConfig.cd[2] or 0, 0}                                   
                        end
                    else
                        obj.beSkillList[skillConfig.beSkillType] = obj.beSkillList[skillConfig.beSkillType] or {}
                        obj.beSkillList[skillConfig.beSkillType][#obj.beSkillList[skillConfig.beSkillType] + 1] = {
                        skillID,
                        skillConfig.beSkillLimit > 0 and skillConfig.beSkillLimit,skillConfig.cd[1] or 0,
                        skillConfig.cd[2] or 0, 0}        
                    end
                end
            end
        end
    end

    if #bossList > 0  then
        for _,pos in ipairs(CombatDefine.SIDE2POS[CombatDefine.DEFEND_SIDE]) do
            local obj = CombatImpl.objList[pos]
            if obj then
                for _, skillID in ipairs(bossList) do        
                    local skillConfig = SkillExcel[skillID]
                    if skillConfig.beSkillType == BeSkill.BESKILL_TYPE24 then              
                        for _,skillID in ipairs(skillConfig.args) do
                            local skillConfig = SkillExcel[skillID]
                            obj.beSkillList[skillConfig.beSkillType] = obj.beSkillList[skillConfig.beSkillType] or {}
                            obj.beSkillList[skillConfig.beSkillType][#obj.beSkillList[skillConfig.beSkillType] + 1] = {
                            skillID,
                            skillConfig.beSkillLimit > 0 and skillConfig.beSkillLimit,skillConfig.cd[1] or 0,
                            skillConfig.cd[2] or 0, 0}
                        end
                    else
                        obj.beSkillList[skillConfig.beSkillType] = obj.beSkillList[skillConfig.beSkillType] or {}
                        obj.beSkillList[skillConfig.beSkillType][#obj.beSkillList[skillConfig.beSkillType] + 1] = {
                        skillID,
                        skillConfig.beSkillLimit > 0 and skillConfig.beSkillLimit,skillConfig.cd[1] or 0,
                        skillConfig.cd[2] or 0, 0}        
                    end 
                end
            end
        end
    end	
end

function onFightEnd(human, result, combatType, cbParam, combatInfo)
    local atkHurt = 0
	for pos = 1, CombatDefine.COMBAT_HERO_CNT do
		local obj = combatInfo.objList and combatInfo.objList[pos]
		if obj then
			atkHurt = atkHurt + obj.result[1]
		end
	end

    -- 魔兽 造成伤害
    for _,pos in ipairs(CombatDefine.SIDE2HELPPOS[CombatDefine.ATTACK_SIDE]) do
		local pet = combatInfo.helpList and combatInfo.helpList[pos]
		if pet and pet.isPet then
            atkHurt = atkHurt + pet.result[1]
		end
	end

    human.db.dragonCopy = human.db.dragonCopy or {}
    local dragon = human.db.dragonCopy
    dragon.time = dragon.time or os.time()
    dragon.hurt = atkHurt
    dragon.dayHurt = dragon.dayHurt or 0
    local oldHurt = dragon.dayHurt
    local breakOk 
    if  atkHurt >  dragon.dayHurt then
        dragon.dayHurt = atkHurt
        dragon.maxHurt = dragon.maxHurt or 0
        dragon.maxHurt =  dragon.maxHurt < atkHurt and atkHurt or  dragon.maxHurt
        BRoleLogic.updateData(BillboardDefine.TYPE_DRAGON, human.db)
        breakOk = true
    end
    	
    local dayHurt = human.db.dragonCopy.dayHurt
    local msgRet = Msg.gc.GC_COPY_DRAGON_FIGHT_END 
    msgRet.rank = BillboardDB.getRank(BillboardDefine.TYPE_DRAGON, human.db._id) or 0
    msgRet.hurt = atkHurt
    msgRet.dayHurt = dragon.dayHurt
    msgRet.nextHurt = 0

    for k, v in ipairs(CopyExcel.dragonReward) do
        if dayHurt < v.need then 
            msgRet.nextHurt = v.need
            break
        end
    end

    if atkHurt> oldHurt then 
        if human.db.dragonCopy.dayGet then return end
        
        human.db.dragonCopy.historyGet = human.db.dragonCopy.historyGet or {}
        human.db.dragonCopy.getDay = human.db.dragonCopy.getDay or {}
        local getCnt = 0

        local getList = {}
        for k, v in ipairs(CopyExcel.dragonReward) do
            if dayHurt >= v.need  and not human.db.dragonCopy.getDay[k] then 
                getCnt = getCnt + 1
                local cnt = 1
                if not human.db.dragonCopy.historyGet[k] then
                   cnt = 3
                   human.db.dragonCopy.historyGet[k] = 1
                end
                if cnt == 3 then
                   combatInfo.double = 3
                end
                human.db.dragonCopy.getDay[k] = cnt

                for _, h in ipairs(v.reward) do
                    getList[h[1]] = getList[h[1]] or 0
                    getList[h[1]] = getList[h[1]] + h[2] * cnt
                end               
            end
        end
        -- 没有奖励可以领取
        if getCnt > 0 then
            local itemList = {}
            local len = 0
            for itemID, itemCnt in pairs(getList) do
                len = len + 1
                itemList[len] = {}
                itemList[len][1] =  itemID
                itemList[len][2] = itemCnt
                BagLogic.addItem(human, itemID, itemCnt, "dragonCopy")
            end
            combatInfo.rewardItem = Util.copyTable(itemList)
            
        end        
    end
    CombatLogic.fontCombatFinish(msgRet.data, combatInfo)
    Msg.send(msgRet, human.fd)
    
    ChengjiuLogic.onCallback(human,ChengjiuDefine.CJ_TASK_TYPE_26,atkHurt)
    MengxinLogic.onCallBack(human,MengxinLogic.MX_TASK_TYPE_5,atkHurt)


    query(human, true)

    if breakOk then
        human.db.dragonCopy.maxCombatInfo = Util.copyTable(combatInfo)        
    end

    --周任务 -9
    WeekTaskLogic.recordWeekTaskFinishCnt(human, WeekTaskLogic.WEEK_TASK_ID_9, 1)

    TriggerLogic.PublishEvent(TriggerDefine.DRAGONNEST_CHALLENGE, human.db._id, 1)
end


function isDot(human)
    if human.dragonfirstLogin == nil then
       return true 
    end
    return false
end


FieldDragonBase = {dragonCopy=1}
function lookVido(human, uuid)
    if not uuid or uuid == "" then return end
    local db = RoleDBLogic.getDb(uuid, FieldDragonBase)
    if db and db.dragonCopy and db.dragonCopy.maxCombatInfo then
        CombatLogic.repeatCombat(human, db.dragonCopy.maxCombatInfo)
    else
        return Broadcast.sendErr(human, Lang.COMBAT_ERR_NOT_VIDEO)
    end
end