--超武之专属武器

local Msg = require("core.Msg")
local Grid = require("bag.Grid")
local BagLogic = require("bag.BagLogic")
local HeroLogic = require("hero.HeroLogic")
local RoleSystemLogic = require("roleSystem.RoleSystemLogic")
local RoleSystemDefine = require("roleSystem.RoleSystemDefine")
local Lang = require("common.Lang")
local Broadcast = require("broadcast.Broadcast")
local RoleAttr = require("role.RoleAttr")
local RoleDefine = require("role.RoleDefine")
local ObjHuman = require("core.ObjHuman")
local Config = require("excel.weapon").weapon
local HeroExcel = require("excel.hero").hero
local TalismanLogic = require("talisman.TalismanLogic")

local GiftLogic

local COND_STAR = 11   -- 获得超武需要的星级
local STAGELV = 20     -- 每20级获得一个特殊效果
local LOGTAG = "HeroExclusiveWeapon" --日志标识
local SSRGRADE = 4          -- SSR英雄的grade值


-- 获取来自秘宝的属性倍数加成
local function getAttrMulFromTalisman(human)
    local attrMul = TalismanLogic.getTalismanAdd(human, TalismanLogic.OTHER_EFFECT_TBL.HeroExclusiveWeapon_Attr_Mul)
    attrMul = attrMul / 100
    return attrMul
end


--获取英雄的专属武器配置
local function getHeroWeaponCfg(heroID)
    for _, cfg in pairs(Config) do
        if cfg.heroId == heroID then
            return cfg
        end
    end
end

--获得消耗列表
local function getItemList(costItemList, nextWeaponLv)
    local itemList = {}
    local itemId, itemCnt = 0,0
    for i=1, #costItemList, 3 do
        local lv = costItemList[i]
        if nextWeaponLv < lv then
            break
        end
        itemId = costItemList[i+1]
        if type(costItemList[i+2]) == "table" then
            itemCnt = costItemList[i+2][1] * nextWeaponLv + costItemList[i+2][2]
        else
            itemCnt = costItemList[i+2]
        end

        itemList[itemId] = itemCnt
    end
    return itemList
end

--计算一个英雄当前专属武器等级消耗的道具
function CalcLevelCostItem(human, heroID, heroIndex)
    local heroGrid = HeroLogic.getHeroGrid(human, heroID, heroIndex)
    if heroGrid.star < COND_STAR then
        return
    end

    if not heroGrid.weaponLv or heroGrid.weaponLv <= 0 then
        return
    end

    local heroCfg = HeroExcel[heroGrid.id]
    if heroCfg.grade < SSRGRADE then
        return
    end

    local cfg = getHeroWeaponCfg(heroID)
    if not cfg then
        return
    end

    local itemList = {}
    local costItemList = cfg.costItemList

    for i=1, heroGrid.weaponLv do
        local costTb = getItemList(costItemList, i)
        for itemId, itemCnt in pairs(costTb) do
            itemList[itemId] = itemList[itemId] or 0
            itemList[itemId] = itemList[itemId] + itemCnt
        end
    end

    return itemList
end


--设置某个英雄的专属武器等级
function SetHeroWeaponLv(human, heroID, heroIndex, lv)
    local heroGrid = HeroLogic.getHeroGrid(human, heroID, heroIndex)
    if heroGrid.star < COND_STAR then
        return
    end

    local heroCfg = HeroExcel[heroGrid.id]
    if heroCfg.grade < SSRGRADE then
        return
    end

    local cfg = getHeroWeaponCfg(heroID)
    if not cfg then
        return
    end

    heroGrid.weaponLv = lv

    --更新数据
    Query(human, heroID, heroIndex)
end


--专属武器加成
function doCalcHero(human, heroGrid, addAttrs)
    if not heroGrid or not heroGrid.weaponLv then
        return
    end

    local cfg = getHeroWeaponCfg(heroGrid.id)
    if not cfg then
        return
    end

    local nowWeaponLv = heroGrid.weaponLv

    local attrMul = getAttrMulFromTalisman(human)
    attrMul = 1 + attrMul

    for _, v in ipairs(cfg.normalAttrs) do
        RoleAttr.updateValue(v[1], v[2] * nowWeaponLv * attrMul, addAttrs)
    end
end


