-- 通用节日活动 - 摇钱树
-- db
--[=[
    human.db.absAct[actId] = {
        basketItemArr = nil, --篮子里的道具idx列表

        lotteryTimes = nil, -- 抽奖次数

        nowStage = 0, -- 当前阶段, 0-未开始阶段, 1-抽奖阶段
    }   
]=]--

local Msg = require("core.Msg")
local Grid = require("bag.Grid")
local BagLogic = require("bag.BagLogic")
local AbsActLogic = require("absAct.AbsActLogic")
local Broadcast = require("broadcast.Broadcast")
local Lang = require("common.Lang")
local MoneyTreeConfig = require("excel.commonact").treereward
local YunYingLogic = require("yunying.YunYingLogic")
local AbsActExcel = require("excel.absAct")


local LOGTYPE = "CommonActMoneyTree" -- 日志标识
local COMMONACT_MONEYTREE_ID = 7506  -- 活动Id
local BASKET_WEIGHT_MAX = 150           -- 篮子可承受的总重量


local function getData(human)
    return human.db.absAct[COMMONACT_MONEYTREE_ID]
end

local function updateLotteryTimes(human, val)
    local actData = getData(human)
    actData.lotteryTimes = (actData.lotteryTimes or 0) + val
end

local function insertBasketItemArr(human, itemIdx)
    local actData = getData(human)
    actData.basketItemArr = actData.basketItemArr or {}
    table.insert(actData.basketItemArr, itemIdx)
end

local function updateBasketItemArr(human, newBasketItemArr)
    local actData = getData(human)
    actData.basketItemArr = newBasketItemArr
end

local function resetBasketArr(human)
    local actData = getData(human)
    actData.basketItemArr = nil
end

local function updateStage(human, newStage)
    local actData = getData(human)
    actData.nowStage = newStage
end




local function isOpenAct(human, funcID)
    return AbsActLogic.isStarted(human, funcID)
end

-- 计算篮子中所有道具的总重量
local function calcBasketWeight(basketItemArr)
    local weightSum = 0

    for _, cfgIdx in ipairs(basketItemArr or {}) do
        local itemCfg = MoneyTreeConfig[cfgIdx]
        weightSum = weightSum + itemCfg.value
    end

    return weightSum
end

-- 抽奖
local function lottery()
    local totalWeight = 0
    for _, itemCfg in ipairs(MoneyTreeConfig) do
        totalWeight = totalWeight + itemCfg.nWeight
    end

    local finalIdx = 0
    local weight = 0
    local randWeight = math.random(0, totalWeight)
    for i, itemCfg in ipairs(MoneyTreeConfig) do
        weight = weight + itemCfg.nWeight
        if randWeight <= weight then
            finalIdx = i
            break
        end
    end

    return finalIdx
end

