local Lang = require("common.Lang")
local Msg = require("core.Msg")
local ObjHuman = require("core.ObjHuman")
local Broadcast = require("broadcast.Broadcast")
local JinbiExchangeExcel = require("excel.JinbiExchange")
local ItemDefine = require("bag.ItemDefine")
local Grid = require("bag.Grid")
local DailyTaskLogic = require("dailyTask.DailyTaskLogic")
local Util = require("common.Util")
local RoleSystemLogic = require("roleSystem.RoleSystemLogic")
local RoleSystemDefine = require("roleSystem.RoleSystemDefine")
local VipLogic = require("vip.VipLogic")
local YunYingLogic = require("yunying.YunYingLogic")
local TalismanLogic = require("talisman.TalismanLogic")
local TriggerDefine = require("trigger.TriggerDefine")
local TriggerLogic = require("trigger.TriggerLogic")
local MonthCardLogic = require("present.MonthCard")

MAINTYPE_FREE = 1
REFRESH_HOURS = {0, 9, 19}

function getExchangeCnt(human, mainType)
    if not human.db.jinbiExchange then
        return 0
    end
    return human.db.jinbiExchange[mainType] or 0
end

function addExchangeCnt(human, mainType)
    if not human.db.jinbiExchange then
        human.db.jinbiExchange = {}
    end
    human.db.jinbiExchange.ts = os.time()
    local oldcnt = human.db.jinbiExchange[mainType] or 0
    human.db.jinbiExchange[mainType] = oldcnt + 1
end

function getLeftCnt(human, mainType)
    local cf = JinbiExchangeExcel.define[mainType]
    if not cf then return 0 end

    local leftCnt = cf.cnt - getExchangeCnt(human, mainType)
    return math.max(leftCnt, 0)
end

local function checkNeedRefresh(ts)
    local nowTime = os.time()
    local dayStartTime = Util.getDayStartTime(ts)
    local leftTime = nil
    for _, hour in ipairs(REFRESH_HOURS) do
        local refreshTime = dayStartTime + hour * 3600
        if nowTime >= refreshTime and ts < refreshTime then
            return true 
        else
            local tleftTime = refreshTime - nowTime
            if tleftTime >= 0 and (leftTime == nil or tleftTime < leftTime) then
                leftTime = tleftTime
            end
        end

        local nextRefreshTime = refreshTime + 86400
        if nowTime >= nextRefreshTime and ts < nextRefreshTime then
            return true
        else
            local tleftTime = nextRefreshTime - nowTime
            if tleftTime >= 0 and (leftTime == nil or tleftTime < leftTime) then
                leftTime = tleftTime
            end
        end
    end
    return false, leftTime
end

function checkRefresh(human)
    local jinbiExchange = human.db.jinbiExchange
    if not jinbiExchange then return end

    local dirty = nil 
    for i = 1, #JinbiExchangeExcel.define do
        if jinbiExchange[i] then
            dirty = true
            break
        end
    end
    if not dirty then return end

    local bRefresh, leftTime = checkNeedRefresh(jinbiExchange.ts)
    if  bRefresh then
        human.db.jinbiExchange = nil
    end

    return leftTime
end

-- 获取金币数量
function getJinbiCnt(human, mainType)
    local jinbiExchangeConfig = JinbiExchangeExcel.jinbiExchange[human.db.lv]
    if not jinbiExchangeConfig then return end
    
    --local vipAdd = (VipLogic.getPowerArgs(human, VipLogic.VIP_POWER11) or 0) / 100
    local talismanAdd = (TalismanLogic.getTalismanAdd(human, TalismanLogic.OTHER_EFFECT_TBL.DJ) or 0) / 100
    local baseCnt = jinbiExchangeConfig[mainType] or 0
    local jinbiCnt = baseCnt + math.ceil(baseCnt * talismanAdd)
    return jinbiCnt
end


-- 金币兑换查询
function jinbiExchangeQuery(human)
    local leftTime = checkRefresh(human)
    local msgRet = Msg.gc.GC_JINBI_EXCHANGE_QUERY
    msgRet.bOpen = true == MonthCardLogic.IsBuyEverlastingCard(human) and 1 or 0
    -- 获得金币
    msgRet.jinbiCnt[0] = #JinbiExchangeExcel.define
    for i = 1, msgRet.jinbiCnt[0] do
        msgRet.jinbiCnt[i] = getJinbiCnt(human, i)
    end
    -- 消耗元宝
    msgRet.needItemCnt[0] = #JinbiExchangeExcel.define - 1
    for i = 1, msgRet.needItemCnt[0] do
        local cf = JinbiExchangeExcel.define[i+1]
        msgRet.needItemCnt[i] = cf.cost
    end
    -- 剩余次数
    msgRet.leftExchange[0] = #JinbiExchangeExcel.define
    for i = 1, msgRet.leftExchange[0] do
        msgRet.leftExchange[i] = getLeftCnt(human, i)
    end

    msgRet.leftTime = leftTime or 0
    --Msg.trace(msgRet)
    Msg.send(msgRet, human.fd)
