--[[
    absAct[id] = {
        drum = {
            [id] = cnt,state
            [id] = cnt,state
        }
        blasting = {
            [id] = cnt,state
        }
        box = {
            [id] = state
        }
        blastingCnt = 0
        buling = 0
    }

]]

-- 延迟加载 AbsActLogic，避免循环依赖
local AbsActLogic = nil
local function getAbsActLogic()
    if not AbsActLogic then
        AbsActLogic = require("absAct.AbsActLogic")
    end
    return AbsActLogic
end

local AbsActExcel = require("excel.absAct")
local BuyExcel = require("excel.buy")
local Util = require("common.Util")
local Msg = require("core.Msg")
local Grid = require("bag.Grid")
local BagLogic = require("bag.BagLogic")
local BuyLogic = require("topup.BuyLogic")
local YunYingLogic = require("yunying.YunYingLogic")
local Log = require("common.Log")

function isOpen(human, YYInfo, funcConfig)
    local state, endTime, startTime = getAbsActLogic().isStarted(human, funcConfig.funcID)
    if not state then return end
    local absAct = human.db.absAct[funcConfig.funcID]
    if absAct and absAct.dayCnt and absAct.dayCnt <= 0 and #absAct.item <= 0 then
        return false
    end
    return true, endTime, startTime
end

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


-- ��ʼ�����ݿ�
function initDB(human,id)
    local absAct = human.db.absAct[id]
    absAct.drum = absAct.drum or {} 
    absAct.blasting = absAct.blasting or {} 
    absAct.box = absAct.box or {} 
    absAct.blastingCnt = absAct.blastingCnt or 0 
    absAct.buling = absAct.buling or 0 
end

-- ��������
function getAndSendMsg(human,id,actID)
    -- �жϻ�Ƿ���
    local state, endTime, starTime = getAbsActLogic().isStarted(human, id)
    if not state then return end

    local absConfig = AbsActExcel.absActivity[id]
    if not absConfig then return end

    local absAct = human.db.absAct[id]
    if not absAct then
        -- Log.write(Log.LOGID_DEBUG, "[DrumBlastingLogic.getAndSendMsg] 活动数据不存在,创建空数据 - 活动ID: "..tostring(id))
        human.db.absAct[id] = {}
        human.db.absAct[id].finish = endTime
        absAct = human.db.absAct[id]
    end
    
    -- 检查并重置损坏/过期的数据
    if absAct and not absAct.drum then
        -- Log.write(Log.LOGID_DEBUG, "[DrumBlastingLogic.getAndSendMsg] 检测到数据不完整,重新初始化 - 活动ID: "..tostring(id))
        human.db.absAct[id] = {}
        human.db.absAct[id].finish = endTime
        absAct = human.db.absAct[id]
    end
    
    -- Log.write(Log.LOGID_DEBUG, "[DrumBlastingLogic.getAndSendMsg] 初始化数据 - 玩家: "..tostring(human.db.name)..", 活动ID: "..tostring(id))
    initDB(human,id)
    
    local nowDay = Util.diffDay(starTime) + 1
    -- ��������
    local msgRet = Msg.gc.GC_ABS_ND_TASK_QUERY
    -- ������
    local taskConfig = AbsActExcel.drum
    local len = #taskConfig
    local count = 0
    msgRet.day = nowDay
    BuyLogic.fontBuyItem(human, msgRet.buyItem, AbsActExcel.blastingBox[1].buyID)
    for i = 1,len do
        local v = taskConfig[i]
        if v.day == nowDay then
            count = count + 1
            local net = msgRet.drumList[count]
            net.id = i
            net.desc = v.desc
            net.name = v.name
            net.needCnt = v.needCnt
            net.panelID = v.panelID
            net.nowCnt = absAct.drum[i] and absAct.drum[i].cnt or 0
            net.state = absAct.drum[i] and absAct.drum[i].state or 0
            for j = 1,#v.item do
                Grid.makeItem(net.item[j],v.item[j][1],v.item[j][2])
            end
            net.item[0] = #v.item
        end
    end
    msgRet.drumList[0] = count
    -- ������
    taskConfig = AbsActExcel.blasting
    len = #taskConfig
    for i = 1,len do
        local v = taskConfig[i]
        local net = msgRet.blastingList[i]
        net.id = i 
        net.desc = v.desc
        net.name = v.name
        net.needCnt = v.needCnt
        net.nowCnt = absAct.blasting[i] and absAct.blasting[i].cnt or 0
        net.state = absAct.blasting[i] and absAct.blasting[i].state or 0
        local itemLen = type(v.item[nowDay]) == "table" and #v.item[nowDay] or 0
        for j = 1,itemLen do
            Grid.makeItem(net.item[j],v.item[nowDay][j][1],v.item[nowDay][j][2])
        end
        net.item[0] = itemLen --#v.item[nowDay]
        net.panelID = v.panelID or 0
    end
    msgRet.blastingList[0] = len
    -- ��������
    taskConfig = AbsActExcel.blastingBox
    len = #taskConfig
    for i = 1,len do
        local v = taskConfig[i]
        local net = msgRet.boxList[i]
        net.id = i
        net.needCnt = v.needCnt
        net.state = absAct.box[i] or 0
        for j = 1,#v.item do
            Grid.makeItem(net.item[j],v.item[j][1],v.item[j][2])
        end
        net.item[0] = #v.item
    end
    msgRet.boxList[0] = len
    msgRet.blastingCnt = absAct.blastingCnt
    Msg.send(msgRet,human.fd)
