local AbsActLogic = require("absAct.AbsActLogic")
local AbsActExcel = require("excel.absAct")
local Msg = require("core.Msg")
local Grid = require("bag.Grid")
local BagLogic = require("bag.BagLogic")
local AbsActDefine = require("absAct.AbsActDefine")
local YunYingLogic = require("yunying.YunYingLogic")
local PanelDefine = require("broadcast.PanelDefine")
local BuyLogic = require("topup.BuyLogic")
local Util = require("common.Util")
local CycleActivityLogic = require("yunying.CycleActivity")

--[[
    absAct.xlsx-exclusiveTask、absAct.xlsx-exclusiveTaskBox
    新英雄来袭-专属任务
        1.完成任务可获得任务奖励,还会增加宝箱积分
        2.宝箱积分达到指定数量可获得宝箱奖励
        3.现在只实现了任务7和任务8,后续新加任务需要再实现
    DB:
      human.db.absAct[id] = {
        boxScore = xx,      -- 箱子积分数
        task = {            -- 任务数据
            xxx = {         -- 任务id
                cnt = xxx,  -- 完成进度
                state = xxx,-- 任务状态 1可领 2已领
            },
            ...
        }，
        box = {
            xxx = state,   -- 箱子id = 箱子状态 1可领 2已领
            ...
        },
        buling = 0,        -- 补领状态
      }
    local:
        isComplRuleTask()       -- 是否完成了任务
    public:
        getAndSendMsg()         -- 发送活动数据
        isRed()                 -- 红点提醒
        isActive()              -- 激活状态
        isOpen()                -- 活动开启
        getLeftTime()           -- 得到活动剩余时间
        getBoxReward()          -- 领取箱子奖励
        getTaskReward()         -- 领取任务奖励
        finishTaskCB()          -- 任务完成回调
--]]

HERO_LOG_TYPE_1 = 1 --每日登录
HERO_LOG_TYPE_2 = 2 --冠军联赛挑战X次
HERO_LOG_TYPE_3 = 3 --扫荡X次
HERO_LOG_TYPE_4 = 4 --领取X次5星以上悬赏任务
HERO_LOG_TYPE_5 = 5 --任意难度勇者试炼通关X次
HERO_LOG_TYPE_6 = 6 --累计消耗X钻石
HERO_LOG_TYPE_7 = 7 --获得任务中指定的英雄
HERO_LOG_TYPE_8 = 8 --获得任务中指定的英雄升到多少星

STATE_0 = 0  -- 不可领
STATE_1 = 1  -- 可领
STATE_2 = 2  -- 已领

local function isComplRuleTask(type, rules, value1, value2)
    if not rules then return true end

    local isCompl
    -- 特殊完成规则
    if type == HERO_LOG_TYPE_7 then  
        for _,heroID in ipairs(rules) do
            if value1 == heroID then
                isCompl = true
                break
            end
        end
    elseif type == HERO_LOG_TYPE_8 then
        for _,rule in ipairs(rules) do
            if value1 == rule[1] and value2 >= rule[2] then
                isCompl = true
                break
            end
        end
    else
        isCompl = true
    end

    return isCompl
end

local function finishTaskCB(human, funcID, type, cnt, value1, value2)
    local absActConfig = AbsActExcel.absActivity[funcID]
    if not absActConfig then return end

    -- AbsActLogic.checkAbsActClean(human, funcID)
    local absAct = human.db.absAct[funcID]
    if not absAct then return end

    local isActive
    for index,v in pairs(AbsActExcel.exclusiveTask) do
        if v.actID == absActConfig.actId and v.type == type and isComplRuleTask(type, v.rules, value1, value2) then
            absAct.task = absAct.task or {}
            if not absAct.task[index] or absAct.task[index].cnt < v.maxCnt then
                absAct.task[index] = absAct.task[index] or {}
                absAct.task[index].cnt = absAct.task[index].cnt or 0
                absAct.task[index].cnt = absAct.task[index].cnt + cnt
                absAct.task[index].state = 0
                if absAct.task[index].cnt >= v.maxCnt then
                    absAct.task[index].state = STATE_1
                    isActive = true
                end
            end
        end
    end

    if isActive then
        YunYingLogic.sendGroupUpdate(YYInfo[funcID], human, absActConfig.panelID)
        YunYingLogic.sendBanner(human)
    end
end

