--------------------------------
-- 文件名       :   BusOneActivityHeroYuanZheng.lua
-- 文件说明     :   新商业活动-英雄远征
-- 创建时间     :   2025/08/06
-- 创建人       :   FC
--------------------------------

local tBusoneActivityConf = require("excel.BusoneActivity")
local Util = require("common.Util")
local Msg = require("core.Msg")
local Grid = require("bag.Grid")
local BagLogic = require("bag.BagLogic")
local CommonDefine = require("common.CommonDefine")
local AbsActLogic = require("absAct.AbsActLogic")
local BuyLogic = require("topup.BuyLogic")
local YunYingLogic = require("yunying.YunYingLogic")
local BusOneActivityTask = require("absAct.BusOneActivityTask")
local BusOneActivityYuanZheng = require("absAct.BusOneActivityYuanZheng")


local BUSONEHEROYUANZHENGABSID = 7204        -- 对应ABS活动ID
local BUSONEHEROYUANZHENGMAXLAYERS = nil     -- 最大层数
local BUSONEHEROYUANZHENGMAXROUND = nil      -- 最大轮数
local BUSONEHEROYUANZHENGBAOHU = 2          -- 保护抽取
local BUSONEHEROYUANZHENGDGOODID = 1039      -- 物品ID

----------------------------------------- 内部处理开始 -------------------------------------
-- 获取权重配置
local function BusOneHeroYuanZheng_GetWeightConf()
    return tBusoneActivityConf.HeroWeight
end

-- 获取奖励配置
local function BusOneHeroYuanZheng_GetHeroConf()
    return tBusoneActivityConf.HeroYuanZheng
end

local function BusOneHeroYuanZheng_GetMaxLayers()
    if nil == BUSONEHEROYUANZHENGMAXLAYERS then
        BUSONEHEROYUANZHENGMAXLAYERS = 0
        for _, v in ipairs(tBusoneActivityConf.HeroYuanZheng) do
            if v.nLayers > BUSONEHEROYUANZHENGMAXLAYERS then
                BUSONEHEROYUANZHENGMAXLAYERS = v.nLayers
            end
        end
    end

    return BUSONEHEROYUANZHENGMAXLAYERS
end

-- 获取最大轮数
local function BusOneHeroYuanZheng_GetMaxRound()
    if nil == BUSONEHEROYUANZHENGMAXROUND then
        BUSONEHEROYUANZHENGMAXROUND = 0
        for _, v in ipairs(tBusoneActivityConf.HeroYuanZheng) do
            if v.nRound > BUSONEHEROYUANZHENGMAXROUND then
                BUSONEHEROYUANZHENGMAXROUND = v.nRound
            end
        end
    end

    return BUSONEHEROYUANZHENGMAXROUND
end

-- 创建DB
local function BusOneHeroYuanZheng_CreatDB(human)
    if not human.db.absAct[BUSONEHEROYUANZHENGABSID] then
        human.db.absAct[BUSONEHEROYUANZHENGABSID] = {}
    end

    human.db.absAct[BUSONEHEROYUANZHENGABSID].tLayers = {
        nRound = 1,
        nLayers = -1,
        tStatus = {},
        bCanDo = true
    }

    local nMaxLayers = BusOneHeroYuanZheng_GetMaxLayers()

    for i = 0, nMaxLayers, 1 do
        human.db.absAct[BUSONEHEROYUANZHENGABSID].tLayers.tStatus[i] = CommonDefine.COMMON_PRIZE_STATE_NOGET
    end
    
end

-- 重置DB
local function BusOneHeroYuanZheng_CheckAndResetDB(human)
    if not human.db.absAct[BUSONEHEROYUANZHENGABSID] or nil == _G.next(human.db.absAct[BUSONEHEROYUANZHENGABSID]) 
        or not human.db.absAct[BUSONEHEROYUANZHENGABSID].tLayers then
            BusOneHeroYuanZheng_CreatDB(human)
    end
end

