local LuaMongo = _G.LuaMongo
local Util = require("common.Util")
local Msg = require("core.Msg")
local RoleLogic = require("role.RoleLogic")
local ChatHandler = require("chat.Handler")
local DB = require("common.DB")
local ChatDBLogic = require("chat.ChatDBLogic")
local RoleDBLogic = require("role.RoleDBLogic")
local Lang = require("common.Lang")

CHAT_RECORD_CNT = 30 -- 聊天记录保存60条
CHAT_MIDDLE_CNT = 30    -- 跨服聊天记录缓存条数
CHAT_RECORD_JINDU = CHAT_RECORD_JINDU or {}                     -- 聊天记录进度
CHAT_FRIEND_LIST_CNT = 20  -- 私聊最多保留20个好友

CHAT_RECORD = CHAT_RECORD or {}
CHAT_RECORD_UNION = CHAT_RECORD_UNION or {}
CHAT_RECORD_FRIEND = CHAT_RECORD_FRIEND or {}

-- 玩家发言记录
CHAT_RECORD_REPETITION = CHAT_RECORD_REPETITION or {}

local function chatRecord_IsMakeRoleBase(nMsgType)
    if ChatHandler.CHAT_TYPE_MIDDLE == nMsgType or ChatHandler.CHAT_TYPE_WARZONE == nMsgType then
        return false
    end

    return true
end
-------------- 封装结构体 --------------------
-- 普通聊天记录结构体
local function fontRecord(human,net,msgType)
    if CHAT_RECORD[msgType] == nil then
       return 0
    end
    local cnt = 0
    local len = #CHAT_RECORD[msgType]
	for i = 1, len do
        local record = CHAT_RECORD[msgType][i]
        if human.db.friendBlack == nil or human.db.friendBlack[record.roleBase.uuid] == nil then 
            cnt = cnt + 1
		    net[cnt].msgType = record.msgType
			local fields = {}
           
            -- 跨服直接赋值
            if false == chatRecord_IsMakeRoleBase(msgType) then
                net[cnt].roleBase = Util.copyTable(record.roleBase)
            else
                RoleLogic.makeRoleBase(record.roleBase,net[cnt].roleBase)
            end

			RoleLogic.makeRoleBaseFields(fields)
			local db = RoleDBLogic.getDb(record.roleBase.uuid,fields)

            if db and true == chatRecord_IsMakeRoleBase(msgType) then
                RoleLogic.makeRoleBase(db,net[cnt].roleBase)
            end

		    net[cnt].vipLv = record.vipLv
		    net[cnt].msg = record.msg
		    net[cnt].sendTime = record.sendTime
		    net[cnt].isJson = record.isJson
		    net[cnt].videoUuid = record.videoUuid or ""
		    net[cnt].unionFrame = record.unionFrame or 0
		    net[cnt].label = record.label or 0
		    net[cnt].svrName = record.svrName or ""
        end
	end
	
	return cnt
end

-- 好友私聊
local function fontFriendRecord(human,net,data,uuid,fUuid)
    local len = #data
    local cnt = 0
	for i = 1, len do
        local v = data[i]
        if human.db.friendBlack == nil or human.db.friendBlack[v.roleBase.uuid] == nil then 
            cnt = cnt + 1
		    net[cnt].msgType = v.msgType
			local fields = {}
            RoleLogic.makeRoleBase(v.roleBase,net[cnt].roleBase)
			RoleLogic.makeRoleBaseFields(fields)
			local db = RoleDBLogic.getDb(v.roleBase.uuid,fields)
            if db then
                RoleLogic.makeRoleBase(db,net[cnt].roleBase)
		    end
            net[cnt].vipLv = v.vipLv
		    net[cnt].msg = v.msg
		    net[cnt].sendTime = v.sendTime
		    net[cnt].isJson = v.isJson
		    net[cnt].videoUuid = v.videoUuid or ""
		    net[cnt].unionFrame = v.unionFrame or 0
		    net[cnt].label = v.label or 0
		    net[cnt].svrName = v.svrName or ""
        end
	end
	
	return cnt
end

