--[[
    失落神庙 战斗模块
]]
local Msg = require("core.Msg")
local LuaMongo = _G.lua_mongo
local DB = require("common.DB")
local LostTempleExcel = require("excel.lostTemple")
local ElementExcel = require("excel.lostTemple").Element
local LostTempleLogic = require("lostTemple.lostTempleLogic")
local CombatLogic = require("combat.CombatLogic")
local CombatDefine = require("combat.CombatDefine")
local BagLogic = require("bag.BagLogic")
local Grid = require("bag.Grid")
local CombatObj = require("combat.CombatObj")
local CombatImpl = require("combat.CombatImpl")
local HeroGrid = require("hero.HeroGrid")
local HeroExcel = require("excel.hero")
local CombatPosLogic = require("combat.CombatPosLogic")
local MoshouLogic = require("moshou.MoshouLogic")
local JibanLogic = require("combat.JibanLogic")
local RoleDefine = require("role.RoleDefine")
local Util = require("common.Util")
local SkinLogic = require("skin.SkinLogic")
local XingYaoGongMing = require("xingYaoMen.XingYaoGongMing")
local BeSkill = require("combat.BeSkill")
local Skill = require("combat.Skill")
local RoleAttr = require("role.RoleAttr")
local ItemDefine = require("bag.ItemDefine")
local Broadcast = require("broadcast.Broadcast")
local Lang = require("common.Lang")
local YunYingLogic = require("yunying.YunYingLogic")
local RoleSystemLogic = require("roleSystem.RoleSystemLogic")
local RoleSystemDefine = require("roleSystem.RoleSystemDefine")
-------------------------------------- combat -----------------------------------------
-- 获取属性
function getHeroAttrs(human, index)
    human.lostTempleAttr = human.lostTempleAttr or { }
    if not human.lostTempleAttr[index] then
        human.lostTempleAttr[index] = RoleAttr.calcHeroGrid(human.lostTemple.summonHero[index], index, human)
    end
    return human.lostTempleAttr[index]
end

-- 根据uuid 获取heroGrid
function getHeroGridByUuid(human, uuid)
    if not uuid or uuid == "" or uuid == "0" then return end

    for index = 1, human.db.heroBag[0] do
        local heroGrid = human.db.heroBag[index]
        if heroGrid and type(heroGrid) == "table" then
            if heroGrid.uuid == uuid then
                return heroGrid
            end
        end
    end

    -- 获取临时背包的
    if human.lostTemple and human.lostTemple.summonHero then
        for i = 1, human.lostTemple.summonHero[0] do
            local heroGrid = human.lostTemple.summonHero[i]
            if heroGrid and type(heroGrid) == "table" then
                if heroGrid.uuid == uuid then
                    return heroGrid
                end
            end
        end
    end

    return nil
end

-- 阵容设定
function checkUpdatePos(human, msg)
    if not human.lostTemple then return end

    local posList = CombatPosLogic.getPosList(msg.formation)
    local heroList = Util.split(msg.heroList, ",")
    local helpList = Util.split(msg.helpList, ",", true)
    local cnt = 0
    local useList = { }
    local fatherList = { }

    -- 确定英雄存不存在
    for i = 1, CombatDefine.COMBAT_HERO_CNT do
        local uuid = heroList[i] or ""
        if uuid ~= "0" and uuid ~= "" then
            if i == CombatDefine.COMBAT_HERO_CNT and CombatPosLogic.canBackup(human) == 0 then
                -- 援军未激活
                return
            end

            if posList[i] == nil and i ~= CombatDefine.COMBAT_HERO_CNT then
                -- 站位不可用
                return
            end

            local heroGrid = getHeroGridByUuid(human, uuid)
            if not heroGrid then return end

            local heroConfig = HeroExcel.hero[heroGrid.id]
            if useList[uuid] or fatherList[heroGrid.id] then
                -- 同父类英雄重复
                return
            else
                cnt = cnt + 1
                useList[uuid] = true
                fatherList[heroGrid.id] = true
            end
        end
    end
    if cnt == 0 then
        -- 上阵英雄空
        return
    end
    -- 检查辅助对象是否激活 todo

    return true, heroList, helpList
end





