--[[
    数据库设计
    relic = {
        [camp] = {
            isLock = 1  -- 是否被锁住
            lv = 0      -- 等级
            exp = 0     -- 经验
            quality = 0 -- 品阶
            star = 0 -- 星
            tupoLv = 0  -- 突破等级
            lvAttr = {[key] = value}
            qualityAttr = {[key] = value}
            tupoAttr = {[key] = value}
        }
    }
]]
local Msg = require("core.Msg")
local RelicExcel = require("excel.relic")
local HeroLogic = require("hero.HeroLogic")
local HechengLogic = require("hecheng.HechengLogic")
local FenjieLogic = require("hecheng.FenjieLogic")
local Grid = require("bag.Grid")
local Broadcast = require("broadcast.Broadcast")
local Util = require("common.Util")
local Lang = require("common.Lang")

local function initDB(human)
    if human.db.relic then
        return
    end
    -- 初始化信息
    for i = 1,5 do
        human.db.relic[i] = {}
        human.db.relic[i].isLock = 1
        human.db.relic[i].lv = 1
        human.db.relic[i].exp = 0

        human.db.relic[i].quality = 0
        human.db.relic[i].star = 0
        human.db.relic[i].tupoLv = 0
        human.db.relic[i].lvAttr = {}
        human.db.relic[i].qualityAttr = {}
        human.db.relic[i].tupoAttr = {}
    end
    -- 第一阵营默认为已解锁状态
    human.db.relic[1].isLock = 0
end

local function getJinjieState(human,camp)
    initDB(human)
    local db = human.db.relic[camp]
    local nextQuality = db.quality + 1
    local config = RelicExcel.jinjie[nextQuality]
    if not config then
        return 0            -- 已达到最大阶数
    end

    if db.lv < config.needLv then
        return 1            -- 等级不够
    end

    -- 检查材料是否足够
	if human.db.jinbi < config.jinbi then
		return 2            -- 材料不足
	end

    local len = #config.item
    for i = 1,len do
	    if BagLogic.getItemCnt(human, config.item[i][1]) < config.item[i][2] then
	    	return 2        -- 材料不足
	    end
    end

    return 3            -- 可以进阶
end

-- 获取突破状态
local function getTupoState(human,camp)
    initDB(human)
    local db = human.db.relic[camp]
    local nextTupo = db.tupoLv + 1
    local config = RelicExcel.tupo[nextTupo]
    if not config then
        return 0    -- 配置错误，或已达到最大等级
    end
    
    if db.quality < config.quality then
        return 1    -- 阶数不够
    end

    -- 检查材料是否足够
	if human.db.jinbi < config.jinbi then
		return 2    -- 材料不足
	end

    local len = #config.item
    for i = 1,len do
	    if BagLogic.getItemCnt(human, config.item[i][1]) < config.item[i][2] then
	    	return 2    -- 材料不足
	    end
    end

    return 3        -- 可以突破
end

local function getAttrTb(human,camp)
    initDB(human)
    local db = human.db.relic[camp]
    local attrTb = {}
    for k,v in pairs(db.lvAttr) do
        attrTb[k] = attrTb[k] or 0
        attrTb[k] = attrTb[k] + v
    end
    for k,v in pairs(db.qualityAttr) do
        attrTb[k] = attrTb[k] or 0
        attrTb[k] = attrTb[k] + v
    end
    for k,v in pairs(db.tupoAttr) do
        attrTb[k] = attrTb[k] or 0
        attrTb[k] = attrTb[k] + v
    end
    return attrTb
end


-- 界面查询
function relicQuery(human,camp)
    -- 等级限制  todo
    if human.db.lv < 1 then
        return
    end

    -- 初始化数据
    initDB(human)

    if human.db.relic[camp].isLock ~= 1 then
        -- 未解锁
        unlockReturn(human,camp)
    else
        -- 已解锁
        lvUpReturn(human,camp)
    end

end

