local Msg = require("core.Msg")
local UnionDBLogic = require("union.UnionDBLogic")
local UnionExcel = require("excel.union")
local Grid = require("bag.Grid")
local BagLogic = require("bag.BagLogic")
local Util = require("common.Util")
local RoleAttr = require("role.RoleAttr")
local RoleSystemLogic = require("roleSystem.RoleSystemLogic")
local RoleSystemDefine = require("roleSystem.RoleSystemDefine")


DAY_UPDATE_TYPE = 1
WEEK_UPDATE_TYPE = 2

local function initUnionLiveDB(human)
    if human.db.unionLive ~= nil then
        return
    end

    human.db.unionLive = {}
    human.db.unionLive.lv = 0
    human.db.unionLive.liveness = 0
    human.db.unionLive.todayLiveness = 0
    human.db.unionLive.weekLiveness = 0
    human.db.unionLive.task = {}
    human.db.unionLive.reward = {}

    local liveConfig = UnionExcel.liveness

    local len = #liveConfig
    for i = 1,len do
        local v = liveConfig[i]
        human.db.unionLive.task[i] = {}
        human.db.unionLive.task[i].id = i
        human.db.unionLive.task[i].type = v.type
        human.db.unionLive.task[i].reach = 0
        human.db.unionLive.task[i].cnt = 0
        human.db.unionLive.task[i].status = 0
        human.db.unionLive.task[i].ts = os.time()
    end
end

function livenessQuery(human)
    -- 判断玩家是否有工会
    -- 判断玩家公会是否存在
    local union = UnionDBLogic.getUnion(human.db.unionUuid)
    if union == nil then
        return
    end

    -- 初始化数据
    initUnionLiveDB(human)

    local nowLv = human.db.unionLive.lv
    local nextLv = nowLv + 1
    local maxLv = #UnionExcel.liveLv

    local msgRet = Msg.gc.GC_UNION_LIVENESS_QUERY
    msgRet.lv = human.db.unionLive.lv
    msgRet.nowLiveness = human.db.unionLive.liveness
    msgRet.maxLiveness = UnionExcel.liveLv[nextLv] and UnionExcel.liveLv[nextLv].needLiveness or 0
    msgRet.todayLiveness = human.db.unionLive.todayLiveness
    msgRet.weekLiveness = human.db.unionLive.weekLiveness
    
    -- 等级奖励
    local liveLvConfig = nil
    local len = 0

    msgRet.reward.status = 0
    msgRet.reward.lv = nowLv

    for i = 1,nowLv do
        -- 有任务奖励未领
        if human.db.unionLive.reward[i] == nil then
            liveLvConfig = UnionExcel.liveLv[i]
            msgRet.reward.status = 1
            msgRet.reward.lv = i
            len = #liveLvConfig.reward
            break
        end
    end

    -- 没有奖励未领,且下一级存在
    if len == 0 and nextLv <= maxLv then
        liveLvConfig = UnionExcel.liveLv[nextLv]
        msgRet.reward.status = 0
        msgRet.reward.lv = nextLv
        len = #liveLvConfig.reward
    end


    for i = 1,len do
        local v = liveLvConfig.reward[i]
        Grid.makeItem(msgRet.reward.reward[i],v[1],v[2])
    end
    msgRet.reward.reward[0] = len
    
    -- 当前等级属性
    if nowLv == 0 then
        msgRet.attr[0] = 0
    else
        len = #UnionExcel.liveLv[nowLv].attr 
        for i = 1,len do
            local v = UnionExcel.liveLv[nowLv].attr[i]
            msgRet.attr[i].key = v[1]
            msgRet.attr[i].value = v[2]
        end
        msgRet.attr[0] = len
    end
    -- 下级等级属性
    if UnionExcel.liveLv[nextLv] == nil then
        msgRet.nextAttr[0] = 0
    else
        len = #UnionExcel.liveLv[nextLv].attr 
        for i = 1,len do
            local v = UnionExcel.liveLv[nextLv].attr[i]
            msgRet.nextAttr[i].key = v[1]
            msgRet.nextAttr[i].value = v[2]
        end
        msgRet.nextAttr[0] = len
    end

    -- 活跃度任务
    len = #human.db.unionLive.task
    for i = 1,len do
        local net = msgRet.unionLiveness[i]
        local v = human.db.unionLive.task[i]
        local config = UnionExcel.liveness[v.id]

        net.taskID = v.id
        net.type = v.type
        net.nowReach = v.reach
        net.need = config.need
        net.nowCnt = v.cnt
        net.maxCnt = config.maxCnt
        net.liveness = config.liveness
        net.pageID = config.pageID
        net.status = v.cnt < config.maxCnt and 0 or 1
        net.name = config.name
        net.desc = config.desc
    end
    msgRet.unionLiveness[0] = len

    Msg.send(msgRet,human.fd)
end

function livenessRewardQuery(human)
    -- 判断玩家是否有工会
    -- 判断玩家公会是否存在
    local union = UnionDBLogic.getUnion(human.db.unionUuid)
    if union == nil then
        return
    end

    local config = UnionExcel.liveLv
    local msgRet = Msg.gc.GC_UNION_LIVENESS_REWARD_QUERY

    local len = #config 
    for i = 1,len do
        local lenReward = #config[i].reward
        for j = 1,lenReward do
            local net = msgRet.reward[i].reward[j]
            local v = config[i].reward[j]
            Grid.makeItem(net,v[1],v[2])
        end
        msgRet.reward[i].reward[0] = lenReward
        msgRet.reward[i].status = 0
        msgRet.reward[i].lv = i
    end
    msgRet.reward[0] = len

    Msg.send(msgRet,human.fd)