end

-- 金币兑换
function jinbiExchangDo(human, mainType)
    local config = JinbiExchangeExcel.define[mainType]
    if not config then return end

    checkRefresh(human)
    if getLeftCnt(human, mainType) < 1 then
        return Broadcast.sendErr(human, Lang.JINBI_EXCHANGE_ERR_CNT)
    end
 
    local needZuanshi = config.cost
    if not ObjHuman.checkRMB(human, needZuanshi) then
        return
    end

    -- 加金币
    local jinbiCnt = getJinbiCnt(human, mainType)
    if not ObjHuman.canAddJinbi(human, jinbiCnt) then
        return
    end

    -- 扣消耗
    if needZuanshi > 0 then
        ObjHuman.decZuanshi(human, -needZuanshi, "jinbi_exchange")
    end 
    addExchangeCnt(human, mainType)
    ObjHuman.updateJinbi(human, jinbiCnt, "jinbi_exchange")
    
    -- 通知客户端
    local msgRet = Msg.gc.GC_JINBI_EXCHANGE_DO
    Grid.makeItem(msgRet.item, ItemDefine.ITEM_JINBI_ID, jinbiCnt)
    msgRet.vipLv = human.db.vipLv or 0
    Msg.send(msgRet, human.fd)

    jinbiExchangeQuery(human)
    
    RoleSystemLogic.onDot(human, RoleSystemDefine.ROLE_SYS_ID_103)
    YunYingLogic.onCallBack(human, "onExchangeJinbi",1)  
    TriggerLogic.PublishEvent(TriggerDefine.GOLD_POINTS_NUM, human.db._id, 1)
end

-- 一键点金
function jinbiExchangOneClick(human)
    if  false == MonthCardLogic.IsBuyEverlastingCard(human) then
        return
    end
    
    checkRefresh(human)
    local tConfig = JinbiExchangeExcel.define
    local nAddJinBiCnt, nAddCiShu = 0, 0
    for mainType, v in ipairs(tConfig) do
        local nLeftCnt = getLeftCnt(human, mainType)
        local needZuanshi = v.cost
        if nLeftCnt >= 1 then
            for i = 1, nLeftCnt, 1 do
                if true == ObjHuman.checkRMB(human, needZuanshi) then
                    -- 加金币
                    local jinbiCnt = getJinbiCnt(human, mainType)
                    if ObjHuman.canAddJinbi(human, jinbiCnt) then
                        -- 扣消耗
                        if needZuanshi > 0 then
                            ObjHuman.decZuanshi(human, -needZuanshi, "jinbi_exchange")
                        end
        
                        addExchangeCnt(human, mainType)
                        nAddJinBiCnt = nAddJinBiCnt + jinbiCnt
                        nAddCiShu = nAddCiShu + 1
                    end
                end
            end
        end
    end

    if nAddJinBiCnt > 0  then
        ObjHuman.updateJinbi(human, nAddJinBiCnt, "jinbi_exchange")
        local msgRet = Msg.gc.GC_JINBI_EXCHANGE_DO
        Grid.makeItem(msgRet.item, ItemDefine.ITEM_JINBI_ID, nAddJinBiCnt)
        msgRet.vipLv = human.db.vipLv or 0
        Msg.send(msgRet, human.fd)

        RoleSystemLogic.onDot(human, RoleSystemDefine.ROLE_SYS_ID_103)
        YunYingLogic.onCallBack(human, "onExchangeJinbi", nAddCiShu)  
        TriggerLogic.PublishEvent(TriggerDefine.GOLD_POINTS_NUM, human.db._id, nAddCiShu)

        jinbiExchangeQuery(human)
    end
end

function isDot(human)
    checkRefresh(human)
    return getLeftCnt(human, MAINTYPE_FREE) > 0
end

function onHour(hour)
    do return  end
    local isFind = nil 
    for _, thour in ipairs(REFRESH_HOURS) do
        if thour == hour then
            isFind = true
            break
        end
    end
    if not isFind then return end

 --   for _, human in pairs(ObjHuman.onlineUuid) do
 --       RoleSystemLogic.onDot(human, RoleSystemDefine.ROLE_SYS_ID_403)
 --   end
end