function getAndSendMsg(human, id, actId)
    -- local state,endTime, starTime = AbsActLogic.isStarted(human, id)
    local state,endTime, starTime = CycleActivityLogic.isStarted(human, id)
    if not state then return end

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

    local msgRet = Msg.gc.GC_ABS_ACT_EXCLUSIVE_TASK_QUERY
    msgRet.actId = id
    msgRet.boxScore = absAct.boxScore or 0

    local nowDay = Util.diffDay(starTime) + 1
    msgRet.day = nowDay

    local len = 0
    for index,v in pairs(AbsActExcel.exclusiveTask) do
        if v.actID == actId then
            len = len + 1
            msgRet.taskList[len].id = index
            msgRet.taskList[len].state = STATE_0
            msgRet.taskList[len].maxCnt = v.maxCnt
            msgRet.taskList[len].desc = v.desc
            msgRet.taskList[len].panelID = v.panelID
            msgRet.taskList[len].addScoreCnt = v.addBoxCnt
            if not absAct.task or not absAct.task[index] then 
                msgRet.taskList[len].nowCnt = 0
            else
                msgRet.taskList[len].nowCnt = absAct.task[index].cnt
                msgRet.taskList[len].state = absAct.task[index].state
            end
            for i = 1,#v.item do
                Grid.makeItem(msgRet.taskList[len].item[i],v.item[i][1],v.item[i][2])
            end
            msgRet.taskList[len].item[0] = #v.item
        end
    end
    msgRet.taskList[0] = len

    len = 0
    local buyID
    for index,v in pairs(AbsActExcel.exclusiveTaskBox) do
       if v.actId == actId then
            if not buyID and v.buyID ~= 0 then
                buyID = v.buyID
            end

            len = len + 1
            msgRet.box[len].id = index
            msgRet.box[len].needCnt = v.needCnt
            if not absAct.box or not absAct.box[index] then 
                msgRet.box[len].state = STATE_0
            else
                msgRet.box[len].state = absAct.box[index]
            end
            for i = 1,#v.item do
                Grid.makeItem(msgRet.box[len].item[i],v.item[i][1],v.item[i][2])
            end
            msgRet.box[len].item[0] = #v.item
       end
    end
    msgRet.box[0] = len
    
    BuyLogic.fontBuyItem(human, msgRet.buyItem, buyID) 

    Msg.send(msgRet,human.fd)
end

function isRed(human, YYInfo, funcConfig)
    -- local state, endTime, starTime = AbsActLogic.isStarted(human, )
    local state,endTime, starTime = CycleActivityLogic.isStarted(human, funcConfig.funcID)
    if not state then return end

    local absAct = human.db.absAct[funcConfig.funcID]
    if not absAct or (not absAct.box and not absAct.task) then
        return
    end

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

    if absAct.task then
        for _,v in pairs(absAct.task) do
            if v.state == STATE_1 then return true end
        end
    end

    return false
end

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

function isOpen(human, YYInfo, funcConfig)
    -- return AbsActLogic.isStarted(human, funcConfig.funcID)
    return CycleActivityLogic.isStarted(human, funcConfig.funcID)
end

function getLeftTime(human, YInfo, funcConfig)
    -- local ret, endTime, startTime = AbsActLogic.isStarted(human, funcConfig.funcID)
    local ret, endTime, startTime = CycleActivityLogic.isStarted(human, funcConfig.funcID)
    if ret == true then
        return endTime - os.time()
    else
        return 0
    end
end

function getBoxReward(human, index, id)
    -- local state,endTime, starTime = AbsActLogic.isStarted(human, id)
    local state,endTime, starTime = CycleActivityLogic.isStarted(human, id)
    if not state then return end

    -- AbsActLogic.checkAbsActClean(human, id)
    local absAct = human.db.absAct[id]
    if not absAct or not absAct.box then return end

    if absAct.box[index] ~= STATE_1 then return end

    local absActConfig = AbsActExcel.absActivity[id]

    absAct.box[index] = STATE_2
    BagLogic.addItemList(human, AbsActExcel.exclusiveTaskBox[index].item, "abs_exclusive_task_box_get")
    
    getAndSendMsg(human, id, absActConfig.actId)

    YunYingLogic.sendBanner(human)
    YunYingLogic.updateIcon(YYInfo[id], human)
    YunYingLogic.sendGroupUpdate(YYInfo[id], human, absActConfig.panelID)
end