-- 将篮子中每个道具都随机一次, 获得最新的篮子道具
local function randBasketItem(basketItemArr)
    local val = 50
    local newBasketItemArr = {}
    for _,itemCfgIdx in ipairs(basketItemArr) do
        local randVal = math.random(1, 100)
        if randVal >= val then
            newBasketItemArr[#newBasketItemArr+1] = itemCfgIdx
        end
    end

    return newBasketItemArr
end

-- 主动刷新一次红点
local function updateRedDot(human)
    YunYingLogic.sendBanner(human)
    local config = AbsActExcel.absActivity[COMMONACT_MONEYTREE_ID]
    YunYingLogic.sendGroupUpdate(YYInfo[COMMONACT_MONEYTREE_ID], human, config.panelID)
end



function isRed(human, YYInfo, funcConfig)
    local state = isOpenAct(human, funcConfig and funcConfig.funcID)
    if not state then
        return false
    end

    local actData = getData(human)

    if not actData then
        return false
    end

    if (actData.nowStage or 0) == 1 then
        return true
    end

    if (actData.lotteryTimes or 0) > 0 then
        return true
    end

    return false
end

function isOpen(human, YYInfo, funcConfig)
    return isOpenAct(human, funcConfig and funcConfig.funcID)
end

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

-- 日常任务活跃值达标
function CompleteHuoYueTask(human)
    if not isOpenAct(human, COMMONACT_MONEYTREE_ID) then
        return
    end

    updateLotteryTimes(human, 1)

    updateRedDot(human)
end

function genAbsActData()
    return {lotteryTimes = 1}
end

function updateDaily(human, funcID)
    if not isOpenAct(human, funcID) then
        return
    end

    local actData = getData(human)
    if not actData then
        return
    end

    updateLotteryTimes(human, 1)

    updateRedDot(human)
end



-- 查询
function CommonActMoneyTree_Query(human)
    if not isOpenAct(human, COMMONACT_MONEYTREE_ID) then
        return Broadcast.sendErr(human, Lang.YUNYING_ERR_TIME)
    end
    local msgRet = Msg.gc.GC_ABS_COMONACT_MONEYTREE_QUERY
    msgRet.rewardBasket[0] = 0
    msgRet.weighMax = BASKET_WEIGHT_MAX
    msgRet.weighNow = 0
    msgRet.lotteryTimes = 0
    msgRet.isStart = 1
    msgRet.isEnd = 0
    msgRet.nowStage = 0

    local actData = getData(human)

    if actData.lotteryTimes then
        msgRet.lotteryTimes = actData.lotteryTimes
    end

    if actData.basketItemArr then
        msgRet.weighNow = calcBasketWeight(actData.basketItemArr)
    end

    if actData.nowStage then
        msgRet.nowStage = actData.nowStage
    end

    local itemNum = actData.basketItemArr and #actData.basketItemArr or 0
    if itemNum == 0 then
        msgRet.isEnd = 1
        return Msg.send(msgRet, human.fd)
    end

    local len, msgOneceMaxLen = 0, 20

    for _, itemCfgIdx in ipairs(actData.basketItemArr) do
        len = len + 1
        msgRet.rewardBasket[0] = len

        local itemCfg = MoneyTreeConfig[itemCfgIdx].reward
        Grid.makeItem(msgRet.rewardBasket[len], itemCfg[1], itemCfg[2])

        if len >= msgOneceMaxLen then
            itemNum = itemNum - len
            if itemNum <= 0 then
                msgRet.isEnd = 1
                return Msg.send(msgRet, human.fd)
            end

            Msg.send(msgRet, human.fd)
            len = 0
            msgRet.isStart = 0
        end
    end

    if len > 0 then
        msgRet.isEnd = 1
        Msg.send(msgRet, human.fd)
    end
end

-- 进入抽奖阶段
function CommonActMoneyTree_EnterLotteryStage(human)
    if not isOpenAct(human, COMMONACT_MONEYTREE_ID) then
        return Broadcast.sendErr(human, Lang.YUNYING_ERR_TIME)
    end

    local actData = getData(human)
    if (actData.lotteryTimes or 0) <= 0 then
        return Broadcast.sendErr(human, Lang.JINBI_EXCHANGE_ERR_CNT)
    end

    -- 扣除次数
    updateLotteryTimes(human, -1)

    -- 更新阶段
    updateStage(human, 1)

    -- 推送最新数据给客户端
    CommonActMoneyTree_Query(human)
end

-- 抽一次奖
function CommonActMoneyTree_Lottery(human)
    if not isOpenAct(human, COMMONACT_MONEYTREE_ID) then
        return Broadcast.sendErr(human, Lang.YUNYING_ERR_TIME)
    end

    local actData = getData(human)
    if (actData.nowStage or 0) ~= 1 then
        return Broadcast.sendErr(human, Lang.MONEYTREE_START)
    end

    if actData.basketItemArr then
        local weightNow = calcBasketWeight(actData.basketItemArr)
        if weightNow > BASKET_WEIGHT_MAX then
            return Broadcast.sendErr(human, Lang.MONEYTREE_IS_MAX)
        end
    end

    -- 扣除次数
    -- updateLotteryTimes(human, -1)

    local finalIdx = lottery()
    if finalIdx == 0 then
        return Broadcast.sendErr(human, Lang.COMMON_COMFIG_ERROR)
    end

    -- 把道具加入篮子
    insertBasketItemArr(human, finalIdx)

    local msgRet = Msg.gc.GC_ABS_COMONACT_MONEYTREE_LOTTERY
    local itemCfg = MoneyTreeConfig[finalIdx]
    Grid.makeItem(msgRet.reward, itemCfg.reward[1], itemCfg.reward[2])
    Msg.send(msgRet, human.fd)

    CommonActMoneyTree_Query(human)
end

-- 领取奖励
function CommonActMoneyTree_GetReward(human)
    if not isOpenAct(human, COMMONACT_MONEYTREE_ID) then
        return Broadcast.sendErr(human, Lang.YUNYING_ERR_TIME)
    end

    local actData = getData(human)

    if (actData.nowStage or 0) ~= 1 then
        return Broadcast.sendErr(human, Lang.MONEYTREE_START)
    end

    if not actData.basketItemArr or not next(actData.basketItemArr) then
        return Broadcast.sendErr(human, Lang.SHARE_GROUP_GET_ERR_CNT)
    end


    -- 检查当前篮子中道具重量是否超过限定重量, 如果超过则当前篮子中每个道具都有50%几率失去
    local itemArr = actData.basketItemArr
    local weightNow = calcBasketWeight(itemArr)
    if weightNow > BASKET_WEIGHT_MAX then
        itemArr = randBasketItem(itemArr)
        -- updateBasketItemArr(human, newBasketItemArr)
        -- CommonActMoneyTree_Query(human)
    end


    local itemList = {}
    for _, itemCfgIdx in ipairs(itemArr) do
        local itemCfg = MoneyTreeConfig[itemCfgIdx].reward
        local itemId, itemNum = itemCfg[1], itemCfg[2]
        itemList[itemId] = (itemList[itemId] or 0) + itemNum
    end

    -- 重置篮子中道具数据
    resetBasketArr(human)

    -- 更新阶段
    updateStage(human, 0)

    -- 发放道具
    BagLogic.addItemList(human, itemList, LOGTYPE)

    -- 推送最新数据给客户端
    CommonActMoneyTree_Query(human)

    -- 刷新红点
    updateRedDot(human)
end