-- 公会聊天
local function fontUnionRecord(human,net, unionUuid)
    if CHAT_RECORD_UNION[unionUuid] == nil then
       return 0
    end
    
    local cnt = 0
    local len = #CHAT_RECORD_UNION[unionUuid]
	for i = 1, len do
		local record = CHAT_RECORD_UNION[unionUuid][i]
        if human.db.friendBlack == nil or human.db.friendBlack[record.roleBase.uuid] == nil then 
            cnt = cnt + 1
		    net[cnt].msgType = record.msgType
            RoleLogic.makeRoleBase(record.roleBase,net[cnt].roleBase)
			local fields = {}
			RoleLogic.makeRoleBaseFields(fields)
			local db = RoleDBLogic.getDb(record.roleBase.uuid,fields)
            if db then
                RoleLogic.makeRoleBase(db,net[cnt].roleBase)
		    end
            net[cnt].vipLv = record.vipLv
            net[cnt].msg = record.msg
		    net[cnt].sendTime = record.sendTime
		    net[cnt].isJson = record.isJson
		    net[cnt].videoUuid = record.videoUuid or ""
		    net[cnt].unionFrame = record.unionFrame or 0
		    net[cnt].label = record.label or 0
		    net[cnt].svrName = record.svrName or ""
        end
	end
	
    return cnt
end
----------------------------end----------------------------------------

-- 启动时，加载玩家私聊数据
function initAfterStart()
    CHAT_RECORD_FRIEND = {}
    local fields = {uuid = 1,fUuid = 1}
    LuaMongo.find(DB.db_chat_record,nil,fields)
    while true do
        local recordData = {}
        if not LuaMongo.next(recordData) then
            return
        end
        local cnt = 0
        if CHAT_RECORD_FRIEND[recordData.uuid] == nil then
           CHAT_RECORD_FRIEND[recordData.uuid] = {count = 0,list = {}}   
        end
        table.insert(CHAT_RECORD_FRIEND[recordData.uuid].list,recordData.fUuid)
    end
end

-- 添加聊天记录
-- uuid  自己的uuid
-- fUuid 好友的Uuid
-- 缓存中 count 为新消息总数，list 为私聊好友列表
function addRecord(human,chatItem, msgType,fUuid)
    local uuid = human.db._id
    local unionUuid = human.db.unionUuid
    local record = nil
    if msgType == ChatHandler.CHAT_TYPE_FRIEND then 
        -- 好友聊天,记录好友到缓存
        CHAT_RECORD_FRIEND[uuid] = CHAT_RECORD_FRIEND[uuid] or {count = 0,list = {}} 
        CHAT_RECORD_FRIEND[fUuid] = CHAT_RECORD_FRIEND[fUuid] or {count = 0,list = {}} 

        -- 判断uuid是否存在于缓存中
        local exist,index = checkCacheFriend(uuid,fUuid)
        if exist == nil then
            -- 不存在则插入
	        table.insert(CHAT_RECORD_FRIEND[uuid].list, fUuid)
	        if #CHAT_RECORD_FRIEND[uuid].list > CHAT_RECORD_CNT then
                -- 删除被顶好友记录
                local delUuid = CHAT_RECORD_FRIEND[uuid].list[1]
                ChatDBLogic.delFriendChatRecord(uuid,fUuid)
	        	table.remove(CHAT_RECORD_FRIEND[uuid].list, 1)
	        end
        else
            -- 存在则移除，并重新插入
            table.remove(CHAT_RECORD_FRIEND[uuid].list, index)
            table.insert(CHAT_RECORD_FRIEND[uuid].list, fUuid)
        end

        exist,index = checkCacheFriend(fUuid,uuid)
        if exist == nil then
            table.insert(CHAT_RECORD_FRIEND[fUuid].list, uuid)
	        if #CHAT_RECORD_FRIEND[fUuid].list > CHAT_RECORD_CNT then
                -- 删除被顶好友记录
                local delUuid = CHAT_RECORD_FRIEND[fUuid].list[1]
                ChatDBLogic.delFriendChatRecord(fUuid,uuid)
	        	table.remove(CHAT_RECORD_FRIEND[fUuid].list, 1)
	        end
        else
            -- 存在则移除，并重新插入
            table.remove(CHAT_RECORD_FRIEND[fUuid].list, index)
            table.insert(CHAT_RECORD_FRIEND[fUuid].list, uuid)
        end
        CHAT_RECORD_FRIEND[fUuid].count = CHAT_RECORD_FRIEND[fUuid].count + 1

        --加聊天记录到数据库
        ChatDBLogic.addFriendChatRecord(uuid,fUuid,chatItem)
        ChatDBLogic.addFriendChatRecord(fUuid,uuid,chatItem)
    elseif msgType == ChatHandler.CHAT_TYPE_MIDDLE then
        -- 跨服聊天
        -- 本地记录数据
	    if CHAT_RECORD[msgType] == nil then
           CHAT_RECORD[msgType] = {}   
        end
        record = CHAT_RECORD[msgType]
    elseif msgType == ChatHandler.CHAT_TYPE_WARZONE then
        if CHAT_RECORD[msgType] == nil then
            CHAT_RECORD[msgType] = {}   
         end
         record = CHAT_RECORD[msgType]
    elseif msgType == ChatHandler.CHAT_TYPE_UNION then
        -- 公会聊天
        if CHAT_RECORD_UNION[unionUuid] == nil then
           CHAT_RECORD_UNION[unionUuid] = {}   
        end
        record = CHAT_RECORD_UNION[unionUuid]
    else
        -- 其他聊天
	    if CHAT_RECORD[msgType] == nil then
           CHAT_RECORD[msgType] = {}   
        end
        record = CHAT_RECORD[msgType]
    end

    CHAT_RECORD_JINDU[msgType] = CHAT_RECORD_JINDU[msgType] or 0
    CHAT_RECORD_JINDU[msgType] = CHAT_RECORD_JINDU[msgType] + 1

    repetitionRecord(human,chatItem.msg)

    -- 插入聊天记录到缓存,好友聊天除外
    if msgType ~= ChatHandler.CHAT_TYPE_FRIEND then
        -- 
        human.db.chatRead = human.db.chatRead or {}
        human.db.chatRead[msgType] = human.db.chatRead[msgType] or 0
        human.db.chatRead[msgType] = CHAT_RECORD_JINDU[msgType]

        local newTb = Util.copyTable(chatItem)
	    table.insert(record, newTb)
	    if #record > CHAT_RECORD_CNT then
	    	table.remove(record, 1)
	    end
    end