-- 获取当前远征轮数
local function BusOneHeroYuanZheng_GetRound(human)
    return human.db.absAct[BUSONEHEROYUANZHENGABSID].tLayers.nRound
end

-- 设置远征轮数
local function BusOneHeroYuanZheng_SetRound(human, nValue)
    human.db.absAct[BUSONEHEROYUANZHENGABSID].tLayers.nRound = nValue
end

-- 获取当前远征层数
local function BusOneHeroYuanZheng_GetLayers(human)
    return human.db.absAct[BUSONEHEROYUANZHENGABSID].tLayers.nLayers
end

-- 设置远征层数
local function BusOneHeroYuanZheng_SetLayers(human, nValue)
    human.db.absAct[BUSONEHEROYUANZHENGABSID].tLayers.nLayers = nValue
end

-- 获取当前远征状态
local function BusOneHeroYuanZheng_GetStatus(human, nID)
    return human.db.absAct[BUSONEHEROYUANZHENGABSID].tLayers.tStatus[nID]
end

-- 设置远征状态
local function BusOneHeroYuanZheng_SetStatus(human, nID, nValue)
    human.db.absAct[BUSONEHEROYUANZHENGABSID].tLayers.tStatus[nID] = nValue
end

-- 获取能否继续抽取
local function BusOneHeroYuanZheng_GetCanDo(human)
    return human.db.absAct[BUSONEHEROYUANZHENGABSID].tLayers.bCanDo
end

-- 设置能否继续抽取
local function BusOneHeroYuanZheng_SetCanDo(human, nValue)
    human.db.absAct[BUSONEHEROYUANZHENGABSID].tLayers.bCanDo = nValue
end

-- 进行对应轮数
local function BusOneHeroYuanZheng_EnterRound(human, nRound)
    local nMaxRound = BusOneHeroYuanZheng_GetMaxRound()
    if nMaxRound < nRound then
        return
    end

    BusOneHeroYuanZheng_SetRound(human, nRound)
    BusOneHeroYuanZheng_SetLayers(human, -1)
    BusOneHeroYuanZheng_SetCanDo(human, true)

    local nMaxLayers = BusOneHeroYuanZheng_GetMaxLayers()
    for i = 0, nMaxLayers, 1 do
        human.db.absAct[BUSONEHEROYUANZHENGABSID].tLayers.tStatus[i] = CommonDefine.COMMON_PRIZE_STATE_NOGET
    end
end

-----------------------------------客户端请求-----------------------------
-- 请求英雄远征
function BusOneHeroYuanZheng_Query(human)
    BusOneHeroYuanZheng_CheckAndResetDB(human)

    local tMsgData = Msg.gc.GC_NEW_BUSONEACT_HERO_QUERY
    local tWeightConf = BusOneHeroYuanZheng_GetWeightConf()
    tMsgData.tFenShu[0] = #tWeightConf
    for i, v in ipairs(tWeightConf) do
        tMsgData.tFenShu[i] = v.nWeight
    end

    tMsgData.bCanDo = BusOneHeroYuanZheng_GetCanDo(human) == true and 1 or 0
    tMsgData.nRound = BusOneHeroYuanZheng_GetRound(human)
    tMsgData.nLayers = BusOneHeroYuanZheng_GetLayers(human)

    local tConf = BusOneHeroYuanZheng_GetHeroConf()
    tMsgData.tLayersInfo[0] = 0

    for _, v in ipairs(tConf) do
        if v.nRound == tMsgData.nRound then
            local nLayers = v.nLayers
            tMsgData.tLayersInfo[0] = tMsgData.tLayersInfo[0] + 1
            local tData = tMsgData.tLayersInfo[tMsgData.tLayersInfo[0]]
            tData.nLayers = nLayers
            tData.nStatus = BusOneHeroYuanZheng_GetStatus(human, nLayers)

            tData.tPrize[0] = #v.tPrize
            for i, tItem in ipairs(v.tPrize) do
                local nGoodsID = tItem[1]
                local nGoodsNum = tItem[2]
    
                Grid.makeItem(tData.tPrize[i], nGoodsID, nGoodsNum)
            end
        end
    end

    Msg.send(tMsgData, human.fd)
