--------------------------------
-- 文件名       ：  Voucher/Proto.lua
-- 文件说明     ：  代金券 - 通用定义
-- 创建时间     :   2024/12/16
-- 创建人       :   FC
--------------------------------

local VoucherShopDefine = require("voucher.VoucherShopDefine")
local BuyExcel = require("excel.buy")
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 CommonDB = require("common.CommonDB")
local MailManager = require("mail.MailManager")
local Grid = require("bag.Grid")
local HeroGrid = require("hero.HeroGrid")
local HeroLogic = require("hero.HeroLogic")
local BagLogic = require("bag.BagLogic")
local Log = require("common.Log")
local BuyLogic = require("topup.BuyLogic")
local YunYingLogic = require("yunying.YunYingLogic")
local TopupLogic =require("topup.TopupLogic")
local TriggerDefine = require("trigger.TriggerDefine")
local TriggerLogic = require("trigger.TriggerLogic")
local VouchProConf = require("excel.voucherPro").probability
local CommonDefine = require("common.CommonDefine")

-- 商店配置
local tVoucherShopCof = nil

-- 膨胀配置
local tVoucherInflateCof = nil

-- 开放等级
local VOUCHERSHOP_OPENLV = 40
local VOUCHERSHOP_ACTID = 27

----------------------------------------- 内部处理开始 -------------------------------------
local function VoucherShop_GetConfig()
    return BuyExcel.VoucherShop
end

-- 写日志
local function VoucherShop_WriteLog(human, szFuncName, sztext)
    Log.write(Log.LOGID_OSS_VOUCHERSHOP, szFuncName..sztext.." _id = "..human.db._id.." name = "..human.db.name)
end

local function VoucherShop_GetPro()
    local tProConf = VoucherShopDefine.INFLATIONPROBABILITY
    if next(VouchProConf[1].startDate) and next(VouchProConf[1].endDate) then
        local tStartDate = VouchProConf[1].startDate
        local tEndDate = VouchProConf[1].endDate

        tStartDate.hour = 0
        tStartDate.min = 0
        tStartDate.sec = 0
        tEndDate.sec = 0

        local realStartTime = os.time(tStartDate)
        local realEndTime = os.time(tEndDate)

        
        local nNowTime = os.time()
        print("[VoucherShop_GetPro] realStartTime = "..realStartTime.." realEndTime = "..realEndTime.." nNowTime = "..nNowTime)
        if realStartTime <= nNowTime and realEndTime > nNowTime then
            tProConf = {
                [1] = {VouchProConf[1].ProOne, 1.2},
                [2] = {VouchProConf[1].ProOne + VouchProConf[1].ProTwo, 1.5},
                [3] = {VouchProConf[1].ProOne + VouchProConf[1].ProTwo + VouchProConf[1].ProThree, 3},
            }
        end
    end

    return tProConf
end


local function VoucherShop_InitShopConfig()
    local tAllConfig = VoucherShop_GetConfig()
    if not tAllConfig then
        return
    end

    tVoucherShopCof = {}
    for nID, v in pairs(tAllConfig) do
        if VoucherShopDefine.VOUCHERTYPE_SHOP == v.nType then
            tVoucherShopCof[v.buyID] = 
            {
                nID = nID,
                tData = v
            }
        end
    end
end

local function VoucherShop_InitInflateConfig()
    local tAllConfig = VoucherShop_GetConfig()
    if not tAllConfig then
        return
    end

    tVoucherInflateCof = {}
    for nID, v in pairs(tAllConfig) do
        if VoucherShopDefine.VOUCHERTYPE_INFLATION == v.nType then
            tVoucherInflateCof[v.buyID] = 
            {
                nID = nID,
                tData = v
            }
        end
    end
end

-- 获取商店配置
local function VoucherShop_GetShopConfig()
    if not tVoucherShopCof then
        VoucherShop_InitShopConfig()
    end

    return tVoucherShopCof
end

-- 获取膨胀配置
local function VoucherShop_GetInflateConfig()
    if not tVoucherInflateCof then
        VoucherShop_InitInflateConfig()
    end

    return tVoucherInflateCof
end


-- 重置购买状态信息
local function VoucherShop_RestStatus(human)
    if not human then
        return
    end

    human.db.tBuyVoucherInflate = {
        nStatus = VoucherShopDefine.VOUCHERSTATUS_NOGET,
        nTime = 0
    }
end

-- 获取购买状态信息
local function VoucherShop_GetStatus(human)
    if not human then
        return
    end

    if not human.db.tBuyVoucherInflate then
        VoucherShop_RestStatus(human)
    end

    return human.db.tBuyVoucherInflate