end

-- ��ȡ��Ʒ
-- type 1��,2��,3��
function get(human,index,itemType,id)
    -- �жϻ�Ƿ���
    local state, endTime, starTime = getAbsActLogic().isStarted(human, id)
    if not state then return end

    local absConfig = AbsActExcel.absActivity[id]
    if not absConfig then return end

    local absAct = human.db.absAct[id]
    if not absAct then
        return
    end
    initDB(human,id)

    local nowDay = Util.diffDay(starTime) + 1
    local allItems = {}  -- ����������ȡʱ�ռ����н���
    
    -- ���indexΪ0��nil����������ȡ��type�����п���ȡ�Ľ���
    if index then
        local hasReward = false
        
        if itemType == 1 then
            -- �������񣺱�������drum������ȡ״̬Ϊ1��
            local taskConfig = AbsActExcel.drum
            for i = 1, #taskConfig do
                local v = taskConfig[i]
                if v.day == nowDay then
                    -- ȷ�����ݽṹ����
                    absAct.drum[i] = absAct.drum[i] or {}
                    local taskState = absAct.drum[i].state or 0
                    if taskState == 1 then
                        hasReward = true
                        -- �ռ�����
                        for j = 1, #v.item do
                            table.insert(allItems, v.item[j])
                        end
                        -- ����״̬
                        absAct.drum[i].state = 2
                    end
                end
            end
        elseif itemType == 2 then
            -- ���ڽ�������������blasting����ȡ״̬Ϊ1��
            local taskConfig = AbsActExcel.blasting
            for i = 1, #taskConfig do
                local v = taskConfig[i]
                -- ȷ�����ݽṹ����
                absAct.blasting[i] = absAct.blasting[i] or {}
                local blastingState = absAct.blasting[i].state or 0
                if blastingState == 1 then
                    hasReward = true
                    -- �ռ�����
                    local itemLen = type(v.item[nowDay]) == "table" and #v.item[nowDay] or 0
                    for j = 1, itemLen do
                        table.insert(allItems, v.item[nowDay][j])
                    end
                    -- ����״̬
                    absAct.blasting[i].state = 2
                    -- ����һ�Σ��ۼƷ��ڴ������ж��Ƿ�ﵽ���Ƚ�����ȡֵ
                    absAct.blastingCnt = (absAct.blastingCnt or 0) + 1
                    for j = 1, #AbsActExcel.blastingBox do
                        if absAct.blastingCnt - 1 < AbsActExcel.blastingBox[j].needCnt and absAct.blastingCnt == AbsActExcel.blastingBox[j].needCnt then
                            absAct.box[j] = 1
                            break
                        end
                    end
                end
            end
        elseif itemType == 3 then
            -- ���Ƚ�������������box����ȡ״̬Ϊ1��
            local taskConfig = AbsActExcel.blastingBox
            for i = 1, #taskConfig do
                local v = taskConfig[i]
                local boxState = absAct.box[i] or 0
                if boxState == 1 then
                    hasReward = true
                    -- �ռ�����
                    for j = 1, #v.item do
                        table.insert(allItems, v.item[j])
                    end
                    -- ����״̬
                    absAct.box[i] = 2
                end
            end
        end
        
        -- ����н������򷢷�
        if hasReward and #allItems > 0 then
            BagLogic.addItemList(human, allItems, "abs_drumblasting")
            getAndSendMsg(human, id, absConfig.actID)
            YunYingLogic.sendBanner(human)
            YunYingLogic.sendGroupUpdate(YYInfo[id], human, absConfig.panelID)
        end
        return
    end
    
    -- ԭ���߼���������ȡ
    local item = nil

    -- ѡ���Ӧ����?
    local config = nil
    local state = nil
    if itemType == 1 then
        config = AbsActExcel.drum[index]
        state = absAct.drum[index] and absAct.drum[index].state or 0
    elseif itemType == 2 then
        config = AbsActExcel.blasting[index]
        state = absAct.blasting[index] and absAct.blasting[index].state or 0
    elseif itemType == 3 then
        config = AbsActExcel.blastingBox[index]
        state = absAct.box[index] or 0
    end

    -- �����������?
    if not config then
        return 
    end

    -- ״̬��Ϊ����ȡ
    if state ~= 1 then
        return
    end

    -- �ı�״̬
    if itemType == 1 then
        item = config.item
        absAct.drum[index].state = 2
    elseif itemType == 2 then
        item = config.item[nowDay]
        absAct.blasting[index].state = 2
        -- ����һ��,�����ۼƴ��������ж��Ƿ�ﵽ������ȡ���?
        absAct.blastingCnt = absAct.blastingCnt + 1
        for i = 1,#AbsActExcel.blastingBox do
            if absAct.blastingCnt - 1 < AbsActExcel.blastingBox[i].needCnt and absAct.blastingCnt == AbsActExcel.blastingBox[i].needCnt then
                absAct.box[i] = 1
                break
            end
        end
    elseif itemType == 3 then
        item = config.item
        absAct.box[index] = 2
    else
        return
    end

    BagLogic.addItemList(human, item, "abs_drumblasting")
    getAndSendMsg(human,id,absConfig.actID)
    
    YunYingLogic.sendBanner(human)
    YunYingLogic.sendGroupUpdate(YYInfo[id], human, absConfig.panelID)