end

-- 请求参与
function BusOneHeroYuanZheng_Join(human)
    BusOneHeroYuanZheng_CheckAndResetDB(human)
    
    local nGoodsNum = BagLogic.getItemCnt(human, BUSONEHEROYUANZHENGDGOODID)
    if 0 >= nGoodsNum then
        print("[BusOneHeroYuanZheng_Join] 物品不足 nGoodsNum = "..nGoodsNum)
        return
    end

    local nNowLayers = BusOneHeroYuanZheng_GetLayers(human)
    if nNowLayers ~= -1 then
        print("[BusOneHeroYuanZheng_Join] 当前层数不正确 nNowLayers = "..nNowLayers)
        return
    end

    local tWeightConf = BusOneHeroYuanZheng_GetWeightConf()
    local nAllWeight = 0
    local tWeight = {}
    for _, v in ipairs(tWeightConf) do
        if v.nWeight >= 0  then
            nAllWeight = nAllWeight + v.nLayers
            table.insert(tWeight, {nWeight = nAllWeight, nFenShu = v.nWeight})
        end
    end

    local nRandWeight = math.random(1, nAllWeight)
    local nFenShu = nil
    for _, v in ipairs(tWeight) do
        if v.nWeight >= nRandWeight then
            nFenShu = v.nFenShu
            break
        end
    end

    local nNewLayers = nNowLayers + nFenShu
    BusOneHeroYuanZheng_SetLayers(human, nNewLayers)
    BusOneHeroYuanZheng_SetStatus(human, nNewLayers, CommonDefine.COMMON_PRIZE_STATE_CANGET)
    
    local nRound = BusOneHeroYuanZheng_GetRound(human)
    local tConf = BusOneHeroYuanZheng_GetHeroConf()

    local tMsgData = Msg.gc.GC_NEW_BUSONEACT_HERO_JOIN
    tMsgData.nFenShu = nFenShu
    tMsgData.nLayers = nNewLayers
    tMsgData.tLayersInfo[0] = 0

    for _, v in ipairs(tConf) do
        if v.nRound == nRound then
            local nLayers = v.nLayers
            tMsgData.tLayersInfo[0] = tMsgData.tLayersInfo[0] + 1
            local tData = tMsgData.tLayersInfo[tMsgData.tLayersInfo[0]]
            tData.nLayers = nLayers
            tData.nStatus = BusOneHeroYuanZheng_GetStatus(human, nLayers)

            tData.tPrize[0] = #v.tPrize
            for i, tItem in ipairs(v.tPrize) do
                local nGoodsID = tItem[1]
                local nGoodsNum = tItem[2]
    
                Grid.makeItem(tData.tPrize[i], nGoodsID, nGoodsNum)
            end
        end
    end

    BagLogic.delItem(human, BUSONEHEROYUANZHENGDGOODID, 1, "BusOneHeroYuanZheng")

    Msg.send(tMsgData, human.fd)
    print("[BusOneHeroYuanZheng_Join] 发送数据完成")
    BusOneActivityYuanZheng.BusOneYuanZheng_NumChange(human, 1)
    BusOneActivityTask.BusOneTask_SendRed(human)
end

