--秘宝系统
--[=[
    db
    human.db.talismanData = 
    {
        [ID1] = level,
        [ID2] = level,
    } 
]=]--
local Msg = require("core.Msg")
local Grid = require("bag.Grid")
local BagLogic = require("bag.BagLogic")
local Lang = require("common.Lang")
local RoleAttr = require("role.RoleAttr")
local RoleDefine = require("role.RoleDefine")
local ObjHuman = require("core.ObjHuman")
local Broadcast = require("broadcast.Broadcast")
local talismanConfig = require("excel.talisman").talisman
local HeroConfig = require("excel.hero").hero
local HuanJingTowerLogic = require("huanjingTower.HuanjingTowerLogic")
local RoleSystemLogic = require("roleSystem.RoleSystemLogic")
local RoleSystemDefine = require("roleSystem.RoleSystemDefine")
local TriggerDefine = require("trigger.TriggerDefine")
local TriggerLogic = require("trigger.TriggerLogic")
local ChengjiuLogic = require("chengjiu.ChengjiuLogic")

local GiftLogic

local LOGTYPE = "talisman"
local COND_TOWER_LEVEL = 100 --开启本系统需要通关恶魔之塔的层数

local TALISMAN_2_CHENGJIU_TASKID = 404 -- 秘宝系统对应的成就任务Id

--秘宝对挂机钻石/情报等其他方面增益标识
OTHER_EFFECT_TBL = {
    ["GJ_QB"] = "GJ_QB",                            --挂机情报类型
    ["GJ_ZS"] = "GJ_ZS",                            --挂机钻石类型
    ["GJ_HERO_EXP"] = "GJ_HERO_EXP",                --挂机英雄经验类型
    ["GJ_HANG_HOURS"] = "GJ_HANG_HOURS",            --挂机最大时间类型
    ["GJ_SD_FREE_CNT"] = "GJ_SD_FREE_CNT",          --每日扫荡次数类型
    ["DJ"] = "DJ",                                  --点金
    ["NW_JB"] = "NW_JB",                            --女巫森林金币类型
    ["NW_HERO_EXP"] = "NW_HERO_EXP",                --女巫森林英雄经验类型
    ["NW_LHS"] = "NW_LHS",                          --女巫森林龙魂石
    ["DRILL_HERO_EXP"] = "DRILL_HERO_EXP",          --勇者试炼英雄经验
    ["ZHANBU_MAX_POINTS"] = "ZHANBU_MAX_POINTS",    --占卜最大积分类型
    ["JYZH_LOTTERY10"] = "JYZH_LOTTERY10",          --精英召唤10连类型
    ["NW_FWJH"] = "NW_FWJH",                        --女巫森林符文精华
    ["NW_CHALLENGE_TIMES"] = "NW_CHALLENGE_TIMES",  --女巫森林所有类型挑战次数
    ["XUANSHANG_QB_MAX"] = "XUANSHANG_QB_MAX",      --悬赏情报上限
    ["ZHANBU_POS6"] = "ZHANBU_POS6",                --占卜解锁格子6
    ["ZHANBU_POS7"] = "ZHANBU_POS7",                --占卜解锁格子7
    ["ZHANBU_FRAGMENT"] = "ZHANBU_FRAGMENT",        --占卜获得碎片加成
    ["BATTLE_ISQUICKTIME"] = "BATTLE_ISQUICKTIME",  --主线闯关跳过战斗
    ["YJ_DAILY_SD"] = "YJ_DAILY_SD",                -- 遗迹探险每日额外扫荡次数
    ["HJ_DAILY_Free"] = "HJ_DAILY_Free",            -- 恶魔之塔每日额外免费次数

    ["HeroSeed_Attr_Mul"] = "HeroSeed_Attr_Mul",    -- 英雄种子系统加成
    ["RoleReal_Attr_Mul"] = "RoleReal_Attr_Mul",    -- 境界系统加成
    ["WinnerRelic_Attr_Mul"] = "WinnerRelic_Attr_Mul", -- 圣遗物系统通用属性加成
    ["Elf_Attr_Mul"] = "Elf_Attr_Mul",              -- 精灵系统通用属性加成
    ["Moshou_LvAttr_Mul"] = "Moshou_LvAttr_Mul",    -- 守护凤凰系统等级加成属性的加成

    ["HeroExclusiveWeapon_Attr_Mul"] = "HeroExclusiveWeapon_Attr_Mul",    -- 英雄专属武器系统加成
    ["HeroTianYuan_Attr_Mul"] = "HeroTianYuan_Attr_Mul",                  -- 英雄天元系统加成
    ["HeroArtifacts_LvAttr_Mul"] = "HeroArtifacts_LvAttr_Mul",            -- 英雄神威灵装系统加成
    ["HeroPubLogic_Attr_Mul"] = "HeroPubLogic_Attr_Mul",                  -- 英雄酒馆系统加成
}

--是否开启本系统
local function isOpen(human)
    local state = ChengjiuLogic.GetTaskState(human, TALISMAN_2_CHENGJIU_TASKID)
    if state == 2 then
        return true
    end

    return false