--获取专属武器对英雄技能提供额外效果的 技能ID/buff ID
function GetweaponEffectIdList(heroGrid)
    if not heroGrid or not heroGrid.weaponLv then
        return
    end

    local cfg = getHeroWeaponCfg(heroGrid.id)
    if not cfg then
        return
    end

    local stage = math.floor(heroGrid.weaponLv / STAGELV)
    if  stage < 1 then
        return
    end

    local ids = {}
    local effectCfg = cfg.stage2effect
    for k, tabl in ipairs(effectCfg) do
        if stage < k then
            break
        end
        for _,v in ipairs(tabl) do
            ids[v[1]] = v[2]
        end
    end
    return ids
end


--红点判断
function isWeaponDot(human, heroGrid)
    if heroGrid.star < COND_STAR then
        return false
    end

    local heroCfg = HeroExcel[heroGrid.id]
    if heroCfg.grade < SSRGRADE then
        return false
    end

    local cfg = getHeroWeaponCfg(heroGrid.id)
    if not cfg then
        return false
    end

    local nowWeaponLv = heroGrid.weaponLv or 0
    if nowWeaponLv >= cfg.maxLevel then
        return false
    end


    local itemList = getItemList(cfg.costItemList, nowWeaponLv+1)
    for itemId, itemCnt in pairs(itemList) do
        if BagLogic.getItemCnt(human, itemId) < itemCnt then
            return false
        end
    end

    return true
end


--查询
function Query(human, heroID, heroIndex)
    local heroGrid = HeroLogic.getHeroGrid(human, heroID, heroIndex)

    if not heroGrid then
        return Broadcast.sendErr(human, Lang.COMMON_ARGUMENT_ERROR)
    end

    if heroGrid.star < COND_STAR then
        return Broadcast.sendErr(human, Lang.COMMOM_NOT_ENABLED)
    end

    local heroCfg = HeroExcel[heroGrid.id]
    if heroCfg.grade < SSRGRADE then
        return Broadcast.sendErr(human, Lang.COMMOM_NOT_ENABLED)
    end

    local cfg = getHeroWeaponCfg(heroID)
    -- if not cfg then
    --     return Broadcast.sendErr(human, Lang.COMMOM_NOT_ENABLED)
    -- end

    local msgRet = Msg.gc.GC_HERO_EXCLUSIVE_WEAPON_QUERY

    msgRet.name = ""
    msgRet.level = 0
    msgRet.icon = 0
    msgRet.costInfo[0] =0
    msgRet.normalAttrs[0] = 0
    msgRet.specEffect[0] = 0

    if cfg then
        local nowWeaponLv = heroGrid.weaponLv or 0
        local nextWeaponLv = nowWeaponLv + 1

        msgRet.name = cfg.name
        msgRet.level = nowWeaponLv
        msgRet.icon = cfg.iconId

        local costInfo = msgRet.costInfo
        costInfo[0] = 0

        if nowWeaponLv < cfg.maxLevel then
            local len= 0
            local costItemList = cfg.costItemList

            local itemList = getItemList(costItemList, nextWeaponLv)
            for itemId, itemCnt in pairs(itemList) do
                len = len + 1
                Grid.makeItem(costInfo[len], itemId, itemCnt)
            end

            costInfo[0] = len
        end

        local attrMul = getAttrMulFromTalisman(human)
        attrMul = 1 + attrMul

        --普通属性加成
        local normalAttrs = msgRet.normalAttrs
        local normalAttrsCfg = cfg.normalAttrs
        normalAttrs[0] = #normalAttrsCfg
        for k, v in ipairs(normalAttrsCfg) do
            normalAttrs[k] = {}
            normalAttrs[k].key = v[1] or 0
            normalAttrs[k].value = v[2] * nowWeaponLv * attrMul
        end

        --特殊效果
        local stage = math.floor(nowWeaponLv / STAGELV)
        local specEffect = msgRet.specEffect
        specEffect[0] = #cfg.effectDesc
        for k, desc in ipairs(cfg.effectDesc) do
            specEffect[k].desc = desc
            specEffect[k].isActivate = 0
            if stage >= k then
                specEffect[k].isActivate = 1
            end
        end
    end

    Msg.send(msgRet, human.fd)
end


