--------------------------------
-- 文件名       ：  WeekendLoopActManger.lua
-- 文件说明     ：  周末冲刺-活动模板管理
-- 创建时间     :   2024/11/25
-- 创建人       :   FC
--------------------------------

local Util = require("common.Util")
local Lang = require("common.Lang")
local Broadcast = require("broadcast.Broadcast")
local MailExcel = require("excel.mail")
local Msg = require("core.Msg")
local ObjHuman = require("core.ObjHuman")
local MailManager = require("mail.MailManager")
local BagLogic = require("bag.BagLogic")
local Grid = require("bag.Grid")
local PanelDefine = require("broadcast.PanelDefine")
local CommonDB = require("common.CommonDB")
local BuyLogic = require("topup.BuyLogic")
local GuideLogic = require("guide.GuideLogic")
local Log = require("common.Log")
local WeekLoopActDef = require("WeekendLoopActivity.WeekendLoopActDefine")
local WeekLoopActCof = require("excel.WeekLoopAct")
local WeekLoopActHeroStar = require("WeekendLoopActivity.WeekendLoopActHeroStar")
local YunYingLogic = require("yunying.YunYingLogic")
local WeekLoopActGuYu = require("WeekendLoopActivity.WeekendLoopActUseGuYu")
local weekLoopActCard = require("WeekendLoopActivity.WeekendLoopActCard")
local weekLoopActRank = require("WeekendLoopActivity.WeekendLoopActRank")

-- 活动信息
tWeekActInfo = nil
-- {
--     nStartTime = nil,       -- 开始时间
--     nEendTime = nil,        -- 结束时间
--     isRun = nil,            -- 是否在活动中
--     nCardBatch = nil,       -- 抽卡批次
-- }

-- 加载的模块
tWeekActModuel = {}

----------------------------------------- 内部处理开始 -------------------------------------
-- 下发数据
local function WeekLoopACT_SendData(tMsgData, fd)
    Msg.send(tMsgData, fd)
end

-- 下发活动数据
function WeekLoopACT_SendActInfo(human)
    if not human or not tWeekActInfo then
        return
    end

    print("[WeekLoopACT_SendActInfo] 下发活动数据 开始 ")

    local tMsgData = Msg.gc.GC_WEEKLOOP_ACT_ALLINFO
    tMsgData.nStartTime = tWeekActInfo.nStartTime
    tMsgData.nEendTime = tWeekActInfo.nEendTime

    tMsgData.tActID[0] = #WeekLoopActCof.WeekLoopAct

    local nIndex = 1
    for id, v in pairs(WeekLoopActCof.WeekLoopAct) do
        local tActData = tMsgData.tActID[nIndex]
        nIndex = nIndex + 1
        tActData.ID = id
        tActData.name = v.name
        tActData.nSortID = v.sortID
        tActData.nIcon = v.icon
        tActData.nPanelID = v.panelID
        local bRed = false
        if tWeekActModuel[id] and tWeekActModuel[id].isRed then
            bRed = tWeekActModuel[id].isRed(human)
        end
        
        -- 特殊处理的命名
        if WeekLoopActDef.WEEKACT_CARD_PANELID == v.panelID and tWeekActModuel[id] and tWeekActModuel[id].GetName then
            tActData.name = tWeekActModuel[id].GetName(human)
        end
        
        print("[WeekLoopACT_SendActInfo] name = "..tActData.name)
        tActData.nRed = bRed and 1 or 0
    end

    YunYingLogic.sendBanner(human)
    WeekLoopACT_SendData(tMsgData, human.fd)

    print("[WeekLoopACT_SendActInfo] 下发活动数据 结束 ")
end

-- 获取记录在人物身上的结束时间
local function WeekLoopACT_GetHumanEndTime(human)
    if not human then
        return -1
    end

    if not human.db.nWeekLoopEndTime then
        return -1
    end

    return human.db.nWeekLoopEndTime
end

-- 设置记录在人物身上的结束时间
local function WeekLoopACT_SetHumanEndTime(human, nTime)
    if not human or 0 >= nTime then
        return
    end

    human.db.nWeekLoopEndTime = nTime
end

-- 获取记录在人物身上的奖励处理标识
local function WeekLoopACT_GetHumanEndMail(human)
    if not human then
        return true
    end

    -- 没有 则认为未参加上一次活动
    if not human.db.nWeekLoopEndMail then
        print("[WeekLoopACT_GetHumanEndMail] 没有参加活动")
        return true
    end

    return human.db.nWeekLoopEndMail