-- 战斗前加属性
function onFightBegin(human, cbParam, combatType, param)
    local putY = tonumber(param[1])
    if not putY then return end

    local grid = LostTempleLogic.checkPutByY(human, putY)
    if not grid then return end
    if not grid.monsterOutID then return end

    for index = 1, CombatDefine.COMBAT_HERO_CNT do
        -- 攻方血量
        local atkPos = CombatLogic.getPos(CombatDefine.ATTACK_SIDE, index)
        local atkObj = CombatImpl.objList[atkPos]

        if atkObj ~= nil then
           -- 英雄状态
           if human.lostTemple.heroStatus then
              local hpRate = human.lostTemple.heroStatus[atkObj.uuid] or 1.0
              local hpMax = CombatObj.getHpMax(atkObj)
              atkObj.hp = math.ceil(hpMax * hpRate)
              if atkObj.hp <= 0 then
                 atkObj.hp = 1
              end

              if atkObj.hp >= hpMax then
                 atkObj.hp = hpMax
              end
           end

           -- 属性
           if human.lostTemple.summonTree then
              atkObj.isSysAttrChange = true
              for key, value in pairs(human.lostTemple.summonTree) do
                 atkObj.sysAttr[key] = atkObj.sysAttr[key] + value
              end
           end
        end

        -- 守方血量
        local defPos = CombatLogic.getPos(CombatDefine.DEFEND_SIDE, index)
        local defObj = CombatImpl.objList[defPos]
        local objStatus = grid.objStatus and grid.objStatus[defPos] or nil
        if defObj ~= nil and objStatus then
            local hpMax = CombatObj.getHpMax(defObj)
            defObj.hp = math.ceil(objStatus.hpRate * hpMax)
        end
    end
end


-- 根据英雄背包创建临时对象
function createHumanObj(human, uuid)
    if not uuid then return end
    local heroGrid = getHeroGridByUuid(human, uuid)
    if not heroGrid or type(heroGrid) ~= "table" then return end

    return CombatLogic.createHeroObjByHeroGrid(human, heroGrid)
end

-- 获取英雄阵容
function getHumanObjList(human, combatType)
    local teamType = CombatPosLogic.getTeamType(combatType)
    if not teamType then return end

    local combatHero, _, formation, combatHeroDB = CombatPosLogic.getCombatHeros(human, combatType)
    if not combatHero then return end
    if formation == 0 then
        formation = 1
    end

    local heroStatus = human.lostTemple.heroStatus
    local jiban = JibanLogic.getJibanHero(human, combatHeroDB)
    local objList = { }
    local zhandouli = 0
    for i = 1, CombatDefine.COMBAT_HERO_CNT do
        local uuid = combatHero[i]
        local obj = createHumanObj(human, uuid)
        if obj then
            local hpRate = heroStatus and heroStatus[uuid] or 1.0
            if hpRate > 0 then
               zhandouli = zhandouli + obj.attrs[RoleDefine.ZHANDOULI]
               objList[i] = obj
            else
               combatHero[i] = nil
            end
        end
    end
    local helpList = { }
    local pet = MoshouLogic.createCombatMoshow(human, combatType)
    helpList[CombatDefine.HELP_TYPE1] = pet
    local rolebase = CombatLogic.createRoleBaseByDB(human.db, zhandouli)

    -- 精灵
    local elfList = {}
    local combatElfList = combatHeroDB.elfList
    if combatElfList then
        for i=1, CombatDefine.COMBAT_ELF_CNT do
			local elfId = combatElfList[i]
			local elfObj = CombatLogic.createElfObj(human, elfId, i)
			if elfObj then
				elfList[i] = elfObj
			end
		end
    end


    return objList, helpList, rolebase, formation, jiban, elfList
end


-- 获取怪物组id
function getCombatMonsterOutID(human, side, args, combatType)
    if side == CombatDefine.ATTACK_SIDE then return end

    if not human.lostTemple then return end
    local putY = tonumber(args[1])
    if not putY then return end

    local grid = LostTempleLogic.checkPutByY(human, putY)
    if not grid then return end

    return grid.monsterOutID
end

-- 战斗
function fight(human, args)
    if not human.lostTemple then return end

    local putY = tonumber(args[1])
    if not putY then return end

    local grid = LostTempleLogic.checkPutByY(human, putY)
    if not grid then return end
    if not grid.monsterOutID then return end

    local power = CombatPosLogic.getCombatHeroZDL(human, CombatDefine.COMBAT_TYPE24)
    if power <= 0 then
        Broadcast.sendErr(human, Lang.COMBAT_ERR_NO_SET_FIGHT)
        return
    end

    CombatLogic.combatBegin(human, 1001, args, CombatDefine.COMBAT_TYPE24)
end