end

-- 设置购买状态
local function VoucherShop_SetStatus(human, nStatus, nTime)
    if not human then
        return
    end

    if not human.db.tBuyVoucherInflate then
        VoucherShop_RestStatus(human)
    end

    human.db.tBuyVoucherInflate.nStatus = nStatus
    human.db.tBuyVoucherInflate.nTime = nTime
end

local function VoucherShop_GetAddNum(tConfig)
    if not tConfig then
        return 0, 0
    end

    -- table.print_lua_table(tConfig)
    local nMultiple = 1
    local nNum = tConfig.tData.nGetVoucherNum
    if VoucherShopDefine.VOUCHERTYPE_INFLATION == tConfig.tData.nType then
        local nRandNum = math.random(1, 100)
        local tProConf = VoucherShop_GetPro()
        for nID, v in ipairs(tProConf) do
            -- if nRandNum <= nID then
            --     nMultiple = v
            --     break
            -- end
            if nRandNum <= v[1] then
                nMultiple = v[2]
                break
            end
        end
    end

    nNum = math.ceil(nMultiple * nNum)

    return nNum, nMultiple
end

----------------------------------------- 其他模块调用 -------------------------------------
-- 购买回调
function VoucherShop_OnBuyVoucher(human, nBuyID)
    if not human or not nBuyID then
        return
    end

    -- 记录一下日志
    local sztext = " nBuyID = "..nBuyID
    VoucherShop_WriteLog(human, "[VoucherShop_OnBuyVoucher]", "玩家购买代金券回调记录开始 "..sztext)

    local tShopCof = VoucherShop_GetShopConfig()
    local tInflateConfig = VoucherShop_GetInflateConfig()
    if not tShopCof or not tInflateConfig then
        print("[VoucherShop_OnBuyVoucher] 获取配置失败 name = "..human.db.name..sztext)
        VoucherShop_WriteLog(human, "[VoucherShop_OnBuyVoucher]", "玩家购买代金券回调获取不到配置 "..sztext)
        return
    end

    local nAddNum, nMultiple = VoucherShop_GetAddNum(tShopCof[nBuyID] or tInflateConfig[nBuyID])
    if 0 >= nAddNum or 0 >= nMultiple then
        sztext = sztext.." nAddNum = "..nAddNum.." nMultiple = "..nMultiple
        print("[VoucherShop_OnBuyVoucher] 获取增加的数量和倍率失败 name = "..human.db.name..sztext)
        VoucherShop_WriteLog(human, "[VoucherShop_OnBuyVoucher]", "获取增加的数量和倍率失败 nBuyID = "..sztext)
        return
    end

    -- 给物品
    BagLogic.addItem(human, VoucherShopDefine.VOUCHERITME_ID, nAddNum, "voucher_use")

    -- 弹窗
    BagLogic.sendItemGetList(human, {{VoucherShopDefine.VOUCHERITME_ID, nAddNum}}, "voucher_use")

    if nMultiple > 1 then
        local szInflateText = "恭喜【"..human.db.name.."】通过刮刮乐获得"..nAddNum.."代金券"
        CommonDB.setVoucherInflate(szInflateText, os.time())

        VoucherShop_SetStatus(human, VoucherShopDefine.VOUCHERSTATUS_GET, os.time())
        VoucherShop_QueryInflate(human)
    end

    VoucherShop_WriteLog(human, "[VoucherShop_OnBuyVoucher]", "玩家购买代金券回调记录结束 "..sztext)
    TriggerLogic.PublishEvent(TriggerDefine.VOUCHER_BUY_NUM, human.db._id, nAddNum)
    
end

-- 定时回调
function VoucherShop_OnZero()
     -- 遍历在线玩家
    for uuid, human in pairs(ObjHuman.onlineUuid) do
        VoucherShop_RestStatus(human)
    end
end

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

    local tStatus = VoucherShop_GetStatus(human)
    if not tStatus then
        return
    end

    if tStatus.nStatus == VoucherShopDefine.VOUCHERSTATUS_GET then
        local nOldTime = tStatus.nTime
        local nNowTime = os.time()
        local sameDay = Util.isSameDayByTimes(nNowTime, nOldTime)
        if true ~= sameDay then
            VoucherShop_RestStatus(human)
            VoucherShop_WriteLog(human, "[VoucherShop_OnBuyVoucher]", "玩家登录重置购买状态 nOldTime = "..nOldTime.." nNowTime = "..nNowTime)
        end 
    end
end


