----------------------------------------
-- boss 挑战模块DB
----------------------------------------

local LuaMongo = _G.lua_mongo
local DB = require("common.DB")
local CombatDefine = require("combat.CombatDefine")
local CombatLogic = require("combat.CombatLogic")
local CombatObj = require("combat.CombatObj")
local RoleDefine = require("role.RoleDefine")

local QueryByUUID = {_id = nil}
local QueryByOwnUuid = {ownUuid = nil, bossType = nil}

BOSS_TYPE_UNION = 1  --公会副本BOSS

DEFAULT_HP_MAX = 100

function createBossData(bossType, ownUuid, monsterOutID, mapID, cbParam)
    local objList = CombatLogic.getMonsterObjList(monsterOutID, CombatDefine.COMBAT_OBJ_TYPE3)
    if not objList then return end

    local bossData = {}
    bossData.bossType = bossType            -- boss类型
    bossData.ownUuid = ownUuid              -- 归属Uuid,可能是玩家Uuid，也可能是公会
    bossData.monsterOutID = monsterOutID    -- 怪物组Id
    bossData.mapID = mapID                  -- 地图
    bossData.cbParam = cbParam              -- boss额外信息
    bossData.record = nil                   -- 伤害记录[uuid] = hurt
    bossData.objList = {}                   -- 怪物列表 剩余血量等 [index] = obj
    LuaMongo.insert(DB.db_boss, bossData) 
    return bossData
end

function updateBossData(bossData)
    if not bossData._id then return end
    QueryByUUID._id = bossData._id
    LuaMongo.update(DB.db_boss, QueryByUUID, bossData)
end

local BOSS_DATA_LIST = {}
function getBossDatas(bossType, ownUuid)    
    QueryByOwnUuid.ownUuid = ownUuid
    QueryByOwnUuid.bossType = bossType

    for k in pairs(BOSS_DATA_LIST) do
        BOSS_DATA_LIST[k] = nil
    end
    LuaMongo.find(DB.db_boss, QueryByOwnUuid)
    while true do
        local bossData = {}
        if not LuaMongo.next(bossData) then
            break
        end
        BOSS_DATA_LIST[#BOSS_DATA_LIST + 1] = bossData
    end
    return BOSS_DATA_LIST
end

function getBossData(uuid)
    if not uuid then return end
    QueryByUUID._id = uuid
    LuaMongo.find(DB.db_boss, QueryByUUID) 
    local bossData = {}
    if not LuaMongo.next(bossData) then return  end 
    return bossData
end

function removeBossData(uuid)
    if not uuid then return end
    QueryByUUID._id = uuid
    LuaMongo.remove(DB.db_boss, QueryByUUID)
end

--------------------------------------------------------------------
-- boss是否死亡
function isBossDie(bossData)
    if not bossData then return true end
    if not bossData.objList then return true end
    if not next(bossData.objList) then return end

    for _, obj in pairs(bossData.objList) do
        if obj.hp > 0 then
            return 
        end
    end
    return true
end

-- 获取boss hp
function getBossHp(bossData, index)
    local obj = bossData.objList[index]
    if not obj then return DEFAULT_HP_MAX end
    return obj.hp or DEFAULT_HP_MAX
end

function getBossHpMax(bossData, index)
    local obj = bossData.objList[index]
    if not obj then return DEFAULT_HP_MAX end
    if obj.hp and not obj.hpMax then return 0 end
    return obj.hpMax or DEFAULT_HP_MAX
end

function getBossHpSum(bossData)
    local sum = 0
    local cnt = 0
    for index, obj in pairs(bossData.objList) do
        sum = sum + getBossHp(bossData, index)
        cnt = cnt + 1
    end  
    return (cnt > 0) and sum or DEFAULT_HP_MAX
end

function getBossHpMaxSum(bossData)
    local sum = 0
    local cnt = 0
    for index, obj in pairs(bossData.objList) do
        sum = sum + getBossHpMax(bossData, index)
        cnt = cnt + 1
    end    
    return (cnt > 0) and sum or DEFAULT_HP_MAX
end

-- 刷新血量
function updateBossHp(bossData, index, combatObj)
    local obj = bossData.objList[index]
    if not obj then
        obj = {}
        obj.hpMax = CombatObj.getHpMax(combatObj) 
        obj.hp = obj.hpMax 
        bossData.objList[index] = obj
    end
    if not combatObj then
        obj.hp = 0
        return 0
    end
    local hurt = math.max(combatObj.initHp - combatObj.hp, 0)
    obj.hp = math.max(obj.hp - hurt, 0)
    return hurt
end

function updateBossHpByHurt(bossData, index, hurt, combatObj)
    local obj = bossData.objList[index]
    if not obj then
        obj = {}
        obj.hpMax = CombatObj.getHpMax(combatObj) 
        obj.hp = obj.hpMax 
        bossData.objList[index] = obj
    end
    obj = bossData.objList[index]
    if obj then
        local realHurt = math.min(obj.hp, hurt)
        obj.hp = math.max(obj.hp - hurt, 0)
        return realHurt
    end
    return 0
end

function updateBossHpSaoDang(bossData, index, hurt)
    local obj = bossData.objList[index]

    if obj then
        local realHurt = math.min(obj.hp, hurt)
        obj.hp = math.max(obj.hp - hurt, 0)
        return realHurt
    end
    return 0
end

-- 伤害记录
function updateBossRecord(bossData, uuid, hurt)
    bossData.record = bossData.record or {}
    bossData.record[uuid] = bossData.record[uuid] or {}
    local record = bossData.record[uuid]
    record.hurt = (record.hurt or 0) + hurt
    record.time = os.time()
    record.uuid = uuid
end

-- 点赞记录
function updateBossRecordLike(bossData,  target)
    bossData.record = bossData.record or {}
    bossData.record[target] = bossData.record[target] or {}
    local record = bossData.record[target]
    record.like = record.like or 0
    record.like = record.like + 1
end

local function cmpHurt(a, b)
    if a.hurt ~= b.hurt then
        return a.hurt > b.hurt
    end
    return a.time < b.time
end

local HURT_BOARD_LIST = {}
function getHurtBoard(bossData)
    if not bossData then return end
    if not bossData.record then return end

    for k in pairs(HURT_BOARD_LIST) do
        HURT_BOARD_LIST[k] = nil
    end
    local cnt = 0
    for uuid, record in pairs(bossData.record) do
        cnt = cnt + 1
        HURT_BOARD_LIST[cnt] = record
    end
    if cnt > 1 then
        table.sort(HURT_BOARD_LIST, cmpHurt)
    end
    return HURT_BOARD_LIST
end