end

-- 添加跨服聊天记录
function addMiddleRecord(chatItem, msgType)
    if msgType ~= ChatHandler.CHAT_TYPE_MIDDLE and msgType ~= ChatHandler.CHAT_TYPE_WARZONE then
        print("[addMiddleRecord] 此处返回了？msgType = "..msgType)
        return
    end

    local record = nil
    if CHAT_RECORD[msgType] == nil then
        CHAT_RECORD[msgType] = {}   
    end
    record = CHAT_RECORD[msgType]

    local nLen = #record
    if nLen >= CHAT_MIDDLE_CNT then
        local nDelLen = nLen - CHAT_MIDDLE_CNT + 1
        for i = nDelLen, 1, -1 do
            table.remove(record, i)
        end
    end

    local newTb = Util.copyTable(chatItem)
    table.insert(record, newTb)
end

-- 根据玩家Uuid 删除聊天记录
function delRecordByUuid(uuid, msgType)
	local tb = CHAT_RECORD[msgType]
	if tb == nil then
		return
	end
	
	for i = #tb, 1, -1 do
		local record = tb[i]
		if record.roleBase.uuid == uuid then
			table.remove(tb, i)
		end
	end
end

-- 添加公会聊天记录
function addUnionRecord(chatItem, unionUuid)
    if CHAT_RECORD_UNION[unionUuid] == nil then
       CHAT_RECORD_UNION[unionUuid] = {}   
    end

    local newTb = Util.copyTable(chatItem)
	table.insert(CHAT_RECORD_UNION[unionUuid], newTb)
	if #CHAT_RECORD_UNION[unionUuid] > CHAT_RECORD_CNT then
		table.remove(CHAT_RECORD_UNION[unionUuid], 1)
	end
end

-- 初始化玩家阅读记录条数
function initHumanChatRead(human)
    human.db.chatRead = human.db.chatRead or {}
end