----------------------------------------- 客户端请求 -------------------------------------
-- 请求代金券商店信息
function VoucherShop_QueryShop(human)
    if not human then
        return
    end

    local tConfig = VoucherShop_GetShopConfig()
    if not tConfig then
        VoucherShop_WriteLog(human, "[VoucherShop_QueryShop]", "获取商店配置失败")
        print("[VoucherShop_QueryShop] 获取商店配置失败")
        return
    end

    local tMsgData = Msg.gc.GC_VOUCHER_QUERY_SHOP
    --tMsgData.tVoucherData[0] = #tConfig

    local nIndex = 1
    for nBuyID, v in pairs(tConfig) do
       local tData =  tMsgData.tVoucherData[nIndex]
       tData.nID = v.nID
       --tData.nGetVoucherNum = v.tData.nGetVoucherNum
       Grid.makeItem(tData.item, VoucherShopDefine.VOUCHERITME_ID, v.tData.nGetVoucherNum)

       print("[VoucherShop_QueryShop] nID = "..tData.nID.." nGetVoucherNum = "..v.tData.nGetVoucherNum)
       BuyLogic.fontBuyItem(human, tData.tBuyItem, nBuyID)
       nIndex = nIndex +1
    end

    print("[VoucherShop_QueryShop] nIndex = "..nIndex)
    tMsgData.tVoucherData[0] = nIndex - 1
    Msg.send(tMsgData, human.fd)
end

-- 请求代金券膨胀信息
function VoucherShop_QueryInflate(human)
    if not human then
        return
    end

    local tConfig = VoucherShop_GetInflateConfig()
    if not tConfig then
        VoucherShop_WriteLog(human, "[VoucherShop_QueryInflate]", "获取膨胀配置失败")
        print("[VoucherShop_QueryInflate] 获取膨胀配置失败")
        return
    end

    local tStatus = VoucherShop_GetStatus(human)
    if not tStatus then
        VoucherShop_WriteLog(human, "[VoucherShop_QueryInflate]", "获取状态信息失败")
        print("[VoucherShop_QueryInflate] 获取状态信息失败")
        return
    end

    local tMsgData = Msg.gc.GC_VOUCHER_QUERY_INFLATE
    tMsgData.nStatus = tStatus.nStatus
    --tMsgData.tVoucherData[0] = #tConfig

    local nIndex = 1
    for nBuyID, v in pairs(tConfig) do
       local tData =  tMsgData.tVoucherData[nIndex]
       tData.nID = v.nID
      
       Grid.makeItem(tData.item, VoucherShopDefine.VOUCHERITME_ID, v.tData.nGetVoucherNum)

       BuyLogic.fontBuyItem(human, tData.tBuyItem, nBuyID)
       nIndex = nIndex +1
    end
    tMsgData.tVoucherData[0] = nIndex - 1

    local szTextInfo = CommonDB.getVoucherInflate()
    tMsgData.tVoucherText[0] = 0
    if szTextInfo then
        local nLen = #szTextInfo
        tMsgData.tVoucherText[0] = nLen > 20 and 20 or nLen
        for i, v in pairs(szTextInfo) do
            if i > 20 then
                break
            end
            tMsgData.tVoucherText[i] = v.szText
            print("[VoucherShop_QueryInflate] szText = "..v.szText)
        end
    end

    local tProConf = VoucherShop_GetPro()
    table.print_lua_table(tProConf)
    tMsgData.tPro[0] = 3
    local nLastPro = 0
    for i, v in ipairs(tProConf) do
        tMsgData.tPro[i] = v[1] - nLastPro
        nLastPro = v[1]
    end

    Msg.send(tMsgData, human.fd)
end