end

-- 设置记录在人物身上的奖励处理标识
local function WeekLoopACT_SetHumanEndMail(human, nValue)
    if not human or not nValue then
        return
    end

    human.db.nWeekLoopEndMail = nValue
end

-- 各个子活动重置活动数据
local function WeekLoopACT_ResetData(human)
    if not human then
        return
    end

    -- 这里实际上应该 遍历modulefunc
    WeekLoopActHeroStar.WeekActHeroStar_ResetData(human)
    WeekLoopActGuYu.WeekActGuYu_ResetData(human)
    weekLoopActCard.WeekActCard_ResetData(human)
end

-- 各个子活动处理结束数据
local function WeekLoopACT_HandleEndData(human)
    if not human then
        return
    end

    WeekLoopActHeroStar.WeekActHeroStar_End(human)
end

-- 所有活动初始化数据开始
local function WeekLoopACT_BeginAllAct(human)
    if not human or not tWeekActInfo then
        return
    end

    local nEndTime = tWeekActInfo.nEendTime
    
    print("[WeekLoopACT_BeginAllAct] 所有活动初始化数据开始 ")

    -- 设置时间
    WeekLoopACT_SetHumanEndTime(human, nEndTime)
    -- 设置标记
    WeekLoopACT_SetHumanEndMail(human, false)

    -- 各个子活动重置数据
    WeekLoopACT_ResetData(human)

    -- 最后下发活动数据
    WeekLoopACT_SendActInfo(human)

    print("[WeekLoopACT_BeginAllAct] 所有活动初始化数据结束 ")
end

-- 结束所有活动
local function WeekLoopACT_EndAllAct(human)
    -- 各个子活动处理数据
    WeekLoopACT_HandleEndData(human)

    WeekLoopACT_SetHumanEndMail(human, true)
end

-- 活动开始
local function WeekLoopACT_Begin()
    if not tWeekActInfo then
        return
    end

    -- 遍历在线玩家
    for uuid, human in pairs(ObjHuman.onlineUuid) do
        WeekLoopACT_BeginAllAct(human)
    end

    -- 清理排行榜数据
    weekLoopActRank.WeekActRank_ResetData()
end

-- 活动结束
local function WeekLoopACT_End()
    -- 遍历在线玩家
    for uuid, human in pairs(ObjHuman.onlineUuid) do
        WeekLoopACT_EndAllAct(human)
    end

    -- 排行榜直接处理
    weekLoopActRank.WeekActRank_End()
end

-- 获取抽卡批次
function WeekLoopACT_GetCardBatch()
    local nNowCardBatch = CommonDB.getWeekCardBatch()
    -- 第一次初始化，设置为2，解决玩家批次不正确的问题
    if 0 == nNowCardBatch then
        nNowCardBatch = 2
        CommonDB.setWeekCardBatch(2)
    end

    print("[WeekLoopACT_GetCardBatch] nNowCardBatch = "..nNowCardBatch)
    return nNowCardBatch
end

-- 设置新的批次
local function WeekLoopACT_SetCardBatch()
    local nNowCardBatch = CommonDB.getWeekCardBatch()
    if nil == nNowCardBatch then
        print("[WeekLoopACT_SetCardBatch] 获取不到批次")
        CommonDB.setWeekCardBatch(1)
        Log.write(Log.LOGID_OSS_WEEKLOOP_ACT, "[WeekLoopACT_SetCardBatch] 获取不到之前的批次 设置批次为1 设置新批次结束")
        return
    end

    local nLen = (nNowCardBatch + 1) % WeekLoopActDef.WEEKACT_CARD_TYPE_LEN
    nNowCardBatch = (0 == nLen) and WeekLoopActDef.WEEKACT_CARD_TYPE_LEN or nLen
    CommonDB.setWeekCardBatch(nNowCardBatch)
    Log.write(Log.LOGID_OSS_WEEKLOOP_ACT, "[WeekLoopACT_SetCardBatch] 设置新批次结束 nNowCardBatch = "..nNowCardBatch)
end

