----------------------------
--      工会模块DB

-- getUnion             根据公会uuid获取公会union
-- getUnionByName       根据公会名字获取公会union
-- getUnionByNameRegex  根据名字模糊查询公会列表

-- addUnion             创建公会
-- delUnion             删除公会
-- updateUnionData      刷新公会信息
-- calcUnionZhandouli   计算公会战力
-- addUnionMember       添加公会成员
-- delUnionMember       删除公会成员
---------------------------

local UnionExcel = require("excel.union")
local Config = require("Config")
local LuaMongo = _G.lua_mongo
local DB = require("common.DB")
local Util = require("common.Util")
local CommonDB = require("common.CommonDB")
local UnionDefine = require("union.UnionDefine")
local RoleDBLogic = require("role.RoleDBLogic")
local RoleLogic = require("role.RoleLogic")
local BRoleLogic = require("billboard.BRoleLogic")
local BillboardDefine = require("billboard.BillboardDefine") 

QueryByName = {name = nil}
QueryByUnionUuid = {_id = nil}
QueryByHeadFrame = {headFrame = {["$exists"] = 1}}

FieldBaseUnion = {name = 1, lv = 1, curCnt = 1, id = 1, bannerID = 1, notice = 1, exp = 1, headFrame = 1, apply = 1,presidentUuid = 1,needLv = 1}
FieldLog = {logs = 1}

UNION_DEFAULT_QUERY_LEN = 10         -- 推荐公会个数
UNION_LOG_MAXCNT = 50                -- 公会操作日志最大条数

-- 查询数据库中是否已注册这个工会名
local tempData = {}
function isNameExistInDB(name)
    QueryByName.name = name
    tempData.name = nil
    LuaMongo.find(DB.db_union, QueryByName)
    return LuaMongo.next(tempData) and tempData
end

-- 根据uuid获取公会数据
function getUnion(unionUuid, fields)
    if unionUuid == nil or unionUuid == "" then 
        return 
    end

    local union = {}
    QueryByUnionUuid._id = unionUuid
    LuaMongo.find(DB.db_union, QueryByUnionUuid, fields)
    return LuaMongo.next(union) and union
end

-- 根据公会名字获取公会信息
function getUnionByName(name)
    local union = {}
    QueryByName.name = name
    LuaMongo.find(DB.db_union, QueryByName)
    return LuaMongo.next(union) and union
end