-- 根据类型获取聊天记录
function getChatRecord(human,type)
    if type == ChatHandler.CHAT_TYPE_FRIEND then
        return
    end

    local msgRet = Msg.gc.GC_CHAT_RECORD_QUERY

    -- 消息记录
    local len = 0
    if type == ChatHandler.CHAT_TYPE_UNION then -- 公会聊天
        if human.db.unionUuid ~= nil then
            len = fontUnionRecord(human,msgRet.chatList,human.db.unionUuid)
        end
    else    -- 其他聊天（包括跨服）
        len = fontRecord(human,msgRet.chatList,type)
    end
    msgRet.chatList[0] = len and len or 0

    -- 未读信息
    for i = 1,ChatHandler.CHAT_TYPE_CNT do
        local net = msgRet.notRead[i]
        net.msgType = i
        net.notRead = 0
        
        -- 私聊特殊
        if i == ChatHandler.CHAT_TYPE_FRIEND then
            if CHAT_RECORD_FRIEND[human.db._id] == nil then
                net.notRead = 0
            else
                net.notRead = CHAT_RECORD_FRIEND[human.db._id].count 
            end
        elseif i == ChatHandler.CHAT_TYPE_UNION then
            local len = CHAT_RECORD_JINDU[i]
            if len ~= nil then
                human.db.chatRead[i] = human.db.chatRead[i] or 0

                net.notRead = len - human.db.chatRead[i]
                if net.notRead >= CHAT_RECORD_CNT then
                    net.notRead = CHAT_RECORD_CNT
                elseif net.notRead < 0 then
                    net.notRead = 0
                end
            end
        else
            if CHAT_RECORD[i] ~= nil then
                if i ~= ChatHandler.CHAT_TYPE_MIDDLE and i ~= ChatHandler.CHAT_TYPE_WARZONE then
                    local len = CHAT_RECORD_JINDU[i]
                    human.db.chatRead[i] = human.db.chatRead[i] or 0
    
                    net.notRead = len - human.db.chatRead[i]
                    if net.notRead >= CHAT_RECORD_CNT then
                        net.notRead = CHAT_RECORD_CNT
                    elseif net.notRead < 0 then
                        net.notRead = 0
                    end
                else
                    net.notRead = 0
                end
            end
        end
        -- 是当前查看类型
        if type == i then   
            local len = CHAT_RECORD_JINDU[i]
            human.db.chatRead[i] = len or 0
        end
    end

    msgRet.notRead[0] = ChatHandler.CHAT_TYPE_CNT
    Msg.send(msgRet,human.fd)
end

-- 获取私聊聊天记录
function getChatFriendList(human)
    local msgRet = Msg.gc.GC_CHAT_FRIEND_RECORD
    local cnt = 0
   
	if CHAT_RECORD_FRIEND[human.db._id] then
		local tb = CHAT_RECORD_FRIEND[human.db._id].list
		for k,v in pairs(tb) do
			local fields = {}
			RoleLogic.makeRoleBaseFields(fields)
			local db = RoleDBLogic.getDb(v,fields)

			cnt = cnt + 1
			RoleLogic.makeRoleBase(db,msgRet.chatFriendList[cnt])

			if cnt >= CHAT_FRIEND_LIST_CNT then
				break
			end
		end
	end

    msgRet.chatFriendList[0] = cnt
    Msg.send(msgRet,human.fd)

	if CHAT_RECORD_FRIEND[human.db._id] then
		-- 清空未读条数
		CHAT_RECORD_FRIEND[human.db._id].count = 0
	end
end

-- 根据uuid获取好友聊天记录
function getChatFriendRecord(human,uuid)
    -- 没有聊天记录，返回
    if CHAT_RECORD_FRIEND[human.db._id] == nil then
        return 
    end

    local recordTb = ChatDBLogic.getFriendChatRecord(human.db._id,uuid)
    -- 没有与该玩家的聊天记录
    if recordTb == nil then
        return
    end

    local msgRet = Msg.gc.GC_CHAT_FRIEND_RECORD_BY_FRIEND
    local len = fontFriendRecord(human,msgRet.chatRecord,recordTb.chatRecord,human.db._id,uuid)
    msgRet.chatRecord[0] = len

    Msg.send(msgRet,human.fd)
end

-- 新增好友聊天
function addFriendChat(human,uuid)
    -- 新增聊天，只增加列表，不加记录，所以只对自己的缓存操作
    CHAT_RECORD_FRIEND[human.db._id] = CHAT_RECORD_FRIEND[human.db._id] or {count = 0,list = {}} 
    
    -- 已经在最近聊天对象列表中
    for i = 1, #CHAT_RECORD_FRIEND[human.db._id].list do
		if CHAT_RECORD_FRIEND[human.db._id].list[i] == uuid then
			return
		end
    end

    table.insert(CHAT_RECORD_FRIEND[human.db._id].list, uuid)
	if #CHAT_RECORD_FRIEND[human.db._id].list > CHAT_FRIEND_LIST_CNT then
        -- 删除被顶好友记录
        local delUuid = CHAT_RECORD_FRIEND[human.db._id].list[1]
        ChatDBLogic.delFriendChatRecord(human.db._id,uuid)
		table.remove(CHAT_RECORD_FRIEND[human.db._id].list, 1)
	end
    
    -- 添加数据库数据
    ChatDBLogic.addFriendChatRecord(human.db._id,uuid)