-- 战斗结束
function onFightEnd(human, result, combatType, cbParam, combatInfo, param)
    if not human.lostTemple then return end

    local putY = tonumber(param[1])
    if not putY then return end

    local grid = LostTempleLogic.checkPutByY(human, putY)
    if not grid then return end
    if not grid.monsterOutID then return end

    local elementConfig = ElementExcel[grid.id]
    if not elementConfig then return end

    local rewardConfig = LostTempleExcel.Drop[elementConfig.arg[1]]
    if not rewardConfig then return end

    local msgRet = Msg.gc.GC_LOST_TEMPLE_FIGHT_END
    msgRet.gdReward[0] = 0
    msgRet.randomReward[0] = 0
    if result == CombatDefine.RESULT_WIN then
        for _, item in ipairs(rewardConfig.drop) do
            msgRet.gdReward[0] = msgRet.gdReward[0] + 1
            Grid.makeItem(msgRet.gdReward[msgRet.gdReward[0]], item[1], item[2])
            BagLogic.addItem(human, item[1], item[2], "lostTemple")
        end

        local mathRandom = math.random(1, 10000)
        if mathRandom <= rewardConfig.randomdrop[1] then
            msgRet.randomReward[0] = 1
            local randomIndex = math.random(2, #rewardConfig.randomdrop)
            local randomItem = rewardConfig.randomdrop[randomIndex]

            human.lostTemple.randomReward = human.lostTemple.randomReward or { }
            human.lostTemple.randomReward[randomItem[1]] = human.lostTemple.randomReward[randomItem[1]] or 0
            human.lostTemple.randomReward[randomItem[1]] = human.lostTemple.randomReward[randomItem[1]] + randomItem[2]

            Grid.makeItem(msgRet.randomReward[1], randomItem[1], randomItem[2])
        end


        -- BOOS
        if not LostTempleLogic.putSet(human, putY, elementConfig.cmd) then
            LostTempleLogic.nextGrid(human, putY)
        else
            --通关判断
            if LostTempleLogic.IsPass(human) then
                YunYingLogic.onCallBack(human, "lostTempleCombat", 1)
                RoleSystemLogic.onDot(human, RoleSystemDefine.ROLE_SYS_ID_1208)
            end
        end
    else
        grid.objStatus = grid.objStatus or { }
        -- 更新防守方血量
        for index = 1, CombatDefine.COMBAT_HERO_CNT do
            local defPos = CombatLogic.getPos(CombatDefine.DEFEND_SIDE, index)
            local defObj = combatInfo.objList[defPos]
            if defObj ~= nil then
                local hp = defObj.hp
                local hpMax = CombatObj.getHpMax(defObj)
                local hpRate = hp / hpMax
                grid.objStatus[defPos] = grid.objStatus[defPos] or { }
                grid.objStatus[defPos].hpRate = hpRate
            end
        end
    end

    -- 更新攻击方血量
    local combatHero = CombatPosLogic.getCombatHeros(human, CombatDefine.COMBAT_TYPE24)
    human.lostTemple.heroStatus = human.lostTemple.heroStatus or { }
    for index = 1, CombatDefine.COMBAT_HERO_CNT do
        local atkPos = CombatLogic.getPos(CombatDefine.ATTACK_SIDE, index)
        local atkObj = combatInfo.objList[atkPos]
        if atkObj ~= nil then
            local hp = atkObj.hp
            local hpMax = CombatObj.getHpMax(atkObj)
            local hpRate = hp / hpMax
            if hpRate < 1.0 then
               human.lostTemple.heroStatus[atkObj.uuid] = hpRate
            end

            -- 阵上英雄下阵
            if combatHero and hp <= 0 then  
               for pos, uuid in pairs(combatHero) do
                  if uuid == atkObj.uuid then
                      combatHero[pos] = nil
                  end
               end
            end
        end
    end
    LostTempleLogic.dbSave(human)

    CombatLogic.fontCombatFinish(msgRet.data, combatInfo)
    Msg.send(msgRet, human.fd)
end

function isDot(human)
    --print("[LostTempleCombatLogic_isDot] 进入红点判断")
    if not RoleSystemLogic.isOpen(human, RoleSystemDefine.ROLE_SYS_ID_1208) then
        print("[LostTempleCombatLogic_isDot] 未开启该系统")
        return false
    end

    local bRet = LostTempleLogic.IsPass(human)
    if nil == bRet then
        print("[LostTempleCombatLogic_isDot] 没有获取到对应数据")
        return false
    end

    --print("[LostTempleCombatLogic_isDot] 没有获取到对应数据 bRet = "..(true == bRet and 1 or 0))

    return (bRet == false) and true or false
end