
local Msg = require("core.Msg")
local ChatHandler = require("chat.Handler")
local VipLogic = require("vip.VipLogic")
local Log = require("common.Log")
local FilterUtil = require("common.FilterUtil")
local Gm = require("chat.Gm")
local ChatRecord = require("chat.ChatRecord")
local Broadcast = require("broadcast.Broadcast")
local UnionDBLogic = require("union.UnionDBLogic")
local UnionLogic = require("union.UnionLogic")
local Timer = require("core.Timer")
local Lang = require("common.Lang")
local Util = require("common.Util")
local RoleLogic = require("role.RoleLogic")
local FriendDBLogic = require("friend.FriendDBLogic")
local Config = require("Config")
local RoleDBLogic = require("role.RoleDBLogic")
local SettingLogic = require("setting.SettingLogic")
local ObjHuman = require("core.ObjHuman")
local InnerMsg = require("core.InnerMsg")
local CommonDB = require("common.CommonDB")
local YunYingLogic = require("yunying.YunYingLogic")
local TriggerDefine = require("trigger.TriggerDefine")
local TriggerLogic = require("trigger.TriggerLogic")

local CHAT_SENDDOWN_RESON_LV = 1
local CHAT_SENDDOWN_RESON_DAY = 2

local function ChatLogic_GetLimit(nChatType)
    local nLimitLv, nLimitOpenDay = 0, 0
    if ChatHandler.CHAT_TYPE_MIDDLE == nChatType then
        nLimitLv = ChatHandler.CHAT_LV_NEED_MIDDLE
        nLimitOpenDay = ChatHandler.CHAT_OPEN_DAY_MIDDLE

    elseif ChatHandler.CHAT_TYPE_WARZONE == nChatType then
        nLimitLv = ChatHandler.CHAT_LV_NEED_WARZONE
        nLimitOpenDay = ChatHandler.CHAT_OPEN_DAY_WARZONE
    elseif ChatHandler.CHAT_TYPE_WORLD == nChatType then
        nLimitLv = ChatHandler.CHAT_LV_NEED_WORLD
    elseif ChatHandler.CHAT_TYPE_FRIEND == nChatType then
        nLimitLv = ChatHandler.CHAT_LV_NEED_FRIEND
    end

    return nLimitLv, nLimitOpenDay
end

local function ChatLogic_SendDown(human, nChatType, nReson)
    local str
    if ChatHandler.CHAT_TYPE_MIDDLE == nChatType then
        str = Util.format(Lang.CHAT_MIDDLE_NEED_LV_ARGS, ChatHandler.CHAT_LV_NEED_MIDDLE)
    elseif ChatHandler.CHAT_TYPE_WARZONE == nChatType then
        str = Util.format(Lang.CHAT_WARZONE_NEED_LV_ARGS, ChatHandler.CHAT_LV_NEED_WARZONE)
    elseif ChatHandler.CHAT_TYPE_WORLD == nChatType then
        str = Util.format(Lang.CHAT_NEED_LV_ARGS, ChatHandler.CHAT_LV_NEED_WORLD)
    elseif ChatHandler.CHAT_TYPE_FRIEND == nChatType then
        str = Util.format(Lang.CHAT_NEED_LV_ARGS, ChatHandler.CHAT_LV_NEED_FRIEND)
    end

    Broadcast.sendDown(human, str)
end