-- 请求代金券购买商品
function VoucherShop_BuyItem(human, nBuyID, nBuyNum)
    if not human or 0 >= nBuyID or nBuyNum <= 0 or nBuyNum >= 200 then
        return Broadcast.sendErr(human, Lang.COMMON_ARGUMENT_ERROR)
    end

    local tBuyConfig = VoucherShop_GetShopConfig()
    local tInflateConfig = VoucherShop_GetInflateConfig()
    if not tBuyConfig or not tInflateConfig then
        return
    end

    if tBuyConfig[nBuyID] or tInflateConfig[nBuyID] then
        -- print("[VoucherShop_BuyItem] 玩家使用代金券购买代金券礼品，直接返回")
        VoucherShop_WriteLog(human, "[VoucherShop_BuyItem]", "玩家使用代金券购买代金券礼品，直接返回")
        return
    end
    
    local tTrueBuyConfig = BuyExcel.buy[nBuyID]
    if not tTrueBuyConfig then
        -- print("[VoucherShop_BuyItem] 不存在对应的商品信息 nBuyID = "..nBuyID)
        return Broadcast.sendErr(human, Lang.COMMON_ARGUMENT_ERROR)
    end

    local nDelVoucherNum = tTrueBuyConfig.Voucher * nBuyNum
    if 0 >= nDelVoucherNum then
        -- print("[VoucherShop_BuyItem] 该商品无法用代金券购买，配置的数量为空 nBuyID = "..nBuyID.." nDelVoucherNum = "..nDelVoucherNum)
        return Broadcast.sendErr(human, Lang.COMMON_COMFIG_ERROR)
    end

    local nNowNum = BagLogic.getItemCnt(human, VoucherShopDefine.VOUCHERITME_ID)
    if nNowNum < nDelVoucherNum then
        -- print("[VoucherShop_BuyItem] 对应购买代金券不足直接返回 nBuyID = "..nBuyID.." nDelVoucherNum = "..nDelVoucherNum.." nNowNum = "..nNowNum)
        return Broadcast.sendErr(human, Lang.VOUCHER_NOT_ENOUGH)
    end

    if tTrueBuyConfig.module and tTrueBuyConfig.module ~= "" then
        local tModule = load("return require(\"" .. tTrueBuyConfig.module .. "\")")()
        if tModule and tModule.GetRemainNum then
            local nTrueNum = tModule.GetRemainNum(human, nBuyID)

            if not nTrueNum or nTrueNum < nBuyNum then
                -- print("[VoucherShop_BuyItem] 获取不到对应的配置nBuyID = "..nBuyID.." nDelVoucherNum = "..nDelVoucherNum.." nNowNum = "..nNowNum.." nBuyNum = "..nBuyNum)
                return Broadcast.sendErr(human, Lang.ABS_GIFT_BUY_LIMIT)
            end
        end
    end

    -- 删物品
    BagLogic.delItem(human, VoucherShopDefine.VOUCHERITME_ID, nDelVoucherNum, "voucher_use")

    local reallyPrice = tTrueBuyConfig.CN
    if human.phpChanelID and table.find(CommonDefine.SEA_CHANNEL_ARR, human.phpChanelID) then
		reallyPrice = tTrueBuyConfig.US
	end

    -- 发道具
    local tBuyInfo = 
    {
        buyID = nBuyID,
        price = reallyPrice,
        buyNum = nBuyNum,
    }
    
    BuyLogic.buy(human, tBuyInfo)
    
    -- local voucherDenomination = tTrueBuyConfig.CN
    -- if voucherDenomination >= 100 then
    --     TopupLogic.sendFireworksMail(human, nDelVoucherNum)
    -- end
    YunYingLogic.sendIconUpdate(VOUCHERSHOP_ACTID, human)
    
    -- 写日志
    local szText = "玩家购买使用代金券购买了物品 nBuyID = "..nBuyID.." nBuyNum = "..nBuyNum.. " 消耗代金券数量 nDelVoucherNum = "..nDelVoucherNum
    VoucherShop_WriteLog(human, "[VoucherShop_BuyItem]", szText)
end


----------------------------------------- 活动模板调用 -------------------------------------
-- 是否开启
function isOpen(human, YYInfo, funcConfig)
    -- if human.version and human.version == VoucherShopDefine.VOUCHER_SP_PLATFORM then
    --     return true
    -- end


    -- if human.version and (human.version == VoucherShopDefine.VOUCHER_NO_OPEN_TAG) then
    --     return false
    -- end

    if human.version and table.find(VoucherShopDefine.VOUCHER_NO_OPEN_TAG_ARR, human.version) then
        return false
    end

    if human.db.phpChanelID and (human.db.phpChanelID == 13 or human.db.phpChanelID == "13") then
        return false
    end

    --print("[VoucherShop is open] 1111")
    if human.db.lv < VOUCHERSHOP_OPENLV then
       -- print("[VoucherShop is open] 22222")
        return false
    end

    if not human.db.nFirstBuy or human.db.nFirstBuy ~= 1 then
        --print("[VoucherShop is open] 33333")
        return false
    end

    --print("[VoucherShop is open] 444444")    
    return true
end

-- 活动剩余时间
function getLeftTime()
    return 9999999
end

-- 是否存在红点
function isRed(human)
    return false
end

function onCharge(human, price, funcID, buyID)
    if human.db.lv >= VOUCHERSHOP_OPENLV and isOpen(human) then
        YunYingLogic.sendIconUpdate(VOUCHERSHOP_ACTID, human)
    end
end

function onLevelUp(human, oldLv, newLv, funcID)
    if true == isOpen(human) then
        YunYingLogic.sendIconUpdate(VOUCHERSHOP_ACTID, human)
    end
end