-- 循环累计充值活动, 开服第8天开始, 每7天一轮, 活动循环开
-- 为保证合服后玩家不受影响, 将活动时间, 充值等数据绑在玩家身上

--db  
--[[
    human.db.cycleRechargeData = 
    {
        startTime = nil, 本轮开启时间
        totalRecharge = 0, 本轮累计充值
        receiveList  = {}, 已经领取列表
    }
]]--

local Msg = require("core.Msg")
local Grid = require("bag.Grid")
local BagLogic = require("bag.BagLogic")
local Lang = require("common.Lang")
local Broadcast = require("broadcast.Broadcast")
local CommonDB = require("common.CommonDB")
local Util = require("common.Util")
local cycleRechargeCfg = require("excel.cycleRecharge").cycleRecharge
local MailManager = require("mail.MailManager")
local MailExcel = require("excel.mail")
local YunYingLogic = require("yunying.YunYingLogic")

-- 开服第8天开始
local OPEN_DAYS = 8

-- 每轮活动持续天数
local DURATION_DAYS = 7

local DAY_SECS = 86400

-- 邮件ID
local MAILID = 7019

-- 日志标识
local LOGTAG = "ActCycleRechargeLogic"

--活动ID
local ACTID = 3314


local function initActData(human)
    human.db.cycleRechargeData = {}
end

local function getActData(human)
    return human.db.cycleRechargeData
end

local function updateActStartTime(human, ti)
    local cycleRechargeData = getActData(human)
    cycleRechargeData.startTime = ti
end

local function updateActReceiveList(human, newReceiveList)
    local cycleRechargeData = getActData(human)
    cycleRechargeData.receiveList = cycleRechargeData.receiveList or {}
    for k in pairs(newReceiveList) do
        cycleRechargeData.receiveList[k] = '1'
    end
end

local function updateActTotalRecharge(human, money)
    local cycleRechargeData = getActData(human)
    cycleRechargeData.totalRecharge = (cycleRechargeData.totalRecharge or 0) + money
end




local function isRecharge(human)
    return (human.db.topupAcount and human.db.topupAcount > 0) and true or false
end

-- 开服时间
local function getOpenServerTime()
    return CommonDB.getServerOpenTime()
end

-- 计算角色的活动首次开启时间
local function calcRoleFirstOpenTime()
    local openServerTime = getOpenServerTime()
    local dayStartTime = Util.getDayStartTime(os.time())
    local actFirstOpenTime = Util.getDayStartTime(openServerTime + (OPEN_DAYS - 1) * DAY_SECS)

    if dayStartTime < actFirstOpenTime then
        return
    end



    -- -- 当天与活动首次开启时间的天数差
    -- local days_passed = math.floor((dayStartTime - actFirstOpenTime) / DAY_SECS)

    -- -- 当前属于第几轮
    -- local crurrent_round = math.floor(days_passed / DURATION_DAYS) + 1

    -- -- 本轮的开启时间
    -- local crurrent_round_openTime = actFirstOpenTime + (crurrent_round - 1) * DURATION_DAYS * DAY_SECS

    -- return crurrent_round_openTime

    return dayStartTime
end

-- 获取可领档位的索引
local function getAwardIdx(human)
    local cycleRechargeData = getActData(human)
    local totalRecharge = cycleRechargeData.totalRecharge
    if not totalRecharge or totalRecharge <= 0 then
        return
    end

    local idxList = {}
    local receiveList = cycleRechargeData.receiveList or {}

    for k,v in ipairs(cycleRechargeCfg) do
        if totalRecharge >= v.moneyCond and not receiveList[k] then
            idxList[k] = 1
        end
    end

    if not next(idxList) then
        return
    end

    return idxList
end

-- 可领取的奖励
local function getAwardList(human)
    local idxList = getAwardIdx(human)
    if not idxList then
        return
    end

    local len  = 0
    local awardList, receiveList = {}, {}

    for idx in pairs(idxList) do
        local singleCfg = cycleRechargeCfg[idx]
        for _,item in ipairs(singleCfg.awardList) do
            len = len + 1
            awardList[len] = item
            receiveList[idx] = 1
        end
    end

    return awardList, receiveList
end

-- 如果还有奖励未领取，通过邮件发送
local function sendAwardByEmail(human)
    local awardList, receiveList = getAwardList(human)

    if awardList and #awardList > 0 then
        updateActReceiveList(human, receiveList)

        local mailCfg = MailExcel.mail[MAILID]
        MailManager.add(MailManager.SYSTEM, human.db._id, mailCfg.title, mailCfg.content, awardList, mailCfg.senderName)
    end