----------------------------------------- 外部调用开始 -------------------------------------
function onZeroAll(funcID)
    local nNowTime = os.time()
    local tDate = os.date("*t",nNowTime)
    
    local nOpenServerDay = CommonDB.getServerOpenDay()
    if nOpenServerDay <= 7 then
        return
    end

    if WeekLoopActDef.WEEKACT_TIME ~= tDate.hour then
        return
    end

    print("[WeekLoopACT_onZeroAll] 进入定时处理")

    if WeekLoopActDef.WEEKACT_OPENDAY == tDate.wday then
        print("[WeekLoopACT_onZeroAll] 周末活动开始打印")

        tWeekActInfo = {}
        tWeekActInfo.isRun = true
        tWeekActInfo.nStartTime = nNowTime

        -- 计算过期时间，转成0时0分
        local nNextTime = nNowTime + 4 * 86400
        local tEndDate = os.date("*t",nNextTime)
        tEndDate.hour = 0
        tEndDate.min = 0
        tEndDate.sec = 0

        local nEndTime = os.time(tEndDate)
        tWeekActInfo.nEendTime = nEndTime
        tWeekActInfo.nCardBatch = WeekLoopACT_GetCardBatch()

        -- 活动开始
        WeekLoopACT_Begin()

        print("[WeekLoopACT_onZeroAll] 时间打印 nStartTime = ".. tWeekActInfo.nStartTime.." nEendTime = "..tWeekActInfo.nEendTime)
    elseif WeekLoopActDef.WEEKACT_ENDDAY == tDate.wday then
        print("[WeekLoopACT_onZeroAll] 周末活动结束打印")
 
        -- 活动结束
        WeekLoopACT_End()

        -- 设置新的批次
        WeekLoopACT_SetCardBatch()

        tWeekActInfo = nil
    end
end

-- 起服初始化
function WeekLoopACT_Init()
    local nNowTime = os.time()
    local tDate = os.date("*t",nNowTime)

    local nOpenServerDay = CommonDB.getServerOpenDay()
    if nOpenServerDay < 7 then
        return
    end

    print("[WeekLoopACT_Init] 起服初始化 wday = "..tDate.wday.." m = "..tDate.month.." d = "..tDate.day.." h = "..tDate.hour)

    -- 等于星期六 或者 小于星期三
    if WeekLoopActDef.WEEKACT_OPENDAY == tDate.wday or  WeekLoopActDef.WEEKACT_ENDDAY > tDate.wday then
        if not tWeekActInfo then
            tWeekActInfo = {}
            tWeekActInfo.isRun = true
            
            local nDiffDay = WeekLoopActDef.WEEKACT_OPENDAY == tDate.wday and 0 or tDate.wday

            local nTime = nNowTime - nDiffDay * 86400
            local tCalDate = os.date("*t",nTime)
            tCalDate.hour = 0
            tCalDate.min = 0
            tCalDate.sec = 0
            tWeekActInfo.nStartTime = os.time(tCalDate)

            local nEndTime =  tWeekActInfo.nStartTime + 4 * 86400
            tCalDate = os.date("*t",nEndTime)
            tCalDate.hour = 0
            tCalDate.min = 0
            tCalDate.sec = 0

            tWeekActInfo.nEendTime = os.time(tCalDate)
            tWeekActInfo.nCardBatch = WeekLoopACT_GetCardBatch()

            print("[WeekLoopACT_Init] 时间打印 nStartTime = ".. tWeekActInfo.nStartTime.." nEendTime = "..tWeekActInfo.nEendTime)
        end
    end

    for nID, v in pairs(WeekLoopActCof.WeekLoopAct) do
        local moduleFn = load("return require(\"" .. v.moduleFn .. "\")")()
        if moduleFn then
            tWeekActModuel[nID] = moduleFn
            if moduleFn.Init then
                local bRet = moduleFn.Init()
                if false == bRet then
                    print("[WeekLoopACT_Init] 初始化模块数据失败 nID ".. nID)
                end
            end
            print("[WeekLoopACT_Init] 加载模块成功 name = "..v.name)
        else
            print("[WeekLoopACT_Init] 加载模块失败 nID ".. nID)
        end

    end
end

-- 是否还在活动期间
function WeekLoopACT_IsRun()
    if not tWeekActInfo then
        return false
    end

    return tWeekActInfo.isRun
end