--升级
function UpgradeWeapon(human, heroID, heroIndex)
    local heroGrid = HeroLogic.getHeroGrid(human, heroID, heroIndex)

    if not heroGrid then
        return Broadcast.sendErr(human, Lang.COMMON_ARGUMENT_ERROR)
    end

    if heroGrid.star < COND_STAR then
        return Broadcast.sendErr(human, Lang.COMMOM_NOT_ENABLED)
    end

    local heroCfg = HeroExcel[heroGrid.id]
    if heroCfg.grade < SSRGRADE then
        return Broadcast.sendErr(human, Lang.COMMOM_NOT_ENABLED)
    end

    local cfg = getHeroWeaponCfg(heroID)
    if not cfg then
        return Broadcast.sendErr(human, Lang.COMMOM_NOT_ENABLED)
    end

    local nowWeaponLv = heroGrid.weaponLv or 0
    if nowWeaponLv >= cfg.maxLevel then
        return Broadcast.sendErr(human, Lang.BINGSHU_LEVELUP_ERR_FULL)
    end

    local nextWeaponLv = nowWeaponLv + 1
    local costItemList = cfg.costItemList

    local itemList = getItemList(costItemList, nextWeaponLv)
    for itemId, itemCnt in pairs(itemList) do
        if BagLogic.getItemCnt(human, itemId) < itemCnt then
            return Broadcast.sendErr(human, Lang.COMMON_ITEM_NOT_ENOUGH)
        end
    end

    --扣除道具
    for itemId, itemCnt in pairs(itemList) do
        BagLogic.delItem(human, itemId, itemCnt, LOGTAG)
    end

    --更新等级
    heroGrid.weaponLv = nextWeaponLv

    --下发数据
    Query(human, heroID, heroIndex)

    --重算战力和红点
    RoleAttr.cleanHeroAttrCache(human)
    RoleAttr.doCalc(human)
    HeroLogic.sendHeroBagDynamic(human, heroID, heroIndex)
    ObjHuman.sendAttr(human, RoleDefine.ZHANDOULI)
    HeroLogic.refreshDot(human, heroGrid.uuid)

    -- 弹窗礼包
    GiftLogic = GiftLogic or require("topup.GiftLogic")
    GiftLogic.trigger(human, GiftLogic.GIFT_HEROWEAPON_UPGRADE_STAR, {currentVal = nextWeaponLv}, GiftLogic.GIFT_SEC_TYPE3)
end


--GM, 设置所有id为heroID英雄的专属武器等级
function GmSetHeroWeaponLv(human, heroID, lv)
    local heroCfg = HeroExcel[heroID]
    if not heroCfg then
        return Broadcast.sendErr(human, Lang.COMMON_ARGUMENT_ERROR)
    end

    if heroCfg.grade < SSRGRADE then
        return Broadcast.sendErr(human, Lang.COMMOM_NOT_ENABLED)
    end
    local heroNum = human.db.heroBag[0]
    for i=1, heroNum do
        local heroGrid = human.db.heroBag[i]
        if not heroGrid then
            break
        end

        if heroGrid.id == heroID and heroGrid.star >= COND_STAR then
            heroGrid.weaponLv = lv
        end
    end
end

--专属武器图鉴查询
function BookQuery(human, heroID)
    local cfg = getHeroWeaponCfg(heroID)
    -- if not cfg then
    --     return Broadcast.sendErr(human, Lang.COMMOM_NOT_ENABLED)
    -- end

    local msgRet = Msg.gc.GC_HERO_EXCLUSIVE_WEAPON_BOOK_QUERY

    msgRet.name = ""
    msgRet.icon = 0
    msgRet.normalAttrs[0] = 0
    msgRet.specEffect[0] = 0

    if cfg then
        msgRet.name = cfg.name
        msgRet.icon = cfg.iconId


        --普通属性加成
        local normalAttrs = msgRet.normalAttrs
        local normalAttrsCfg = cfg.normalAttrs
        normalAttrs[0] = #normalAttrsCfg
        for k, v in ipairs(normalAttrsCfg) do
            normalAttrs[k] = {}
            normalAttrs[k].key = v[1] or 0
            normalAttrs[k].value = v[2] * cfg.maxLevel
        end

        --特殊效果
        local specEffect = msgRet.specEffect
        specEffect[0] = #cfg.effectDesc
        for k, desc in ipairs(cfg.effectDesc) do
            specEffect[k].desc = desc
            specEffect[k].isActivate = 0
        end
    end

    Msg.send(msgRet, human.fd)
end