function chat(human, recvMsg, isJson)
	if Gm.checkGm(human, recvMsg.msg) then
		return 
	end

    isJson = isJson or ChatHandler.CHAT_NORMAL
    
    local nOpenServerDay = CommonDB.getServerOpenDay()
    local nLimitLv, nLimitOpenDay = ChatLogic_GetLimit(recvMsg.msgType)
    if human.db.lv < nLimitLv and VipLogic.getVipLv(human) == 0 then
        ChatLogic_SendDown(human, recvMsg.msgType, CHAT_SENDDOWN_RESON_LV)
        return
    end

    if nOpenServerDay < nLimitOpenDay then
        ChatLogic_SendDown(human, recvMsg.msgType, CHAT_SENDDOWN_RESON_DAY)
        return
    end

	--世界聊天限制等级
    -- if recvMsg.msgType == ChatHandler.CHAT_TYPE_WORLD then 
	-- 	if human.db.lv < ChatHandler.CHAT_LV_NEED_WORLD and VipLogic.getVipLv(human) == 0 then
    --         local str = Util.format(Lang.CHAT_NEED_LV_ARGS, ChatHandler.CHAT_LV_NEED_WORLD)
	-- 		Broadcast.sendDown(human, str)
	-- 		return 
	-- 	end
    -- end

    -- 跨服聊天限制等级
    -- if recvMsg.msgType == ChatHandler.CHAT_TYPE_MIDDLE then 
    --     local nOpenServerDay = CommonDB.getServerOpenDay()
    --     if nOpenServerDay < 15 then
    --         local str = Util.format(Lang.CHAT_MIDDLE_NEED_LV_ARGS, ChatHandler.CHAT_LV_NEED_MIDDLE)
	-- 		Broadcast.sendDown(human, str)
    --         return
    --     end

	-- 	if human.db.lv < ChatHandler.CHAT_LV_NEED_MIDDLE and VipLogic.getVipLv(human) == 0 then
	-- 		local str = Util.format(Lang.CHAT_MIDDLE_NEED_LV_ARGS, ChatHandler.CHAT_LV_NEED_MIDDLE)
	-- 		Broadcast.sendDown(human, str)
	-- 		return 
	-- 	end
    -- end

    -- 好友私聊
    if recvMsg.msgType == ChatHandler.CHAT_TYPE_FRIEND then 
		-- 聊天权限判断
        -- if human.db.lv < ChatHandler.CHAT_LV_NEED_FRIEND and VipLogic.getVipLv(human) == 0 then
		-- 	local str = Util.format(Lang.CHAT_NEED_LV_ARGS, ChatHandler.CHAT_LV_NEED_FRIEND)
		-- 	Broadcast.sendDown(human, str)
		-- 	return 
		-- end

        -- 是否互为好友
        local isFriend = FriendDBLogic.isFriend(human.db._id, recvMsg.fUuid)
        if isFriend ~= true then
            return Broadcast.sendDown(human, Lang.CHAT_ERR_NOT_FIREND)
        end
        
        local db = RoleDBLogic.getDb(recvMsg.fUuid, fields)
        local tempHuman = {}
        tempHuman.db = db
        local cantPrivate = SettingLogic.isNoPrivateChat(tempHuman)
        if cantPrivate == true then
            return Broadcast.sendDown(human, Lang.CHAT_ERR_CNT_FIREND)
        end
    end

    --判定是否被禁言
	if human.db.banSayTime and (os.time() < human.db.banSayTime or human.db.banSayTime == -1) then
        local leftMin = math.ceil((human.db.banSayTime - os.time())/60)
        local content = Util.format(human.db.banSayReason,leftMin)
        Broadcast.sendErr(human, content)	
        return 
	end	

    human.db.banSay = nil
    human.db.banSayTime = nil
	--Log.write(Log.LOGID_OSS_CHAT, human.db._id, human.db.account, human.db.name, human.db.ip, recvMsg.msgType, recvMsg.msg)
    Log.write(Log.LOGID_OSS_CHAT, human.db._id, human.db.newUniqueTag, human.db.name, human.db.ip, recvMsg.msgType, recvMsg.msg)


    -- 发送聊天数据
	local msgRet = Msg.gc.GC_CHAT
	if SettingLogic.isNoShowVip(human) == true then
		msgRet.item.vipLv = VipLogic.getVipLv(human)
        if msgRet.item.vipLv > 0 and msgRet.item.vipLv < 14 then
            msgRet.item.vipLv = -1
        end
	else
		msgRet.item.vipLv = VipLogic.getVipLv(human)
	end

    -- 获取服务器名
    msgRet.item.svrName = Config.SVR_NAME
    -- 角色信息
    RoleLogic.getRoleBase(human,msgRet.item.roleBase)

    -- 称号
    msgRet.item.label = human.db.chenghao or 0

    -- 聊天内容
    if isJson > ChatHandler.CHAT_NORMAL then
        msgRet.item.msg = recvMsg.msg
    else
        msgRet.item.msg = FilterUtil.filter(recvMsg.msg)
    end	
	
    msgRet.item.msgType = recvMsg.msgType
	msgRet.item.isJson = isJson 
	msgRet.item.sendTime = os.time()
	msgRet.item.videoUuid = recvMsg.videoUuid or ""

    -- 频道上次发言时间
    human.chatTime = human.chatTime or {}
    local chatTime = human.chatTime[recvMsg.msgType] or 0

    if recvMsg.msgType == ChatHandler.CHAT_TYPE_WORLD or    --世界聊天
       recvMsg.msgType == ChatHandler.CHAT_TYPE_MIDDLE or   -- 全服
       ChatHandler.CHAT_TYPE_WARZONE == recvMsg.msgType then    -- 战区
        --世界聊天
        -- 判断上次发言时间
        if chatTime and chatTime + ChatHandler.CHAT_CD > Timer.now then
			local cdLeftSec = math.ceil((ChatHandler.CHAT_CD - (Timer.now - chatTime))/1000)
			Broadcast.sendDown(human, Util.format(Lang.CHAT_TIME_SHORT, cdLeftSec))
			return 
		end
		
        -- 不是战斗记录的情况下，判断是否重复发消息
		if (recvMsg.videoUuid == nil or 
           recvMsg.videoUuid == "") and
           human.worldChatLast and 
           human.worldChatLast[recvMsg.msgType] and
           human.worldChatLast[recvMsg.msgType] == msgRet.item.msg then
		    Broadcast.sendDown(human, Lang.CHAT_TIME_DUPLICATE)
		    return 
		end
		human.worldChatLast = human.worldChatLast or {}
		human.worldChatLast[recvMsg.msgType] = msgRet.item.msg
        human.chatTime[recvMsg.msgType] = Timer.now

        -- 跨服
        if  recvMsg.msgType == ChatHandler.CHAT_TYPE_MIDDLE 
            or ChatHandler.CHAT_TYPE_WARZONE == recvMsg.msgType then
            -- 发送数据到中心服
            local lwMsgRet = InnerMsg.lw.LW_MIDDLE_CHAT
            lwMsgRet.svrIndex = Config.SVR_INDEX
            lwMsgRet.tChatMsg = msgRet
            InnerMsg.sendMsg(0, lwMsgRet)
            print("[chat] 发送跨服消息开始")
        else
		    Msg.sendWorld(msgRet)
            ChatRecord.addRecord(human,msgRet.item, recvMsg.msgType)
        end
    elseif recvMsg.msgType == ChatHandler.CHAT_TYPE_UNION then
        --公会聊天
    	local union = UnionDBLogic.getUnion(human.db.unionUuid)
    	if not union then
    		Broadcast.sendDown(human, Lang.CHAT_NEED_JOIN_UNION)
    		return 
    	end