end

function delFriendChatRecord(human,uuid)
    -- 清除缓存数据
    -- 缓存中不存在私聊聊天数据
    if CHAT_RECORD_FRIEND[human.db._id] == nil then
        return
    end

    -- 移除缓存中数据
    local exist,index = checkCacheFriend(human.db._id,uuid)
    if exist ~= nil and index ~= nil then
        table.remove(CHAT_RECORD_FRIEND[human.db._id].list, index)
    end

    -- 清除数据库数据
    ChatDBLogic.delFriendChatRecord(human.db._id,uuid)
    
    -- 查询聊天记录列表
    getChatFriendList(human)
end

-- 删除双方私聊记录
function delFriendChatRecordDouble(fUuid,uuid)
    -- 清除数据库数据
    ChatDBLogic.delFriendChatRecord(fUuid,uuid)

    -- 清除数据库数据
    ChatDBLogic.delFriendChatRecord(uuid,fUuid)
end

-- 检查私聊缓存中是否存在当前好友
function checkCacheFriend(uuid,fUuid)
    if CHAT_RECORD_FRIEND[uuid] == nil then
        return
    end

    local len = #CHAT_RECORD_FRIEND[uuid].list
    if len <= 0 then
        return
    end

    for i = 1,len do
        local v = CHAT_RECORD_FRIEND[uuid].list[i]
        if v == fUuid then
            return true,i
        end
    end
end

-- 发送未读总数
function sendAllNotRead(human)
    local allNotRead = 0

    -- 未读信息
    for i = 1,ChatHandler.CHAT_TYPE_CNT do
        -- 私聊特殊
        if i == ChatHandler.CHAT_TYPE_FRIEND then
            if CHAT_RECORD_FRIEND[human.db._id] ~= nil then
                allNotRead = allNotRead + CHAT_RECORD_FRIEND[human.db._id].count 
            end
        else
            if CHAT_RECORD[i] ~= nil then
                if i ~= ChatHandler.CHAT_TYPE_MIDDLE and i~= ChatHandler.CHAT_TYPE_WARZONE then
                    local len = CHAT_RECORD_JINDU[i]
                    human.db.chatRead[i] = human.db.chatRead[i] or 0
    
                    local notRead = len - human.db.chatRead[i]
                    if notRead >= CHAT_RECORD_CNT then
                        notRead = CHAT_RECORD_CNT
                    elseif notRead < 0 then
                        notRead = 0
                    end
                    allNotRead = allNotRead + notRead
                end
            end
        end
    end

    local msgRet = Msg.gc.GC_CHAT_NOT_READ_ALL
    msgRet.notRead = allNotRead
    Msg.send(msgRet,human.fd)
end

function repetitionRecord(human,str)
    -- 等级大于20级，返回
    --if human.db.lv >= 20 then
    --    return
    --end

    -- 充值过，返回
    if human.db.topupAcount ~= nil then
        return
    end

    -- 检验聊天内容
    if CHAT_RECORD_REPETITION[human.db._id] ~= nil then
        if CHAT_RECORD_REPETITION[human.db._id][str] ~= nil then
            CHAT_RECORD_REPETITION[human.db._id][str] = CHAT_RECORD_REPETITION[human.db._id][str] + 1
            if CHAT_RECORD_REPETITION[human.db._id][str] >= 10 then
                human.db.banSayTime = human.db.banSayTime or 0
                local banTime = os.time() + 24*60*60
                if human.db.banSayTime < banTime then
                    human.db.banSayTime = banTime
                    human.db.banSayReason = Lang.CHAT_BAN_REASON_JUBAO
                end
            end
        else
            CHAT_RECORD_REPETITION[human.db._id][str] = 1
        end
    else
        CHAT_RECORD_REPETITION[human.db._id] = {}
        CHAT_RECORD_REPETITION[human.db._id][str] = 1
    end
end