end

-- ÿ�������Ծ��?
function onDailyTask(human,funcID, parameter)
    drumTaskCallBack(human,funcID,1,parameter)
end

-- �ٻ�
function onDrawCard(human,funcID, parameter)
    drumTaskCallBack(human,funcID,2,parameter)
end

-- ��ħ֮��
function onHuangjingTower(human,funcID, parameter)
    drumTaskCallBack(human,funcID,3,parameter)
end

-- ��ֵ
function onCharge(human, parameter,funcID)
    -- 临时处理 
    drumTaskCallBack(human,funcID,4,parameter)
end

-- ��������
function onDrill(human,funcID, parameter)
    drumTaskCallBack(human,funcID,5,parameter)
end

-- Ů��ɭ��
function onCopyChallenge(human,funcID, parameter)
    drumTaskCallBack(human,funcID,6,parameter)
end

-- �ھ�����
function onJjcFight(human,funcID, parameter)
    drumTaskCallBack(human,funcID,7,parameter)
end

-- ����̵깺��?
function onShopBuy(human,funcID,parameter)
    drumTaskCallBack(human,funcID,8,parameter)
end

-- ð��ɨ��
function onMopup(human,funcID,parameter)
    drumTaskCallBack(human,funcID,9,parameter)
end

-- ������Ѩ
function onBinglong(human,funcID,parameter)
    drumTaskCallBack(human,funcID,10,parameter)
end

-- ���?
function onExchangeJinbi(human,funcID,parameter)
    drumTaskCallBack(human,funcID,11,parameter)
end

-- ����
function onBarTaskgetDo(human,funcID,parameter)
    drumTaskCallBack(human,funcID,12,parameter)
end

-- ����
function onUnionDonate(human,funcID,parameter)
    drumTaskCallBack(human,funcID,13,parameter)
end

-- ���ḱ��
function onUnionEctypeFight(human,funcID,parameter)
    drumTaskCallBack(human,funcID,14,parameter)