end

--取对应类型的秘宝配置
local function generateCfgByType(type_m)
    local tbl = {}
    for id, cfg in pairs(talismanConfig) do
        if cfg.type == type_m then
            tbl[id] = cfg
            tbl[id].id = id
        end
    end
    if not next(tbl) then
        return nil
    end
    return tbl
end

--填充协议的数据
local function populateMsg(config, msgTb, nLevel)
    msgTb.id = config.id
    msgTb.name = config.name
    msgTb.iconId = config.iconId
    msgTb.level = nLevel

    local descVec = msgTb.descVec
    local effectDescCfg = config.effectDesc
    descVec[0] = #effectDescCfg
    for idx, desc in ipairs(effectDescCfg) do
        local singleDesc = descVec[idx]
        singleDesc.desc = desc
        singleDesc.isActivate = nLevel >= idx and 1 or 0
    end

    if nLevel < config.maxLevel then
        nLevel = nLevel + 1
        nLevel = math.ceil(nLevel/3)
    else
        nLevel = 0
    end
    Grid.makeItem(msgTb.upGradeCost, config.costItemId, nLevel)
end


--红点判断
local function dotJudgment(human, cfgHtbl)
    local talismanData = human.db.talismanData
    for id, cfg in pairs(cfgHtbl) do
        local nLevel = 0
        if talismanData and talismanData[id] then
            nLevel = talismanData[id]
        end

        if nLevel < cfg.maxLevel then
            nLevel = nLevel + 1
            local costItemCnt = math.ceil(nLevel/3)
            if BagLogic.getItemCnt(human, cfg.costItemId) >= costItemCnt then
                return true
            end
        end
    end
    return false
end

-- 获取秘宝总星数
local function talismanLogic_GetAllStar(human)
    local nAllStar = 0
    if not human.db.talismanData then
        return nAllStar
    end

    for id, _ in pairs(talismanConfig) do
        if human.db.talismanData[id] then
            nAllStar = nAllStar + human.db.talismanData[id]
        end
    end

    return nAllStar
end

--GM命令, 设置秘宝等级
function GmSetlevel(human, id, level)
    local config = talismanConfig[id]
    if not config then
        return Broadcast.sendErr(human, Lang.COMMON_ARGUMENT_ERROR)
    end
    if level > config.maxLevel then
        level = config.maxLevel
    end
    if level < 0 then
        level = 0
    end
    human.db.talismanData = human.db.talismanData or {}
    human.db.talismanData[id] = level
end


--秘宝对英雄属性加成
function doCalcHero(human, heroGrid, addAttrs)
    if not human or not heroGrid then
        return
    end

    local talismanData = human.db.talismanData
    if not talismanData then
        return
    end

    local heroCfg = HeroConfig[heroGrid.id]

    for id, level in pairs(talismanData) do
        local attrs = talismanConfig[id].attrs
        for i=1, level do
            local singleAttr = attrs[i]
            if #singleAttr == 2 and type(singleAttr[1]) == "number" then --给所有英雄加属性
                RoleAttr.updateValue(singleAttr[1], singleAttr[2], addAttrs)
            elseif #singleAttr == 3 then --只给某个种族的英雄加属性
                if singleAttr[1] == heroCfg.camp then
                    RoleAttr.updateValue(singleAttr[2], singleAttr[3], addAttrs)
                end
            elseif #singleAttr == 4 then
                local bl = false
                local tp = singleAttr[1]
                if tp == 1 then -- 职业
                    if heroCfg.job == singleAttr[2] then
                        bl = true
                    end
                end

                if bl then
                    RoleAttr.updateValue(singleAttr[3], singleAttr[4], addAttrs)
                end
            end
        end
    end

end

--红点
function isDot(human, dotConfig)
    if not isOpen(human) then
        return false
    end
    --入口处的红点判断
    if dotConfig.id == RoleSystemDefine.ROLE_SYS_ID_2006 then
        return dotJudgment(human, talismanConfig)
    else
        --单个分页的红点
        local talismanType = 0
        if dotConfig.id == RoleSystemDefine.ROLE_SYS_ID_2007 then
            talismanType = 1
        elseif dotConfig.id == RoleSystemDefine.ROLE_SYS_ID_2008 then
            talismanType = 2
        elseif dotConfig.id == RoleSystemDefine.ROLE_SYS_ID_2009 then
            talismanType = 3
        elseif dotConfig.id == RoleSystemDefine.ROLE_SYS_ID_2010 then
            talismanType = 4
        else
            talismanType = 5
        end

        local cfgHtbl = generateCfgByType(talismanType)
        if not cfgHtbl then
            return Broadcast.sendErr(human, Lang.COMMON_ARGUMENT_ERROR)
        end

        return dotJudgment(human, cfgHtbl)
    end
end


-- 外部调用, 本系统是否开启
function ModuleisOpen(human)
    local towerLevel = HuanJingTowerLogic.getTowerLevel(human)
    if towerLevel >= COND_TOWER_LEVEL then
        return true
    end
    return false
end