-- 模糊查询 获取公会列表
function getUnionByNameRegex(name)
    QueryByName.name = {["$regex"] = name}
    LuaMongo.find(DB.db_union, QueryByName, nil, 10)
    local unionList = {}
    while true do
        local union = {}
        if not LuaMongo.next(union) then
            break
        end
        unionList[#unionList + 1] = union
    end
    return unionList
end

-- 刷新公会信息
function updateUnionData(union)
    if not union or not union._id then return end

    QueryByUnionUuid._id = union._id
    LuaMongo.update(DB.db_union, QueryByUnionUuid, union)   
end

-- 更新某些字段
local DBUpdateField = {} -- 更新域
function upsetUnionData(unionUuid, key, value)
    if unionUuid == nil then return end
    if key == nil then return end
 
    if value then
        DBUpdateField["$set"] = {[key]=value}
        DBUpdateField["$unset"] = nil
    else       
        DBUpdateField["$set"] = nil
        DBUpdateField["$unset"] = {[key]=1}
    end 
    QueryByUnionUuid._id = unionUuid
    LuaMongo.update(DB.db_union, QueryByUnionUuid, DBUpdateField)  
end

-- 生成一个11位的全局不重复的数字组成的id
-- 规则 前6位服务器index 后五位自增id
local function getIdentity()
    local firstStr = Config.SVR_INDEX
    local id = CommonDB.getUnionIdentityMax() + 1
    CommonDB.setUnionIdentityMax(id)
    return tostring(firstStr .. "" .. id)
end

-- 创建公会
function addUnion(human, name, bannerID, notice, needLv, needAgree)
    local unionId = getIdentity()
    if not unionId then assert(nil) end

    local uuid = human.db._id
    local union = {}
    union.id = unionId                          -- 公会编号，全数字字符串
    union.createTime = os.time()                -- 创建时间
    union.name = name                           -- 公会名字
    union.nameTime = nil                        -- 公会改名时间
    union.lv = 1                                -- 等级
    union.exp = 0                               -- 经验
    union.presidentUuid = uuid                  -- 会长
    union.zhandouli = 0                         -- 公会战力
    union.member = {}                           -- 成员 [uuid] = {post = nil}
    union.curCnt = 0                            -- 公会人数    
    union.kickCntToday = nil                    -- 本日踢除人数（每日踢人是有上限的，防止恶意踢人？）
    union.kickTime = nil                        -- 最近一次踢人时间
    union.notice = notice                       -- 公告
    union.noticeTime = nil                      -- 公告修改时间
    union.bannerID = bannerID                   -- 旗子
    union.needLv = needLv						-- 入会等级要求
    union.needAgree = needAgree                 -- 是否需要验证 
    union.signInCnt = 0                         -- 签到人数
    union.signInTime = nil                      -- 签到时间戳
    union.apply = nil                           -- 申请列表
    union.bossLv = 1                            -- 公会副本boss当前等级
    union.logs = nil                            -- 公会日志
    union.mailCnt = nil                         -- 公会邮件发送数量
    union.mailTs = nil                          -- 公会邮件发送时间戳
    union.mill = nil                            -- 公会磨坊信息 {lv,donate}
    union.headFrame = nil                       -- 公会头像框(公会战给与，暂时屏蔽)
    union.copyBuff = nil                        -- 公会副本BUF
    union.shopLv = 0                            -- 公会商店等级
    union.shopExp = 0                           -- 公会商店经验
    union.recruit = nil                         -- 公会招募标记
    
    union.lastTreaAtkResult = nil               -- 上次宝藏掠夺战 攻击别人的结果 {[1]掠夺成功为1/掠夺失败为nil [2] [3]} 
    union.billboard = nil                       -- 各种公会秘境迷宫的排行榜
    addUnionMember(union, uuid, UnionDefine.POST_PRESIDENT)
    LuaMongo.insert(DB.db_union, union)

    BRoleLogic.updateData(BillboardDefine.TYPE_UNION, union)
    return union
end

-- 解散公会
function delUnion(unionUuid)
    if unionUuid == nil then return end

    QueryByUnionUuid._id = unionUuid
    LuaMongo.remove(DB.db_union, QueryByUnionUuid)
end

-- 添加公会成员
function addUnionMember(union, uuid, post)
    if union.member[uuid] then
        return
    end
    local member = {}
    member.post = post or UnionDefine.POST_MEMBER   -- 职位 
    member.donate = nil                             -- 捐献
    union.member[uuid] = member
    union.curCnt = union.curCnt + 1
    union.zhandouli = calcUnionZhandouli(union) 
    if union._id then
        updateUnionData(union)
        BRoleLogic.updateData(BillboardDefine.TYPE_UNION, union)
    end
end

-- 删除成员
function delUnionMember(union, uuid, isKict)
    if not union then return end

    union.member[uuid] = nil 
    union.curCnt = union.curCnt - 1
    union.zhandouli = calcUnionZhandouli(union) 
    if isKict then
        union.kickCntToday = (union.kickCntToday or 0) + 1
        union.kickTime = union.kickTime or os.time()
    end
    updateUnionData(union)
    BRoleLogic.updateData(BillboardDefine.TYPE_UNION, union)
end

-- 公会成员战力更新
function MemberPowerChange(union)
    if not union then return end
    union.zhandouli = calcUnionZhandouli(union)
    updateUnionData(union)
    BRoleLogic.updateData(BillboardDefine.TYPE_UNION, union)
end

-- 本日踢人数目
function getKickCntToday(union)
    if union.kickTime and 
        not Util.isSameDay(union.kickTime) then
        union.kickCntToday = nil 
        union.kickTime = nil
    end
    return union.kickCntToday or 0
end

-- 根据uuid获取公会成员信息
function getUnionMember(union, uuid)
    if not union then return end
    return union.member[uuid]
end

-- 计算公会战力
function calcUnionZhandouli(union) 
    if not union then return 0 end

    local zhandouli = 0
    for uuid in pairs(union.member) do
        local db = RoleDBLogic.getDb(uuid, "zhandouli")
        zhandouli = zhandouli + (db and db.zhandouli or 0)
    end
    return zhandouli
end

-- 推荐公会列表
function getRecommendList()
    local count = LuaMongo.count(Config.DB_NAME, "union")
    if count < 1 then return end

    local skip = 0
    local limit = count
    if count > UNION_DEFAULT_QUERY_LEN then
        limit = UNION_DEFAULT_QUERY_LEN
        skip = math.random(0, count - UNION_DEFAULT_QUERY_LEN)
    end

    LuaMongo.find(DB.db_union, nil, FieldBaseUnion, limit, skip)
    local unionList = {}
    while true do
        local union = {}
        if not LuaMongo.next(union) then
            break
        end
        unionList[#unionList + 1] = union
    end
    return unionList
end

-- 后台查询
function getUnionAdmin(start)
    local unionList = {}
    local all = LuaMongo.count(Config.DB_NAME, "union")
    LuaMongo.find(DB.db_union, {["$orderby"] = { lv = - 1 } }, FieldBaseUnion, 10, start)
    while true do
        if not LuaMongo.next(tempData) then
            break
        end
        local union = {}
        union.name = tempData.name
        union.lv = tempData.lv
        union.id = tempData.id
        unionList[#unionList + 1] = union
    end
    return #unionList, unionList, all
end

-- 日志
function addLog(unionUuid, content,classify) 
    local union = getUnion(unionUuid, FieldLog)
    if not union then return end

    local log = {}
    log.content = content
    log.time = os.time()
    log.classify = classify
    union.logs = union.logs or {}
    table.insert(union.logs, 1, log)
    union.logs[UNION_LOG_MAXCNT + 1] = nil
    upsetUnionData(union._id, "logs", union.logs)
end

-- 是否有申请
function hasApply(union)
    if not union.apply then
        return
    end
    return next(union.apply)
end

-- 是否已申请
function isApply(union, uuid)
    if not union.apply then
        return
    end
    return union.apply[uuid]
end

-- 添加申请
function addApply(union, uuid)
    if isApply(union, uuid) then
        return
    end

    union.apply = union.apply or {}
    union.apply[uuid] = os.time()
    upsetUnionData(union._id, "apply", union.apply)
end

-- 删除申请
function delApply(union, uuid)
    if not isApply(union, uuid) then
        return
    end

    union.apply[uuid] = nil
    upsetUnionData(union._id, "apply", union.apply)
end

-- 清空申请
function resetApply(union)
    if union.apply == nil then return end

    union.apply = nil
    upsetUnionData(union._id, "apply", nil)
end

-- 设置职位
function setPost(union, uuid, post)
    local member = getUnionMember(union, uuid)
    if not member then return end

    member.post = post 
    upsetUnionData(union._id, "member", union.member)
end

-- 获取职位人数
function getPostCnt(union, post)
    if not union then return 0 end

    local cnt = 0
    for _, member in pairs(union.member) do
        if member.post == post then
            cnt = cnt + 1
        end
    end
    return cnt
end

-- 设置公告
function setNotice(union, notice)  
    union.notice = notice
    union.noticeTime = os.time()
    updateUnionData(union)
end

-- 设置旗帜
function setBannerID(union, bannerID)  
    union.bannerID = bannerID
    updateUnionData(union)
end

-- 设置入会要求
function setJoinLimit(union, needLv, needAgree)
    union.needLv = needLv
    union.needAgree = needAgree
    updateUnionData(union)
end

-- 更换会长
function setPresident(union, targetUuid)
    local oldMember = getUnionMember(union, union.presidentUuid)
    if oldMember then
        oldMember.post = UnionDefine.POST_MEMBER
    end
    local newMember = getUnionMember(union, targetUuid)
    newMember.post = UnionDefine.POST_PRESIDENT
    union.presidentUuid = targetUuid
    updateUnionData(union)
end

-- 本日签到数目
function getSignInCnt(union)
    if union.signInTime and 
        not Util.isSameDay(union.signInTime) then
        union.signInCnt = nil 
        union.signInTime = nil
    end
    return union.signInCnt or 0
end

-- 设置公会名称
function setUnionName(union, name)
    union.name = name 
    union.nameTime = os.time()
    updateUnionData(union)
end

-- 本日公会邮件数目
function getMailCnt(union)
    if union.mailTs and 
        not Util.isSameDay(union.mailTs) then
        union.mailCnt = nil 
        union.mailTs = nil
    end
    return union.mailCnt or 0
end

-- 更新公会副本等级
function updateBossLv(union, level)
    level = tonumber(level)
    if not level then return end

    upsetUnionData(union._id, "bossLv", level)
end

-- 获取工坊等级
function getMillLv(union)
    return union.mill and union.mill.lv or 1
end

-- 获取工坊经验
function getMillDonate(union)
     return union.mill and union.mill.donate or 1   
end

-- 初始工坊信息
function initMillData(union)
    union.mill = {}
    union.mill.lv = 1
    union.mill.donate = 0
end

-- 回收头像框
function cleanUnionHeadFrame()
    LuaMongo.find(DB.db_union, QueryByHeadFrame, FieldBaseUnion)
    local list = {}
    while true do
        local union = { }
        if not LuaMongo.next(union) then
            break
        end
        list[#list + 1] = union._id
    end
    for _, unionUuid in ipairs(list) do
        upsetUnionData(unionUuid, "headFrame", nil)
    end
end

-- 更新公会 全体BUF
function updateEctypeBuf(union)
    if union.copyBuff == nil then return end    
  
    upsetUnionData(union._id, "copyBuff", union.copyBuff)
    
end

function updateJihuo(union)

    upsetUnionData(union._id, "jihuo", union.jihuo)
    upsetUnionData(union._id, "jihuoTime", union.jihuoTime)  
end

-- 公会红包

-- 发送公会改DB
function insertSendRedBag(unionUuid,redBagID,redBagName,sender,senderPost,config,index)
    local now = os.time()
    QueryByUnionUuid._id = unionUuid
    
    -- 更新发红包次数,红包ID
	local updateTb = { ["$inc"]= {["redBagID"] = 1}}
    LuaMongo.update(DB.db_union, QueryByUnionUuid, updateTb)

    -- 更新红包总额排行榜
    local updateTb = { ["$inc"]= {
        ["redBagRank."..sender.uuid..".totalMoney"] = config.price,
        ["redBagRank."..sender.uuid..".bagCnt"] = 1,
        }}
    LuaMongo.update(DB.db_union, QueryByUnionUuid, updateTb)

    -- 更新红包数据
    local obj = {}
    obj.id = redBagID
    obj.type = config.type
    obj.name = config.name
    obj.sender = sender
    obj.senderPost = senderPost
    obj.bagCnt = config.bagCnt
    obj.nowCnt = 0
    obj.itemID = config.content[1][1]
    obj.itemCnt = config.content[1][2]
    obj.leftCnt = config.content[1][2]
    obj.time = now + config.time*60*60
    obj.index = config.index

    updateTb = {
        ["redBag."..redBagID] = obj
    }

    local tb = { }
    tb["$set"] = updateTb
    LuaMongo.update(DB.db_union, QueryByUnionUuid, tb)
end

function updateRedBagRecord(unionUuid,uuid,redBagID,itemID,itemCnt)
    local now = os.time()
    QueryByUnionUuid._id = unionUuid
    
    -- 更新红包记录
    local role = {}
    RoleLogic.getRoleBaseByUuid(uuid,role)

    local obj = {}
    obj.itemID = itemID
    obj.itemCnt = itemCnt
    obj.role = role
    obj.time = now

    local updateTb = {
        ["redBag."..redBagID..".record."..uuid] = obj
    }

    local tb = { }
    tb["$set"] = updateTb
    LuaMongo.update(DB.db_union, QueryByUnionUuid, tb)

    updateTb = { ["$inc"]= {["redBag."..redBagID..".leftCnt"] = -itemCnt,["redBag."..redBagID..".nowCnt"] = 1}}
    LuaMongo.update(DB.db_union, QueryByUnionUuid, updateTb)
end

function cleanRedBagCnt(human)
    human.db.redBagCnt = nil
end