-- 请求抽取
function BusOneHeroYuanZheng_Do(human, nOperate)
    local nDelNum = nOperate == BUSONEHEROYUANZHENGBAOHU and 1 or 0
    local nGoodsNum = BagLogic.getItemCnt(human, BUSONEHEROYUANZHENGDGOODID)
    if nGoodsNum < nDelNum then
        print("[BusOneHeroYuanZheng_Do] 进行抽取 当前的可抽取的数量不正确 nGoodsNum = "..nGoodsNum.." nDelNum = "..nDelNum)
        return
    end

    local bCanDO = BusOneHeroYuanZheng_GetCanDo(human)
    if false == bCanDO then
        print("[BusOneHeroYuanZheng_Do] 进行抽取, 当前不能进行抽取")
        return
    end

    local tWeightConf = BusOneHeroYuanZheng_GetWeightConf()
    local nAllWeight = 0
    local tWeight = {}
    for _, v in ipairs(tWeightConf) do
        if v.nWeight >= 0  then
            nAllWeight = nAllWeight + v.nLayers
            table.insert(tWeight, {nWeight = nAllWeight, nFenShu = v.nWeight})
        else
            -- if nOperate ~= BUSONEHEROYUANZHENGBAOHU then
                nAllWeight = nAllWeight + v.nLayers
                table.insert(tWeight, {nWeight = nAllWeight, nFenShu = v.nWeight})
            -- end
        end
    end

    local nRandWeight = math.random(1, nAllWeight)
    local nFenShu = nil
    for _, v in ipairs(tWeight) do
        if v.nWeight >= nRandWeight then
            nFenShu = v.nFenShu
            break
        end
    end

    local nAddFenShu = nFenShu
    if 0 > nFenShu then
        nAddFenShu = nOperate == BUSONEHEROYUANZHENGBAOHU and 0 or nFenShu
    end

    local bCanNext = true
    if nAddFenShu < 0 then
        bCanNext = false
    end

    BusOneHeroYuanZheng_SetCanDo(human, bCanNext)

    local nNowLayers = BusOneHeroYuanZheng_GetLayers(human)
    local nMaxLayers = BusOneHeroYuanZheng_GetMaxLayers()
    
    local nNextLayer = nNowLayers + nAddFenShu
    if nNextLayer > 0 then
        nNextLayer = nNextLayer > nMaxLayers and nMaxLayers or nNextLayer
        BusOneHeroYuanZheng_SetStatus(human, nNowLayers, CommonDefine.COMMON_PRIZE_STATE_NOGET)
        BusOneHeroYuanZheng_SetLayers(human, nNextLayer)
        BusOneHeroYuanZheng_SetStatus(human, nNextLayer, CommonDefine.COMMON_PRIZE_STATE_CANGET)
        if nNextLayer == nMaxLayers  then
            BusOneHeroYuanZheng_SetCanDo(human, false)
        end
    else
        nNextLayer = nNextLayer < 0 and 0 or nNextLayer
        BusOneHeroYuanZheng_SetStatus(human, nNowLayers, CommonDefine.COMMON_PRIZE_STATE_NOGET)
        BusOneHeroYuanZheng_SetLayers(human, nNextLayer)
        BusOneHeroYuanZheng_SetStatus(human, nNextLayer, CommonDefine.COMMON_PRIZE_STATE_CANGET)
    end

    local tMsgData = Msg.gc.GC_NEW_BUSONEACT_HERO_DO
    tMsgData.nOperate = nOperate
    tMsgData.bCanDo = BusOneHeroYuanZheng_GetCanDo(human) == true and 1 or 0
    tMsgData.nFenShu = nFenShu
    tMsgData.nLayers = nNextLayer
    tMsgData.nRound = BusOneHeroYuanZheng_GetRound(human)
    tMsgData.tLayersInfo[0] = 0

    local tConf = BusOneHeroYuanZheng_GetHeroConf()
    for _, v in ipairs(tConf) do
        if v.nRound == tMsgData.nRound then
            local nLayers = v.nLayers
            tMsgData.tLayersInfo[0] = tMsgData.tLayersInfo[0] + 1
            local tData = tMsgData.tLayersInfo[tMsgData.tLayersInfo[0]]
            tData.nLayers = nLayers
            tData.nStatus = BusOneHeroYuanZheng_GetStatus(human, nLayers)

            tData.tPrize[0] = #v.tPrize
            for i, tItem in ipairs(v.tPrize) do
                local nGoodsID = tItem[1]
                local nGoodsNum = tItem[2]
    
                Grid.makeItem(tData.tPrize[i], nGoodsID, nGoodsNum)
            end
        end
    end

    if nDelNum > 0 then
        BagLogic.delItem(human, BUSONEHEROYUANZHENGDGOODID, nDelNum, "BusOneHeroYuanZheng")
    end

    BusOneActivityYuanZheng.BusOneYuanZheng_NumChange(human, 1)
    BusOneActivityTask.BusOneTask_SendRed(human)
    Msg.send(tMsgData, human.fd)