--秘宝对其他方面的加成, 如:挂机钻石
function getTalismanAdd(human, effectType)
    local addValue = 0

    if not human or not human.db then
        return addValue
    end

    local talismanData = human.db.talismanData
    if not talismanData or not effectType then
        return addValue
    end

    for id, level in pairs(talismanData) do
        local cfg = talismanConfig[id]
        local attrs = cfg.attrs
        for i=1,#attrs do
            local singleAttr = attrs[i]
            local addType = singleAttr[1]
            local value = singleAttr[2]
            if type(addType) == "string" and level >= i and effectType == addType then
                if type(value) == "number" then
                    addValue = addValue + value
                else
                    addValue = value
                end
            end
        end
    end

    return addValue
end


--查询
function Query(human, type_m)
    if not type_m then
        return Broadcast.sendErr(human, Lang.COMMON_ARGUMENT_ERROR)
    end

    if not isOpen(human) then
        return Broadcast.sendErr(human, Lang.COMMOM_NOT_ENABLED)
    end

    local cfgHtbl = generateCfgByType(type_m)
    if not cfgHtbl then
        return Broadcast.sendErr(human, Lang.COMMON_ARGUMENT_ERROR)
    end

    local msgRet = Msg.gc.GC_TALISMAN_QUERY
    msgRet.nAllStar = talismanLogic_GetAllStar(human)
    msgRet.type = type_m
    local talismanVec = msgRet.talismanVec

    local len = 0
    local talismanData = human.db.talismanData
    for id, cfg in pairs(cfgHtbl) do
        len = len + 1
        local nLevel = 0
        if talismanData and talismanData[id] then
            nLevel = talismanData[id]
        end
        populateMsg(cfg, talismanVec[len], nLevel)
    end
    talismanVec[0] = len
    Msg.send(msgRet, human.fd)
end

--升级
function UpGrade(human, id)
    if not isOpen(human) then
        return Broadcast.sendErr(human, Lang.COMMOM_NOT_ENABLED)
    end

    local singleCfg = talismanConfig[id]
    if not singleCfg then
        return Broadcast.sendErr(human, Lang.COMMON_COMFIG_ERROR)
    end

    local nLevel = 0
    local type = singleCfg.type

    --等级判断
    if human.db.talismanData and human.db.talismanData[id] then
        nLevel = human.db.talismanData[id]
    end
    if nLevel >= singleCfg.maxLevel then
        return Broadcast.sendErr(human, Lang.COMMON_MAXLEVEL)
    end

    --道具判断
    nLevel = nLevel + 1
    local costItemId = singleCfg.costItemId
    local costItemCnt = math.ceil(nLevel/3)
    if BagLogic.getItemCnt(human, costItemId) < costItemCnt then
        return Broadcast.sendErr(human, Lang.COMMON_ITEM_NOT_ENOUGH)
    end
    BagLogic.delItem(human, costItemId, costItemCnt, LOGTYPE)

    --更新数据
    human.db.talismanData = human.db.talismanData or {}
    human.db.talismanData[id] = nLevel

    --下发数据
    local msgRet = Msg.gc.GC_TALISMAN_UPGRADE
    msgRet.type = type
    populateMsg(singleCfg, msgRet.talismanInfo, nLevel)
    Msg.send(msgRet, human.fd)

    --重算战力
    RoleAttr.cleanHeroAttrCache(human)
    RoleAttr.doCalc(human)
    ObjHuman.sendAttr(human, RoleDefine.ZHANDOULI)

    if nLevel == 1 then
        -- 激活
        TriggerLogic.PublishEvent(TriggerDefine.MIBAO_ACTIVATE, human.db._id, id, 1)
    end

    -- 总星数
    TriggerLogic.PublishEvent(TriggerDefine.MIBAO_ALLSTAR, human.db._id, 1)

    local allStar = talismanLogic_GetAllStar(human)
    GiftLogic = GiftLogic or require("topup.GiftLogic")
    GiftLogic.trigger(human, GiftLogic.GIFT_TALISMAN_UPGRADE_STAR, {currentVal = allStar}, GiftLogic.GIFT_SEC_TYPE3)

    --刷新红点
    nLevel = nLevel + 1
    costItemCnt = math.ceil(nLevel/3)
    if nLevel >= singleCfg.maxLevel or BagLogic.getItemCnt(human, costItemId) < costItemCnt then
        local dotID = 0
        if type == 1 then
            dotID = RoleSystemDefine.ROLE_SYS_ID_2007
        elseif type == 2 then
            dotID = RoleSystemDefine.ROLE_SYS_ID_2008
        elseif type == 3 then
            dotID = RoleSystemDefine.ROLE_SYS_ID_2009
        elseif type == 4 then
            dotID = RoleSystemDefine.ROLE_SYS_ID_2010
        else
            dotID = RoleSystemDefine.ROLE_SYS_ID_2011
        end

        --刷新单页
        RoleSystemLogic.onDot(human, dotID)
        --刷新入口处
        RoleSystemLogic.onDot(human, RoleSystemDefine.ROLE_SYS_ID_2006)
    end

    Query(human, type)
end