-- 未解锁界面返回
function unlockReturn(human,camp)
    local msgRet = Msg.gc.GC_RELIC_UNLOCK_QUERY_RETURN
    for i = 1,5 do
        msgRet.lockMsg[i] = human.db.relic[i].isLock
    end
    msgRet.lockMsg[0] = 5

    HeroLogic.makeUpStarCond(msgRet.unlockNeed, RelicExcel.unlock[i].unlockNeed)
    Msg.send(msgRet,human.fd)
end

-- 解锁
function unlockDo(human,camp,inputIDList,inputIndexList)
    -- 初始化数据
    initDB(human)
    
    local db = human.db.relic[camp]
    if db.isLock ~= 1 then
        return
    end

    if not HechengLogic.checkCond(human, inputIDList, inputIndexList, RelicExcel.unlock[camp].unlockNeed) then
		return
	end

    local fenjieList = FenjieLogic.fenjie(human, FenjieLogic.FENJIE_DO_JUEXING, inputIDList, inputIndexList)

    db.isLock = 0
    db.lv = 1
    local config = RelicExcel.lvup[db[camp].lv]
    local len = #config.attrAdd[camp]
    for i = 1,len do
        local key = config.attrAdd[camp][i][1]
        local value = config.attrAdd[camp][i][2]
        db.lvAttr[key] = db.lvAttr[key] or 0
        db.lvAttr[key] = db.lvAttr[key] + value
    end

    local msgRet = Msg.gc.GC_RELIC_UNLOCK_RETURN
    msgRet.camp = camp
    Msg.send(msgRet,human.fd)
    relicQuery(human,camp)
end

-- 升级界面返回
function lvUpReturn(human,camp)
    local msgRet = Msg.gc.GC_RELIC_LVUP_QUERY_RETURN
    local db = human.db.relic
    for i = 1,5 do
        msgRet.lockMsg[i] = db[i].isLock
    end
    msgRet.lockMsg[0] = 5
    local config = RelicExcel.lvup[db[camp].lv]
    msgRet.lv = db[camp].lv 
    msgRet.maxExp = config.exp
    msgRet.exp = db[camp].exp 
    msgRet.jinbi = config.jinbi
    local len = #config.item
    for i = 1,len do
        Grid.makeItem(msgRet.item[i],config.item[i][1],config.item[i][2])
    end
    msgRet.item[0] = len
    local attrTb = getAttrTb(human,camp)
    local count = 0
    for k,v in pairs(attrTb) do
        count = count + 1
        msgRet.attr[count].key = k
        msgRet.attr[count].value = v
    end
    msgRet.attr[0] = count

    Msg.send(msgRet,human.fd)
end

-- 升级
function lvUpDo(human,camp)
    -- 初始化数据
    initDB(human)

    -- 未解锁，返回
    local db = human.db.relic[camp]
    if db.isLock == 1 then
        return
    end

    -- 最大等级
    local maxLv = #RelicExcel.lvup

    -- 已经是最大等级
    if db.lv >= maxLv then
        return
    end
    local config = RelicExcel.lvup[db.lv]

    -- 检查材料是否足够
	if human.db.jinbi < config.jinbi then
		return Broadcast.sendErr(human, Lang.COMMON_NO_JINBI)
	end

    local len = #config.item
    for i = 1,len do
	    if BagLogic.getItemCnt(human, config.item[i][1]) < config.item[i][2] then
	    	local strName = ItemDefine.getValue(config.item[i][1], "name")
	    	return Broadcast.sendErr(human, Util.format(Lang.COMMON_NO_ITEM, strName))
	    end
    end

    -- 扣除材料
	ObjHuman.updateJinbi(human, -config.jinbi, "relic_lvup")
    for i = 1,len do
	    BagLogic.delItem(human, config.item[i][1], config.item[i][2], "relic_lvup")
    end

    -- 增加经验
    db.exp = db.exp + config.upExp
    if db.exp >= config.exp then
        db.exp = 0
        db.lv = db.lv + 1
    end

    local len = #RelicExcel.lvup[db.lv].attrAdd[camp]
    for i = 1,len do
        local key = RelicExcel.lvup[db.lv].attrAdd[camp][i][1]
        local value = RelicExcel.lvup[db.lv].attrAdd[camp][i][2]
        db.lvAttr[key] = db.lvAttr[key] or 0
        db.lvAttr[key] = db.lvAttr[key] + value
    end

    relicQuery(human,camp)
