local Msg = require("core.Msg")
local Util = require("common.Util")
local Lang = require("common.Lang")
local Broadcast = require("broadcast.Broadcast")
local PanelDefine = require("broadcast.PanelDefine")
local BagLogic = require("bag.BagLogic")
local Grid = require("bag.Grid")
local OpenAct = require("present.OpenAct")
local DrawCardLogic = require("drawCard.DrawCardLogic")
local YunYingLogic = require("yunying.YunYingLogic")
local OpenActExcel = require("excel.openAct")
--[[
	开服活动-累计消耗类活动 累计消耗钻、累计招募
	DB:
		human.db.openServerReach = {
            [type] = {              -- 消耗类型    
				value = xxx,		-- 累计消耗值
				[id] = xxx,			-- 档位领取状态(0不可领,1可领,2已领)
			    ... 
            },
            ...
		}
	local:
		getDB()				  		-- 获得单笔充值DB数据
        getOpenActConfig()          -- 通过消耗类型得到开服活动配置
        getOpenActParam()           -- 通过消耗类型得到开服活动参数
        getReachType()              -- 通过活动参数得到开服活动消耗类型
        reachTouchHanlde()          -- 消耗达标处理
		wrapTConsumeList()			-- 包装单笔充值档位数据
	public:
		isRed()                 	-- 红点提醒	
        isActive()                  -- 激活状态
		isBaseOpen()				-- 开启活动基本条件	
		isOpen()                	-- 活动开启	
        getLeftTime()               -- 得到活动剩余时间 
		query()						-- 发送活动信息
		get()						-- 领取活动奖励
		onDecZuanshi()				-- 消耗钻石回调
        onDrawCard()                -- 抽卡回调
--]]

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

OA_REACH_TYPE_1 = 1                 -- 钻石消耗
OA_REACH_TYPE_2 = 2                 -- 招募达标

local function getDB(human, reachType)
	human.db.openServerReach = human.db.openServerReach or {}
    human.db.openServerReach[reachType] = human.db.openServerReach[reachType] or {}
	return human.db.openServerReach[reachType]
end

local function getOpenActConfig(reachType)
    if reachType == OA_REACH_TYPE_1 then return OpenActExcel.totalConsume end
    if reachType == OA_REACH_TYPE_2 then return OpenActExcel.drawCardConsume end    
end

local function getOpenActParam(reachType)
    if reachType == OA_REACH_TYPE_1 then return OpenAct.OPEN_ACT_TOTAL_CONSUME end
    if reachType == OA_REACH_TYPE_2 then return OpenAct.OPEN_ACT_DRAW_CARD end
end

local function getReachType(funcConfig)
    if funcConfig.param == OpenAct.OPEN_ACT_TOTAL_CONSUME then return OA_REACH_TYPE_1 end
    if funcConfig.param == OpenAct.OPEN_ACT_DRAW_CARD then return OA_REACH_TYPE_2 end
end

local function reachTouchHanlde(human, funcID, reachType, value)
    local funcConfig = YunYingLogic.getFuncConfig(funcID)
    if not funcConfig then return end

    local openActConfig = getOpenActConfig(reachType)
    if not openActConfig then return end

    local tConsumeDB = getDB(human, reachType)
    tConsumeDB.value = (tConsumeDB.value or 0) + value

    -- 取之前是不是有红点
    local beforeRed = isRed(human, nil, funcConfig)

    local isActive
    for id,tConsumeInfo in ipairs(openActConfig) do
        if tConsumeInfo.needConsume <= tConsumeDB.value and 
            tConsumeDB[id] ~= STATE_2 then
            tConsumeDB[id] = STATE_1
            isActive = true
        end
    end
    
    -- 之前没有红点,现在激活了红点通知(只需要通知banner上的红点)
    if not beforeRed and isActive then
        YunYingLogic.sendBanner(human)
    end
end

local function wrapTConsumeList(net, id, tConsumeInfo, sConsumeDB)
	net.id = id
	net.needConsume = tConsumeInfo.needConsume
 	net.state = sConsumeDB[id] or STATE_0

 	local len = 0
	for index,itemInfo in ipairs(tConsumeInfo.rewards) do
		len = len + 1
		Grid.makeItem(net.items[index], itemInfo[1], itemInfo[2])
	end
	net.items[0] = len