-- 玩家登录
function onLogin(human, funcID)
    if not human then
        return
    end

    local nOpenServerDay = CommonDB.getServerOpenDay()
    if nOpenServerDay < 7 then
        print("[onLogin] 玩家登录，当前服务器开放时间不足，直接返回 nOpenServerDay = "..nOpenServerDay)
        return
    end

    local nLastEndTime = WeekLoopACT_GetHumanEndTime(human)
    local nState = WeekLoopACT_GetHumanEndMail(human)

    local nSendMail = nState and 1 or 0
    print("[onLogin] 玩家登录 nSendMail = "..nSendMail)

    -- 未开始
    if false == WeekLoopACT_IsRun() then
        if true == nState or -1 >= nLastEndTime then
            return
        end

        WeekLoopACT_EndAllAct(human)
        
        return
    end

    -- 当前活动开启，记录的结束时间比当前开始的时间都小说明是新活动
    if nLastEndTime < tWeekActInfo.nStartTime then
        if false == nState then
            -- 处理上一次的奖励数据
            WeekLoopACT_HandleEndData(human)
        end

        WeekLoopACT_BeginAllAct(human)
        
        return
    end

    -- 下发活动基础数据
    if true == WeekLoopACT_IsRun() then
        WeekLoopACT_SendActInfo(human)
        weekLoopActCard.onLogin(human)
        WeekLoopActHeroStar.onLogin(human)
    end
end

-- 英雄星级改变回调
function onHeroStarChange(human, funcID, parameter, parameter2)
    if not human or "table" ~= type(parameter) then
        return
    end

    if false == WeekLoopACT_IsRun() then
        return
    end

    WeekLoopActHeroStar.WeekActHeroStar_HeroStarUp(human, parameter[1], parameter[2])
end

-- 是否开启
function isOpen(human, YYInfo, funcConfig)
    local bRet = WeekLoopACT_IsRun()
    local nRet = bRet and 1 or 0
    print("WeekLoopACT_isOpen 结束 nRet = "..nRet)
    return bRet
end

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

function isRed(human, YYInfo, funcConfig)
    local bRet = false
    for id, v in pairs(WeekLoopActCof.WeekLoopAct) do
        if tWeekActModuel[id] and tWeekActModuel[id].isRed then
            bRet = tWeekActModuel[id].isRed(human)
            if true == bRet then
                break
            end
        end
    end

    return bRet
end

-- 消耗古玉回调
function onDecZuanshi(human, funcID, parameter, parameter2)
    if not human or "number" ~= type(parameter) then
        return
    end

    if false == WeekLoopACT_IsRun() then
        return
    end

    local nGuYu = math.abs(parameter)
    if 0 >= nGuYu then
        return
    end

    WeekLoopActGuYu.WeekActGuYu_UseGuYu(human, nGuYu)
end

-- 高级召唤回调
function onDrawCard(human, funcID, parameter, parameter2)
    if not human or "number" ~= type(parameter) then
        return
    end

    if false == WeekLoopACT_IsRun() then
        return
    end

    print("[onDrawCard] 高级召唤回调 parameter = "..parameter)
    weekLoopActCard.WeekActCard_UseCard(human, parameter, WeekLoopActDef.WEEKACT_CARD_TYPE_HIGH)
end

-- 天命召唤回调
function onTMDrawCard(human, funcID, parameter, parameter2)
    if not human or "number" ~= type(parameter) then
        return
    end

    if false == WeekLoopACT_IsRun() then
        return
    end

    print("[onDrawCard] 天命召唤回调 parameter = "..parameter)

    weekLoopActCard.WeekActCard_UseCard(human, parameter, WeekLoopActDef.WEEKACT_CARD_TYPE_TIANMING)
end

-- 寻星回调
function onFindStar(human, funcID, parameter, parameter2)
    if not human or "number" ~= type(parameter) then
        return
    end

    if false == WeekLoopACT_IsRun() then
        return
    end
    
    print("[onDrawCard] 寻星回调 parameter = "..parameter)

    weekLoopActCard.WeekActCard_UseCard(human, parameter, WeekLoopActDef.WEEKACT_CARD_TYPE_FINDSTAR)
end

-- GM 命令
function GMResetWeekAct(human)
    if WeekLoopACT_IsRun() then
        WeekLoopACT_EndAllAct(human)

        WeekLoopACT_SetCardBatch()
        WeekLoopACT_BeginAllAct(human)
    end
end

function onCharge(human, price, funcID, buyID)
    if not human then
        return
    end

    if false == WeekLoopACT_IsRun() then
        return
    end

    print("[onCharge] 玩家充值回调开始 name = "..human.db.name.." price = "..price)

    weekLoopActRank.onCharge(human, price, funcID, buyID)
end