end

function jinjieQuery(human,camp)
    -- 初始化数据
    initDB(human)

    -- 未解锁，返回
    local db = human.db.relic[camp]
    if db.isLock == 1 then
        return
    end

    local nextQuality = db.quality + 1
    local config = RelicExcel.jinjie[nextQuality]
    if not config then
        return
    end
    local msgRet = Msg.gc.GC_RELIC_JINJIE_QUERY
    if config.tupo == 1 then 
        local nextTupoLv = db.tupoLv + 1
        if nextTupoLv <= #RelicExcel.tupo then
            config = RelicExcel.tupo[nextTupoLv]
        end
        msgRet.unlockNeed[0] = 1
        HeroLogic.makeUpStarCond(msgRet.unlockNeed[1], config.unlockNeed)
    else
        msgRet.unlockNeed[0] = 0
    end
    msgRet.quality = db.quality
    msgRet.star = db.satr
    msgRet.tupoLv = db.tupoLv
    msgRet.jinbi = config.jinbi
    msgRet.needLv = config.needLv
    msgRet.canJinjie = getJinjieState(human,camp)
    msgRet.canTupo = getTupoState(human,camp)
    local count = 0
    local attrTb = getAttrTb(human,camp)
    for k,v in pairs(attrTb) do
        count = count + 1
        msgRet.attr[count].key = k
        msgRet.attr[count].value = v
    end
    msgRet.attr[0] = count
    local len = #config.item
    for i = 1,len do
        Grid.makeItem(msgRet.item[i],config.item[i][1],config.item[i][2])
    end
    msgRet.item[0] = len

    Msg.send(msgRet,human.fd)
end

-- 进阶预览
function yulanQuery(human,camp)
    local config = RelicExcel.jinjie
    local msgRet = Msg.gc.GC_RELIC_JINJIE_YULAN_QUERY
    local len = #config 
    for i = 1,len do
        msgRet.yulan[i].quality = i
        msgRet.yulan[i].desc = config[i].desc
        local attrLen = #RelicExcel.lvup[i].attr[camp]
        for j = 1,attrLen do
            count = count + 1
            local key = RelicExcel.lvup[i].attr[camp][j][1]
            local value = RelicExcel.lvup[i].attr[camp][j][2]
            msgRet.yulan[i].attr[count].key = k
            msgRet.yulan[i].attr[count].value = v
        end
        msgRet.attr[0] = count
    end
    msgRet.yulan[0] = len

    Msg.send(msgRet,human.fd)
end

-- 进阶
function jinjieDo(human,camp)
    -- 初始化数据
    initDB(human)

    -- 未解锁，返回
    local db = human.db.relic[camp]
    if db.isLock == 1 then
        return
    end

    -- 已经是最大阶数
    local nextQuality = db.quality + 1
    local config = RelicExcel.jinjie[nextQuality]
    if not config then
        return
    end

    -- 需要等级不达标
    if db.lv < config.needLv then
        return
    end

    -- 需要突破等级不达标
    if db.tupoLv < config.needTupo then
        return
    end

    -- 检查材料是否足够
	if human.db.jinbi < config.jinbi then
		return Broadcast.sendErr(human, Lang.COMMON_NO_JINBI)
	end

    local len = #config.item
    for i = 1,len do
	    if BagLogic.getItemCnt(human, config.item[i][1]) < config.item[i][2] then
	    	local strName = ItemDefine.getValue(config.item[i][1], "name")
	    	return Broadcast.sendErr(human, Util.format(Lang.COMMON_NO_ITEM, strName))
	    end
    end
   
    -- 扣除材料
	ObjHuman.updateJinbi(human, -config.jinbi, "relic_jinjie")
    for i = 1,len do
	    BagLogic.delItem(human, config.item[i][1], config.item[i][2], "relic_jinjie")
    end

    -- 进阶
    db.quality = nextQuality
    db.satr = db.satr + 1
    local len = #config.attrAdd[camp]
    for i = 1,len do
        local key = config.attrAdd[camp][i][1]
        local value = config.attrAdd[camp][i][2]
        db.qualityAttr[key] = db.qualityAttr[key] or 0
        db.qualityAttr[key] = db.qualityAttr[key] + value
    end

    jinjieQuery(human,camp)