end

-- 检查红点
local function redDotCheck(human, noCheckRed)
    -- YunYingLogic.updateIcon(YYInfo[ACTID], human, noCheckRed)
    YunYingLogic.sendGroupUpdate(YYInfo[ACTID], human, ACTID)
end




-- 跨天
function updateDaily(human)
    local cycleRechargeData = getActData(human)
    if not cycleRechargeData then
        local firstOpenTime = calcRoleFirstOpenTime()
        if not firstOpenTime then
            return
        end

        initActData(human)

        updateActStartTime(human, firstOpenTime)

        -- redDotCheck(human, true)

        if isRecharge(human) then
            -- 推送数据，更新界面
            Query(human)
        end
    else
        local now = os.time()
        if now >= (cycleRechargeData.startTime + DURATION_DAYS * DAY_SECS) then
            --检查是否有未领取的奖励
            sendAwardByEmail(human)

            -- 重置数据
            initActData(human)

            -- 更新新一轮开启时间
            local dayStartTime = Util.getDayStartTime(now)
            updateActStartTime(human, dayStartTime)


            if isRecharge(human) then
                -- 推送数据，更新界面
                Query(human)

                -- 红点更新
                redDotCheck(human, true)
            end
        end

    end
end

function isOpen(human)
    local bl = isRecharge(human)
    local cycleRechargeData = getActData(human)
    if not cycleRechargeData or not bl then
        return false
    end

    return true
end

function isRed(human, YYInfo, funcConfig)
    if getAwardIdx(human) then
        return true
    end

    return false
end

--充值
function onCharge(human, price, funcID, buyID)
    local cycleRechargeData = getActData(human)
    if not cycleRechargeData then
        return
    end

    updateActTotalRecharge(human, price)

    redDotCheck(human)
end



function Query(human)
    local bl = isRecharge(human)
    local cycleRechargeData = getActData(human)
    if not cycleRechargeData  or not bl then
        return
    end

    local startTag = 1
    local len = 0
    local msgMaxLen = 5
    local cfgCnt = #cycleRechargeCfg

    local msgRet = Msg.gc.GC_CYCLERECHARGE_QUERY
    msgRet.startTime = cycleRechargeData.startTime
    msgRet.endTime = cycleRechargeData.startTime + DURATION_DAYS * DAY_SECS
    msgRet.totalRecharge = cycleRechargeData.totalRecharge or 0

    local msgAwardList = msgRet.awardList
    local receiveList = cycleRechargeData.receiveList or {}

    for k, v in ipairs(cycleRechargeCfg) do
        len = len + 1
        msgAwardList[0] = len
        msgAwardList[len].idx = k
        msgAwardList[len].moneyCond = v.moneyCond


        msgAwardList[len].state = 0
        if receiveList[k] then
            msgAwardList[len].state = 2
        else
            if cycleRechargeData.totalRecharge and cycleRechargeData.totalRecharge >= v.moneyCond then
                msgAwardList[len].state = 1
            end
        end

        for i, itemInfo in ipairs(v.awardList) do
            msgAwardList[len].itemList[0] = i
            Grid.makeItem( msgAwardList[len].itemList[i], itemInfo[1], itemInfo[2])
        end

        if len >= msgMaxLen then
            msgRet.startTag = startTag
            msgRet.endTag = 0
            if cfgCnt - len <= 0 then
                msgRet.endTag = 1
                return Msg.send(msgRet, human.fd)
            end

            Msg.send(msgRet, human.fd)

            len = 0
            startTag = 0
            cfgCnt = cfgCnt - msgMaxLen
        end
    end

    msgRet.startTag = startTag
    msgRet.endTag = 1
    Msg.send(msgRet, human.fd)
end


function GetAward(human)
    local cycleRechargeData = getActData(human)
    if not cycleRechargeData then
        return Broadcast.sendErr(human, Lang.COMMOM_NOT_ENABLED)
    end

    if not cycleRechargeData.totalRecharge or cycleRechargeData.totalRecharge <= 0 then
        return Broadcast.sendErr(human, Lang.COMMON_RECHARGE_NOT_ENOUGH)
    end

    local awardList, receiveList = getAwardList(human)
    if not awardList or not next(awardList) then
        return Broadcast.sendErr(human, Lang.SHARE_GROUP_GET_ERR_CNT)
    end

    updateActReceiveList(human, receiveList)

    BagLogic.addItemList(human, awardList, LOGTAG)

    Query(human)

    redDotCheck(human, true)
end