end

-- ռ��
function onZhanBuBuyCard(human,funcID,parameter)
    -- ZhanbuLogic.lua  436�? 传的数值为�?, 不知道哪�?监听该事件的地方需要数值为负，所以只处理当前模块
    if parameter < 0 then
        return
    end
    drumTaskCallBack(human,funcID,15,parameter)
end

-- ������ʯ
function onDecZuanshi(human,funcID,parameter)
    drumTaskCallBack(human,funcID,16,parameter)
end

-- ������Ԩ
function onLianyu(human,funcID,parameter)
    drumTaskCallBack(human,funcID,17,parameter)
end

-- �ϳɷ���
function onFuwenHecheng(human,funcID,parameter)
    drumTaskCallBack(human,funcID,18,parameter)
end



-- �ص�
function drumTaskCallBack(human,id,type,cnt)
    getAbsActLogic().checkAbsActClean(human, id)
   

    local state, endTime, starTime = getAbsActLogic().isStarted(human, id)
    -- 活動�?開啓
    if not state or os.time() > endTime then 
        return
    end
    
    local absConfig = AbsActExcel.absActivity[id]
    if not absConfig then return end

    local absActData = human.db.absAct[id]
    if not absActData then 
        return
    end

    initDB(human,id)

    local nowDay = Util.diffDay(starTime) + 1
    -- ������������������
    local taskConfig = AbsActExcel.drum
    for k = 1,#taskConfig do
        if taskConfig[k].type == type and taskConfig[k].day == nowDay then
            local taskID = k
            human.db.absAct[id].drum[taskID] = human.db.absAct[id].drum[taskID] or {}
            human.db.absAct[id].drum[taskID].cnt = human.db.absAct[id].drum[taskID].cnt or 0
            human.db.absAct[id].drum[taskID].state = human.db.absAct[id].drum[taskID].state or 0
            human.db.absAct[id].drum[taskID].cnt = human.db.absAct[id].drum[taskID].cnt + cnt
            if human.db.absAct[id].drum[taskID].state ~= 0 and cnt < 0 then
                human.db.absAct[id].drum[taskID].cnt = human.db.absAct[id].drum[taskID].cnt - cnt
            end
            local config = AbsActExcel.drum[taskID]
            -- ��������
            if human.db.absAct[id].drum[taskID].cnt >= config.needCnt and human.db.absAct[id].drum[taskID].state == 0 then
                human.db.absAct[id].drum[taskID].state = 1
                -- �ж��Ƿ���������
                for i = 1,#config.blasting do
                    local blastingID = config.blasting[i]
                    local blastingConfig = AbsActExcel.blasting[blastingID]
                    human.db.absAct[id].blasting[blastingID] = human.db.absAct[id].blasting[blastingID] or {}
                    human.db.absAct[id].blasting[blastingID].cnt = human.db.absAct[id].blasting[blastingID].cnt or 0
                    human.db.absAct[id].blasting[blastingID].state = human.db.absAct[id].blasting[blastingID].state or 0
                    human.db.absAct[id].blasting[blastingID].cnt = human.db.absAct[id].blasting[blastingID].cnt + 1
                    if human.db.absAct[id].blasting[blastingID].cnt >= 3 and human.db.absAct[id].blasting[blastingID].state ~= 2 then
                        human.db.absAct[id].blasting[blastingID].state = 1
                    end
                end
            end
        end
    end
    
    YunYingLogic.sendBanner(human)
    YunYingLogic.sendGroupUpdate(YYInfo[id], human, absConfig.panelID)
end

-- ÿ�����ùģ���״̬
function updateDaily(human,id)
    local state, endTime, starTime = getAbsActLogic().isStarted(human, id)
    if not state then return end

    local config = AbsActExcel.absActivity[id]
    if not config then return end

    getAbsActLogic().checkAbsActClean(human, id)

    local absAct = human.db.absAct[id] or {}
    absAct.drum = {} 
    absAct.blasting = {} 
    absAct.box = absAct.box or {} 
    absAct.blastingCnt = absAct.blastingCnt or 0
    human.db.absAct[id] = absAct
end

 -- 因为玩�?�在活动�?开�?前完成了活跃度任务，活动开�?后没法完成活跃度任务,所以在玩�?�上线时,做一次更新活跃度数据操作