end

-- 突破
function tupoDo(human,camp,inputIDList, inputIndexList)
    -- 初始化数据
    initDB(human)

    -- 未解锁，返回
    local db = human.db.relic[camp]
    if db.isLock == 1 then
        return
    end

    -- 已经是最大阶数
    local nextTupoLv = db.tupoLv + 1
    local config = RelicExcel.tupo[nextTupoLv]
    if not config then
        return
    end

    -- 需要品阶不达标
    if db.quality < config.quality then
        return
    end

    -- 检查材料是否足够
	if human.db.jinbi < config.jinbi then
		return Broadcast.sendErr(human, Lang.COMMON_NO_JINBI)
	end

    local len = #config.item
    for i = 1,len do
	    if BagLogic.getItemCnt(human, config.item[i][1]) < config.item[i][2] then
	    	local strName = ItemDefine.getValue(config.item[i][1], "name")
	    	return Broadcast.sendErr(human, Util.format(Lang.COMMON_NO_ITEM, strName))
	    end
    end
    
    if not HechengLogic.checkCond(human, inputIDList, inputIndexList, RelicExcel.unlock[camp].unlockNeed) then
		return
	end

    local fenjieList = FenjieLogic.fenjie(human, FenjieLogic.FENJIE_DO_JUEXING, inputIDList, inputIndexList)
   
    -- 扣除材料
	ObjHuman.updateJinbi(human, -config.jinbi, "relic_jinjie")
    for i = 1,len do
	    BagLogic.delItem(human, config.item[i][1], config.item[i][2], "relic_jinjie")
    end

    -- 进阶
    db.tupoLv = nextTupoLv
    db.satr = 0

    local msgRet = Msg.gc.GC_RELIC_TUPO_RETURN
    msgRet.camp = camp
    msgRet.lv = db.tupoLv
    local count = 0
    for k,v in pairs(db.tupoAttr) do
        count = count + 1
        msgRet.befAttr[count].key = k
        msgRet.befAttr[count].value = v
    end
    msgRet.befAttr[0] = count
    
    local len = #config.attrAdd[camp]
    for i = 1,len do
        local key = config.attrAdd[camp][i][1]
        local value = config.attrAdd[camp][i][2]
        db.tupoAttr[key] = db.tupoAttr[key] or 0
        db.tupoAttr[key] = db.tupoAttr[key] + value
    end

    count = 0
    for k,v in pairs(db.tupoAttr) do
        count = count + 1
        msgRet.aftAttr[count].key = k
        msgRet.aftAttr[count].value = v
    end
    msgRet.aftAttr[0] = count
    Msg.send(msgRet,human.fd)
end

-- 计算圣器属性
function doCalcHero(human, grid, attrs)
    if not human then return end
    initDB(human)
	
	local heroConfig = HeroExcel.hero[grid.id]
    local relicCamp = human.db.relic[heroConfig.camp]

    for k,v in pairs(relicCamp.lvAttr) do
	    RoleAttr.updateValue(k,v,attrs)
    end
    
    for k,v in pairs(relicCamp.qualityAttr) do
	    RoleAttr.updateValue(k,v,attrs)
    end
    
    for k,v in pairs(relicCamp.tupoAttr) do
	    RoleAttr.updateValue(k,v,attrs)
    end
end
