-- 种子系统
local Lang = require("common.Lang")
local Msg = require("core.Msg")
local BagLogic = require("bag.BagLogic")
local HeroLogic = require("hero.HeroLogic")
local ObjHuman = require("core.ObjHuman")
local Grid = require("bag.Grid")
local RoleAttr = require("role.RoleAttr")
local HeroSeedCfg = require("excel.heroSeed")
local Broadcast = require("broadcast.Broadcast")
local RoleDefine = require("role.RoleDefine")
local TalismanLogic = require("talisman.TalismanLogic")

local GiftLogic

local LOGTAG = "HeroSeed" --日志标识
local HAVE_SEED_HERO_MIN_STAR = 9 --英雄获得种子的最低星级要求


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

-- 获取下一级消耗的道具数量
local function getUpGradeCostCnt(nextLv)
    local upGradeCfg = HeroSeedCfg.upGrade

    -- local maxLvCfg = upGradeCfg[#upGradeCfg]
    -- if nextLv >= maxLvCfg.levelArea[2] then
    --     return 0
    -- end

    for _, v in ipairs(upGradeCfg) do
        if nextLv >= v.levelArea[1] and nextLv <= v.levelArea[2] then
            return v.itemCnt
        end
    end
end

-- 计算一共可以升多少级， 消耗多少道具
local function calcUpGrade(nowLv, itemAllCnt)
    local addLv, oldItemAllCnt, itemCostCnt = 0, itemAllCnt, 0
    while true do
        nowLv = nowLv + 1
        itemCostCnt = getUpGradeCostCnt(nowLv)
        if not itemCostCnt then
            break
        end

        if itemAllCnt < itemCostCnt then
            break
        end

        addLv = addLv + 1
        itemAllCnt = itemAllCnt - itemCostCnt
    end

    local useItemCnt = oldItemAllCnt - itemAllCnt

    return addLv, useItemCnt
end

-- 计算种子重置等级后返还的材料
local function calcReturnItem(seeIdx, seedLv)
    if not seeIdx or not seedLv or seedLv <= 0 then
        return
    end

    local targetSeedCfg = HeroSeedCfg.base[seeIdx]
    if not targetSeedCfg then
        return
    end

    local itemCnt = 0
    for i=seedLv, 0, -1 do
        for _, v in ipairs(HeroSeedCfg.upGrade) do
            if i >= v.levelArea[1] and i <= v.levelArea[2] then
                itemCnt = itemCnt + v.itemCnt
                break
            end
        end
    end

    if itemCnt <= 0 then
        return
    end

    local itemTb = { targetSeedCfg.itemId, itemCnt }
    return itemTb
end

-- 获取英雄种子的红点标识数组
-- local function getHeroSeedRedDotArr(human, heroGrid)
--     local bl = false
--     local redDotArr = {0, 0, 0, 0, 0, 0, 0, 0}
--     local seedData = heroGrid.seedData or {}
--     for idx, v in ipairs(HeroSeedCfg.base) do
--         local seedNowLv = seedData[idx] or 0
--         if seedNowLv < v.maxLv then
--             local itemCnt = getUpGradeCostCnt(seedNowLv+1)
--             if itemCnt and BagLogic.getItemCnt(human, v.itemId) >= itemCnt then
--                 bl = true
--                 redDotArr[idx] = 1
--             end
--         end
--     end

--     return redDotArr, bl
-- end

-- 计算重置种子等级后返还的材料
function CalcReturnItem(human, heroGrid)
    if heroGrid.star < HAVE_SEED_HERO_MIN_STAR then
        return
    end

    local seedData = heroGrid.seedData
    if not seedData then
        return
    end

    local itemArr = {}
    for seeIdx, seedLv in pairs(seedData) do
        local itemTb = calcReturnItem(seeIdx, seedLv)
        if itemTb then
            itemArr[#itemArr+1] = itemTb
        end
    end

    if #itemArr == 0 then
        return
    end

    return itemArr
end

-- 重置英雄所有种子等级
function ResetSeedLv(human, heroGrid)
    if not heroGrid or not heroGrid.seedData then
        return
    end

    heroGrid.seedData = nil
end

-- 英雄种子红点检测
function isSeedDot(human, heroGrid)
    if heroGrid.star < HAVE_SEED_HERO_MIN_STAR then
        return false
    end

    local seedData = heroGrid.seedData or {}
    for idx, v in ipairs(HeroSeedCfg.base) do
        local seedNowLv = seedData[idx] or 0
        if seedNowLv < v.maxLv then
            local itemCnt = getUpGradeCostCnt(seedNowLv+1)
            if itemCnt and BagLogic.getItemCnt(human, v.itemId) >= itemCnt then
                return true
            end
        end
    end

    return false
end

-- 种子加成
function doCalcHero(human, heroGrid, addAttrs)
    if not heroGrid or not heroGrid.seedData then
        return
    end

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

    local seedBaseCfg = HeroSeedCfg.base
    for seedIdx, seedLv in pairs(heroGrid.seedData) do
        if seedLv > 0 then
            if seedBaseCfg[seedIdx] then
                for _, attrTb in ipairs(seedBaseCfg[seedIdx].attr) do
                    local attrId, attrVal = attrTb[1], attrTb[2]
                    RoleAttr.updateValue(attrId, attrVal * seedLv * attrMul, addAttrs)
                end
            end
        end
    end
end



--查询所有种子的简略信息
function HeroSeed_Query_All(human, heroID, heroIndex)
    local heroGrid = HeroLogic.getHeroGrid(human, heroID, heroIndex)
    if not heroGrid then
        return Broadcast.sendErr(human, Lang.FUWEN_HERO_GRID_ERR)
    end

    if heroGrid.star < HAVE_SEED_HERO_MIN_STAR then
        return Broadcast.sendErr(human, Lang.HEROPUB_STAR_NOT_ENOUGH)
    end

    local seedData = heroGrid.seedData
    local seedBaseCfg = HeroSeedCfg.base
    local msgRet = Msg.gc.GC_HEROSEED_QUERY_ALL
    msgRet.seedArr[0] = #seedBaseCfg

    for idx, seedCfg in ipairs(seedBaseCfg) do
        msgRet.seedArr[idx].seedIdx = idx
        msgRet.seedArr[idx].seedIcon = seedCfg.seedIcon
        if seedData and seedData[idx] then
            msgRet.seedArr[idx].seedLv = seedData[idx]
        else
            msgRet.seedArr[idx].seedLv = 0
        end
        msgRet.seedArr[idx].seedName = seedCfg.name

        -- 红点标识
        msgRet.seedArr[idx].redDotTag = 0
        local seedNowLv = msgRet.seedArr[idx].seedLv
        if seedNowLv < seedCfg.maxLv then
            local itemCnt = getUpGradeCostCnt(seedNowLv+1)
            if itemCnt and BagLogic.getItemCnt(human, seedCfg.itemId) >= itemCnt then
                msgRet.seedArr[idx].redDotTag = 1
            end
        end
    end

    Msg.send(msgRet, human.fd)
end

-- 查询单个种子详细信息
function HeroSeed_Query_Single(human, heroID, heroIndex, seedIdx)
    local targetCfg = HeroSeedCfg.base[seedIdx]
    if not targetCfg then
        return Broadcast.sendErr(human, Lang.COMMON_ARGUMENT_ERROR)
    end

    local heroGrid = HeroLogic.getHeroGrid(human, heroID, heroIndex)
    if not heroGrid then
        return Broadcast.sendErr(human, Lang.FUWEN_HERO_GRID_ERR)
    end

    if heroGrid.star < HAVE_SEED_HERO_MIN_STAR then
        return Broadcast.sendErr(human, Lang.HEROPUB_STAR_NOT_ENOUGH)
    end

    local seedNowLv = 0
    local seedData = heroGrid.seedData
    if seedData then
        seedNowLv = seedData[seedIdx] or 0
    end

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

    local msgRet = Msg.gc.GC_HEROSEED_QUERY_SINGLE
    msgRet.seedIdx = seedIdx
    msgRet.seedIcon = targetCfg.seedIcon
    msgRet.seedLv = seedNowLv
    msgRet.seedMaxLv = targetCfg.maxLv
    msgRet.seedName = targetCfg.name
    msgRet.seedLvAttr[0] = 0
    for idx, attrTb in ipairs(targetCfg.attr) do
        msgRet.seedLvAttr[0] = idx
        msgRet.seedLvAttr[idx].key = attrTb[1]
        msgRet.seedLvAttr[idx].value = attrTb[2] * attrMul
    end

    local itemCnt = seedNowLv >= targetCfg.maxLv and 0 or getUpGradeCostCnt(seedNowLv+1)
    Grid.makeItem(msgRet.seedUpGradeCost, targetCfg.itemId, itemCnt)

    Msg.send(msgRet, human.fd)
end

-- 种子升级
function HeroSeed_UpGrade(human, heroID, heroIndex, seedIdx, opType)
    local targetCfg = HeroSeedCfg.base[seedIdx]
    if not targetCfg then
        return Broadcast.sendErr(human, Lang.COMMON_ARGUMENT_ERROR)
    end

    local heroGrid = HeroLogic.getHeroGrid(human, heroID, heroIndex)
    if not heroGrid then
        return Broadcast.sendErr(human, Lang.FUWEN_HERO_GRID_ERR)
    end

    if heroGrid.star < HAVE_SEED_HERO_MIN_STAR then
        return Broadcast.sendErr(human, Lang.HEROPUB_STAR_NOT_ENOUGH)
    end

    local seedNowLv = 0
    if heroGrid.seedData and heroGrid.seedData[seedIdx] then
        seedNowLv = heroGrid.seedData[seedIdx]
    end

    if seedNowLv >= targetCfg.maxLv then
        return Broadcast.sendErr(human, Lang.COMMON_MAXLEVEL)
    end


    local itemId, itemCnt, addLv = targetCfg.itemId, 0, 0
    local itemAllCnt = BagLogic.getItemCnt(human, itemId)

    if opType == 1 then --升级一次
        itemCnt = getUpGradeCostCnt(seedNowLv+1)
        if not itemCnt then
            return Broadcast.sendErr(human, Lang.DATA_ERR)
        end

        if itemAllCnt < itemCnt then
            return Broadcast.sendErr(human, Lang.COMMON_ITEM_NOT_ENOUGH)
        end
        addLv = 1
    elseif opType == 2 then -- 一键升级
        if itemAllCnt <= 0 then
            return Broadcast.sendErr(human, Lang.COMMON_ITEM_NOT_ENOUGH)
        end

        addLv, itemCnt = calcUpGrade(seedNowLv, itemAllCnt)
        if addLv <= 0 or itemAllCnt < itemCnt then --再验证一次道具数量
            return Broadcast.sendErr(human, Lang.COMMON_ITEM_NOT_ENOUGH)
        end
    else
        return Broadcast.sendErr(human, Lang.COMMON_ARGUMENT_ERROR)
    end

    -- 扣除道具
    BagLogic.delItem(human, itemId, itemCnt, LOGTAG)

    -- 更新等级
    heroGrid.seedData = heroGrid.seedData or {}
    heroGrid.seedData[seedIdx] = (heroGrid.seedData[seedIdx] or 0) + addLv

    -- 推送最新数据给客户端
    HeroSeed_Query_All(human, heroID, heroIndex)
    HeroSeed_Query_Single(human, heroID, heroIndex, seedIdx)

    --重算战力和红点
    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_HEROSEED_UPGRADE_STAR, {currentVal = heroGrid.seedData[seedIdx]}, GiftLogic.GIFT_SEC_TYPE3)
end