--		if msgRet.item.isJson > ChatHandler.CHAT_NORMAL then
--			Broadcast.sendDown(human, Lang.SHARE_SUCCESS)
--		end

		UnionLogic.send2Union(msgRet, union)
		--ChatRecord.addUnionRecord(msgRet.item, human.db.unionUuid)
        ChatRecord.addRecord(human,msgRet.item, recvMsg.msgType)
    else
        -- 其他聊天
        if chatTime and chatTime + ChatHandler.CHAT_CD > Timer.now then
			local cdLeftSec = math.ceil((ChatHandler.CHAT_CD - (Timer.now - chatTime))/1000)
			Broadcast.sendDown(human, Util.format(Lang.CHAT_TIME_SHORT, cdLeftSec))
			return 
		end

        human.chatTime[recvMsg.msgType] = Timer.now

        -- 好友特殊发送
        if recvMsg.msgType == ChatHandler.CHAT_TYPE_FRIEND then
            local fHuman = ObjHuman.onlineUuid[recvMsg.fUuid]
            if fHuman and fHuman.fd then
                Msg.send(msgRet, fHuman.fd)
            end
			Msg.send(msgRet, human.fd)

            ChatRecord.addRecord(human,msgRet.item, recvMsg.msgType,recvMsg.fUuid)
        else
            Msg.sendWorld(msgRet)
            ChatRecord.addRecord(human,msgRet.item, recvMsg.msgType)
        end
    end
	
    YunYingLogic.onCallBack(human, "ChatTimes", 1)

    TriggerLogic.PublishEvent(TriggerDefine.CHAT_TIMES, human.db._id, 1)

    -- 上报消息到后台
	ChatHandler.chatReport(human,recvMsg.msg)
    return true
end

function  sendChatByTestGm(human)
	local str = "test chat okokok"
	chat(human, {msgType = ChatHandler.CHAT_TYPE_WORLD,msg = str},false, false)
end

function getCombatName(combatType, name)
	return Util.format(Lang.COMBAT_CHAT_MSG, name)
end

function isDot(human)
    if ChatRecord.CHAT_RECORD_FRIEND[human.db._id] and ChatRecord.CHAT_RECORD_FRIEND[human.db._id].count ~= 0 then 
        return true
    end
end

-- 跨服消息到达
function WL_MIDDLE_CHAT(fd, msg)
    Msg.sendWorld(msg.tChatMsg)
    ChatRecord.addMiddleRecord(msg.tChatMsg.item, msg.tChatMsg.item.msgType)
end