end

function touchLiveness(human,id,cnt)
    -- 判断玩家是否有工会
    -- 判断玩家公会是否存在
    local union = UnionDBLogic.getUnion(human.db.unionUuid)
    if union == nil then
        return
    end
    
    -- 初始化数据
    initUnionLiveDB(human)

    local config = UnionExcel.liveness[id]

    -- 验证是否有此任务
    if human.db.unionLive.task[id] == nil then
        return
    end

    -- 验证此任务是否已经完成
    if human.db.unionLive.task[id].cnt >= config.maxCnt then
        return
    end

    -- 增加次数
    human.db.unionLive.task[id].reach = human.db.unionLive.task[id].reach + cnt
    while true do
        if human.db.unionLive.task[id].cnt >= config.maxCnt then
            break
        end
        if human.db.unionLive.task[id].reach < config.need then
            break
        end
        human.db.unionLive.task[id].reach = human.db.unionLive.task[id].reach - config.need 
        human.db.unionLive.task[id].cnt = human.db.unionLive.task[id].cnt + 1
        -- 增加经验
        touchLv(human,config.liveness)
    end
end

function touchLv(human,liveness)
    -- 判断玩家是否有工会
    -- 判断玩家公会是否存在
    local union = UnionDBLogic.getUnion(human.db.unionUuid)
    if union == nil then
        return
    end
    
    -- 初始化数据
    initUnionLiveDB(human)

    -- 判断是否达到最大等级
    local maxLv = #UnionExcel.liveLv
    local nextLv = human.db.unionLive.lv + 1
    if nextLv > maxLv then
        return
    end

    local config = UnionExcel.liveLv[nextLv]
    if config == nil then
        return
    end

    human.db.unionLive.liveness = human.db.unionLive.liveness + liveness
    human.db.unionLive.todayLiveness = human.db.unionLive.todayLiveness + liveness
    human.db.unionLive.weekLiveness = human.db.unionLive.weekLiveness + liveness
    local roundCnt = 0
    while true do
        if config ~= nil and human.db.unionLive.liveness < config.needLiveness then
            break
        end

        -- 死循环保护
        roundCnt = roundCnt + 1
        if roundCnt > maxLv then
            break
        end

        human.db.unionLive.liveness = human.db.unionLive.liveness - config.needLiveness
        human.db.unionLive.lv = human.db.unionLive.lv + 1
        
        RoleAttr.cleanHeroAttrCache(human)
        -- 达到最大等级后，清除活跃度，并跳出
        if human.db.unionLive.lv >= maxLv then
            human.db.unionLive.liveness = 0
            break
        end

        nextLv = human.db.unionLive.lv + 1
        config = UnionExcel.liveLv[nextLv]
    end
end

function getReward(human,lv)
    -- 判断玩家是否有工会
    -- 判断玩家公会是否存在
    local union = UnionDBLogic.getUnion(human.db.unionUuid)
    if union == nil then
        return
    end
    
    -- 初始化数据
    initUnionLiveDB(human)

    -- 校验等级是否达成
    if lv == nil or lv <= 0 then
        return
    end

    if lv > human.db.unionLive.lv then
        return
    end

    -- 校验等级奖励是否已领
    if human.db.unionLive.reward[lv] ~= nil then
        return
    end

    -- 改dB
    human.db.unionLive.reward[lv] = 1

    -- 发奖励
    BagLogic.addItemList(human,  UnionExcel.liveLv[lv].reward, "unionLive_reward")
    RoleSystemLogic.onDot(human, RoleSystemDefine.ROLE_SYS_ID_1004)
    RoleSystemLogic.onDot(human, RoleSystemDefine.ROLE_SYS_ID_1001)
    livenessQuery(human)
end

-- 每日更新
function updateDaily(human)
    -- 判断玩家是否有工会
    -- 判断玩家公会是否存在
    local union = UnionDBLogic.getUnion(human.db.unionUuid)
    if union == nil then
        return
    end
    
    -- 初始化数据
    initUnionLiveDB(human)
    human.db.unionLive.todayLiveness = 0

    local now = os.time()

    local len = #human.db.unionLive.task
    for i = 1,len do
        local v = human.db.unionLive.task[i]
        local clean = nil
        if v.type == DAY_UPDATE_TYPE then
            clean = Util.isSameDayByTimes(now,v.ts)
        elseif v.type == WEEK_UPDATE_TYPE then
            clean = Util.isSameWeek(now,v.ts)
        end

        if clean ~= true then
            v.reach = 0
            v.cnt = 0
        end
    end
end

function doCalcHero(human,attrs)
    -- 判断玩家是否有工会
    -- 判断玩家公会是否存在
    if not human then return end
    local union = UnionDBLogic.getUnion(human.db.unionUuid)
    if union == nil then
        return
    end
    
    -- 初始化数据
    initUnionLiveDB(human)

    if human.db.unionLive.lv <= 0 then
        return
    end

    local config = UnionExcel.liveLv[human.db.unionLive.lv]
    if config == nil then
        return
    end

    for k, v in ipairs(config.attr) do
        RoleAttr.updateValue(v[1], v[2], attrs)
    end
end

function isDot(human)
    initUnionLiveDB(human)
    
    local nowLv = human.db.unionLive.lv
    for i = 1,nowLv do
        -- 有任务奖励未领
        if human.db.unionLive.reward[i] == nil then
            return true
        end
    end

    return
end