function specialFunc(human, id)
    getAbsActLogic().checkAbsActClean(human, id)
    local state, endTime, starTime = getAbsActLogic().isStarted(human, id)
    -- 活動�?開啓
    if not state or os.time() > endTime then 
        return
    end
    
    local absConfig = AbsActExcel.absActivity[id]
    if not absConfig then return end

    local absActData = human.db.absAct[id]
    if not absActData then 
        return
    end

    initDB(human,id)
    local nowHuoYue = human.db.dailyTask and human.db.dailyTask.nowHuoYue or 0
    if nowHuoYue > 0 then
        local nowDay = Util.diffDay(starTime) + 1
        local actType = 1
        -- ������������������
        local singleData
        local isChange = false
        local taskConfig = AbsActExcel.drum
        for k = 1,#taskConfig do
            if taskConfig[k].type == actType and taskConfig[k].day == nowDay then
                local taskID = k
                human.db.absAct[id].drum[taskID] = human.db.absAct[id].drum[taskID] or {}
                singleData = human.db.absAct[id].drum[taskID]
                singleData.cnt = singleData.cnt or 0
                singleData.state = singleData.state or 0
                if singleData.cnt > 0 then 
                    break 
                end
                singleData.cnt = nowHuoYue
                isChange = true

                -- if human.db.absAct[id].drum[taskID].state ~= 0 and cnt < 0 then
                --     human.db.absAct[id].drum[taskID].cnt = human.db.absAct[id].drum[taskID].cnt - cnt
                -- end
                local config = AbsActExcel.drum[taskID]
                -- ��������
                if singleData.cnt >= config.needCnt and singleData.state == 0 then
                    singleData.state = 1
                    -- �ж��Ƿ���������
                    for i = 1,#config.blasting do
                        local blastingID = config.blasting[i]
                        local blastingConfig = AbsActExcel.blasting[blastingID]
                        human.db.absAct[id].blasting[blastingID] = human.db.absAct[id].blasting[blastingID] or {}
                        human.db.absAct[id].blasting[blastingID].cnt = human.db.absAct[id].blasting[blastingID].cnt or 0
                        human.db.absAct[id].blasting[blastingID].state = human.db.absAct[id].blasting[blastingID].state or 0
                        human.db.absAct[id].blasting[blastingID].cnt = human.db.absAct[id].blasting[blastingID].cnt + 1
                        if human.db.absAct[id].blasting[blastingID].cnt >= 3 and human.db.absAct[id].blasting[blastingID].state ~= 2 then
                            human.db.absAct[id].blasting[blastingID].state = 1
                        end
                    end
                end
            end
        end
        
        if isChange then
            YunYingLogic.sendBanner(human)
            YunYingLogic.sendGroupUpdate(YYInfo[id], human, absConfig.panelID)
        end
    end
end

function onLogin(human, id)
    specialFunc(human, id)
end


function isRed(human, YYInfo, funcConfig)
    local state = getAbsActLogic().isStarted(human, funcConfig.funcID)
    if not state then return end
    local absConfig = AbsActExcel.absActivity[funcConfig.funcID]
    local absAct = human.db.absAct[funcConfig.funcID]
    if not absAct then  return true end

    initDB(human,funcConfig.funcID)

    for k,v in pairs(absAct.drum) do
        if v.state == 1 then
            return true
        end
    end

    for k,v in pairs(absAct.blasting) do
        if v.state == 1 then
            return true
        end
    end

    for k,v in pairs(absAct.box) do
        if v == 1 then
            return true
        end
    end

    return false
end

-- ������
function buling(human,funcID,conf)
    -- ����������Ϊ30��
    getAbsActLogic().checkAbsActClean(human, funcID)
    initDB(human,funcID)
    local absConfig = AbsActExcel.absActivity[funcID]
    -- 
    local absAct = human.db.absAct[funcID]
    
    if absAct.buling == 1 then
        return
    end
    absAct.buling = 1

    local config = AbsActExcel.blastingBox
    local len = #config
    for i = 1,len do
        if config[i].needCnt > absAct.blastingCnt then
            absAct.blastingCnt = config[i].needCnt
            absAct.box[i] = 1
        end
    end
    getAndSendMsg(human,id,absConfig.actID)
end