end

-- 请求领取奖励
function BusOneHeroYuanZheng_Get(human, nLayers, nIndex)
    local nRound = BusOneHeroYuanZheng_GetRound(human)
    local nNowLayers = BusOneHeroYuanZheng_GetLayers(human)

    if nLayers ~= nNowLayers then
        print("[BusOneHeroYuanZheng_Get] 请求领取奖励的层数和记录的不一致 nLayers = "..nLayers.." nNowLayers = "..nNowLayers)
        return
    end

    local tItem = {}
    local tConf = BusOneHeroYuanZheng_GetHeroConf()
    for _, v in ipairs(tConf) do
        if v.nRound == nRound and v.nLayers == nNowLayers then
            BusOneHeroYuanZheng_SetStatus(human, nNowLayers, CommonDefine.COMMON_PRIZE_STATE_GET)

            for i, value in ipairs(v.tPrize) do
                if i == nIndex then
                    table.insert(tItem, {value[1], value[2]})
                    break
                end
            end
        end
    end

    if nil ~= _G.next(tItem) then
        BagLogic.addItemList(human, tItem, "BusOneHeroYuanZheng")
        local nNextRound = nRound + 1
        local nMaxRound = BusOneHeroYuanZheng_GetMaxRound()
        local nMaxLayers = BusOneHeroYuanZheng_GetMaxLayers()
        print("[BusOneHeroYuanZheng_Get] 当前轮数 nRound = "..nRound.." nNextRound = "..nNextRound.." nMaxRound = "..nMaxRound)
        if nNextRound <= nMaxRound and nNowLayers == nMaxLayers then
            print("[BusOneHeroYuanZheng_Get] 进入下一轮")
            BusOneHeroYuanZheng_EnterRound(human, nNextRound)
        else
            print("[BusOneHeroYuanZheng_Get] 重置为第一轮")
            BusOneHeroYuanZheng_EnterRound(human, 1)
        end

        BusOneHeroYuanZheng_Query(human)
        YunYingLogic.sendBanner(human)
        BusOneActivityTask.BusOneTask_SendRed(human)
    else
        print("[BusOneHeroYuanZheng_Get] 不存在对应的奖励 nLayers = "..nLayers.." nIndex = "..nIndex)
    end
end

-----------------------------------外部调用-----------------------------
function isOpen(human, YYInfo, funcConfig)
    print("[BusOneHeroYuanZheng_isOpen] 进入判断")

    local state, endTime, startTime = AbsActLogic.isStarted(human, funcConfig and funcConfig.funcID or BUSONEHEROYUANZHENGABSID)
    if not state then
        print("[BusOneHeroYuanZheng_isOpen] 当前活动未开启")
        return 
    end
    print("[BusOneHeroYuanZheng_isOpen] 进入判断 endTime = "..endTime.." startTime = "..startTime)
    return true, endTime, startTime
end

function isActive(human, YYInfo, funcConfig)
    return not isOpen(human, YYInfo, funcConfig)
end

function isRed(human, YYInfo, absActConfig)
    BusOneHeroYuanZheng_CheckAndResetDB(human)

    local tConf = BusOneHeroYuanZheng_GetHeroConf()
    local nRound = BusOneHeroYuanZheng_GetRound(human)
    for _, v in ipairs(tConf) do
        if v.nRound == nRound then
            local nStatus = BusOneHeroYuanZheng_GetStatus(human, v.nLayers)
            if nStatus == CommonDefine.COMMON_PRIZE_STATE_CANGET then
                return true
            end
        end
    end
    
    return false
end