function getTaskReward(human, index, id)
    -- local state,endTime, starTime = AbsActLogic.isStarted(human, id)
    local state,endTime, starTime = CycleActivityLogic.isStarted(human, id)

    if not state then return end

    -- AbsActLogic.checkAbsActClean(human, id)
    local absAct = human.db.absAct[id]
    if not absAct or not absAct.task then return end

    -- 不可领或已领过
    if not absAct.task or not absAct.task[index] 
        or absAct.task[index].state ~= STATE_1 then return end

    local absActConfig = AbsActExcel.absActivity[id]
    local absExTaskInfo = AbsActExcel.exclusiveTask[index]

    absAct.task[index].state = STATE_2
    absAct.boxScore = (absAct.boxScore or 0) + absExTaskInfo.addBoxCnt
    for index2,v2 in ipairs(AbsActExcel.exclusiveTaskBox) do
        if v2.actId == absActConfig.actId and absAct.boxScore >= v2.needCnt then
            absAct.box = absAct.box or {}
            absAct.box[index2] = absAct.box[index2] or STATE_1
        end
    end

    BagLogic.addItemList(human, absExTaskInfo.item, "abs_exclusive_task_get")
    getAndSendMsg(human, id, absActConfig.actId)

    YunYingLogic.sendBanner(human)
    YunYingLogic.updateIcon(YYInfo[id], human)
    YunYingLogic.sendGroupUpdate(YYInfo[id], human, absActConfig.panelID)
end

function onLogin(human,funcID)
    finishTaskCB(human, funcID, 1, 1)
end

function onCharge(human, price, funcID)
    finishTaskCB(human, funcID, 3, price)
end

function onDailyTask(human,funcID, parameter)
    finishTaskCB(human, funcID, 2, parameter)
end

function onBinglong(human, funcID, parameter)
    finishTaskCB(human, funcID, 4, parameter)
end

function onDecZuanshi(human, funcID, parameter)
    finishTaskCB(human, funcID, 5, parameter)
end

function onGetNewHeroAct(human, funcID, parameters)
    local logType = parameters[1]
    if logType == "abs_hero_come_draw_card" or logType == "item_summon" then
        local heroID = parameters[2]
        local cnt = parameters[3] or 1
        finishTaskCB(human, funcID, HERO_LOG_TYPE_7, cnt, heroID)
    end
end

function onHeroStarChange(human, funcID, parameters)
    local heroID = parameters[1]
    local star = parameters[2] or 0
    local cnt = parameters[3] or 1
    finishTaskCB(human, funcID, HERO_LOG_TYPE_8, cnt, heroID, star)
end

function buling(human,funcID,conf)
    if funcID ~= conf.args[1] then
        return
    end

    -- boxScore设置成最大值
    local absConfig = AbsActExcel.absActivity[funcID]
    local absAct = human.db.absAct[funcID]
    if not absAct then
        return
    end

    if absAct.buling == 1 then
        return
    end

    absAct.buling = 1
    local maxNeedCnt
    for index,v in pairs(AbsActExcel.exclusiveTaskBox) do
        if v.actId == absConfig.actId then
            if not maxNeedCnt or maxNeedCnt < v.needCnt then
                maxNeedCnt = v.needCnt
            end
        end
    end
    absAct.boxScore = maxNeedCnt

    for index2,v2 in ipairs(AbsActExcel.exclusiveTaskBox) do
        if v2.actId == absConfig.actId and absAct.boxScore >= v2.needCnt then
            absAct.box = absAct.box or {}
            absAct.box[index2] = absAct.box[index2] or STATE_1
        end
    end

    getAndSendMsg(human, funcID, absConfig.actId)
    YunYingLogic.sendBanner(human)
    YunYingLogic.updateIcon(YYInfo[id], human)
    YunYingLogic.sendGroupUpdate(YYInfo[id], human, absConfig.panelID)
end

function updateDaily(human, funcID)
    -- local state, endTime, starTime = AbsActLogic.isStarted(human, funcID)
    local state, endTime, starTime = CycleActivityLogic.isStarted(human, funcID)
    if not state then return end

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

    local isUpdate = false
    local absActConf = AbsActExcel.absActivity[funcID]
    for index,v in pairs(AbsActExcel.exclusiveTask) do
        if v.actID == absActConf.actId then
            if v.refresh == 0 then
                isUpdate = false
                break
            elseif v.refresh == 1 then
                isUpdate = true
                break
            end
        end
    end

    if isUpdate == true then
        absAct.task = {}
    end
end