end

function isRed(human, YYInfo, funcConfig)
    local reachType = getReachType(funcConfig)
    if not reachType then return end

    local openActConfig = getOpenActConfig(reachType)
    if not openActConfig then return end

	local tConsumesDB = getDB(human, reachType)
	if not tConsumesDB then return end
 
	for id in ipairs(openActConfig) do
		if tConsumesDB[id] and tConsumesDB[id] == STATE_1 then return true end
	end
end

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

function isBaseOpen(human, YYInfo, funcConfig, noSend)
    if human.db.lv < funcConfig.openLv then
        if not noSend then
            local str = Util.format(Lang.ROLE_LEV_ERROR, funcConfig.openLv)
            return Broadcast.sendErr(human, str)
        end
    end

    local flag = OpenAct.getOpenActTime(funcConfig.param)
    if not flag then return end

    return true
end

function isOpen(human, YYInfo, funcConfig)
    if isBaseOpen(human, YYInfo, funcConfig, true) then return true end
end

function getLeftTime(human, YYInfo, funcConfig)
    local _,leftTime = OpenAct.getOpenActTime(funcConfig.param)
    return leftTime
end

function query(human, reachType)
    local openActConfig = getOpenActConfig(reachType)
    if not openActConfig then return end

    local openActParam = getOpenActParam(reachType)
    if not openActParam then return end

    local _,leftTime = OpenAct.getOpenActTime(openActParam)
    local tConsumeDB = getDB(human, reachType)

    local msgRet = Msg.gc.GC_OPEN_SERVER_REACH_QUERY
    msgRet.type = reachType
	msgRet.value = tConsumeDB.value or 0
    msgRet.leftTime = leftTime
	local len = 0
	for id,tConsumeInfo in ipairs(openActConfig) do
		len = len + 1
		wrapTConsumeList(msgRet.list[len], id, tConsumeInfo, tConsumeDB)
	end
	msgRet.list[0] = len

	Msg.send(msgRet, human.fd)
end

function get(human, funcID, reachType, id)
    local funcConfig = YunYingLogic.getFuncConfig(funcID)
    if not funcConfig then return end

    local openActConfig = getOpenActConfig(reachType)
    if not openActConfig then return end

	local tConsumeInfo = openActConfig[id]	
	if not tConsumeInfo then return end

	local tConsumeDB = getDB(human, reachType)
	if tConsumeDB[id] ~= STATE_1 then return end

	tConsumeDB[id] = STATE_2
	BagLogic.addItemList(human, tConsumeInfo.rewards, "openServerTConsume_get")

	query(human, reachType)

    -- 现在没有红点了通知
    if not isRed(human, nil, funcConfig) then
        YunYingLogic.sendBanner(human)
        YunYingLogic.updateIcon(YYInfo[funcID], human)
        YunYingLogic.sendGroupUpdate(YYInfo[funcID], human, funcConfig.panelID)
    end
end

function onDecZuanshi(human, funcID, value)
    local funcConfig = YunYingLogic.getFuncConfig(funcID)
    if not funcConfig then return end

    if not isOpen(human, nil, funcConfig) then return end

    local reachType = getReachType(funcConfig)
    if reachType == OA_REACH_TYPE_1 then
        reachTouchHanlde(human, funcID, reachType, value)
    end
end

function onDrawCard(human, funcID, value, drawType)
    local funcConfig = YunYingLogic.getFuncConfig(funcID)
    if not funcConfig then return end

    if not isOpen(human, nil, funcConfig) then return end

    local reachType = getReachType(funcConfig)
    if reachType == OA_REACH_TYPE_2 then
        if drawType == DrawCardLogic.DRAWCARD_ID2 or 
            drawType == DrawCardLogic.DRAWCARD_ID5 or 
            drawType == DrawCardLogic.DRAWCARD_ID6 then
            reachTouchHanlde(human, funcID, reachType, value)
        end
    end
end