local this = {}
local emojiTpl = L_GameTpl:getChatEmojiTpl()

function this:req_getChatInfo(playerId, callback)
  local conversation = self:getConversation(playerId)
  if self:getIsQeqChatInfo(conversation) then
    if callback then
      callback()
    end
    return
  end
  local baseInfo = L_FriendStore:getPlayerBaseInfo(playerId)
  local data = {
    id = {
      pid = playerId,
      zoneid = L_FriendStore:getPlayerZoneId(baseInfo)
    }
  }
  L_Net:sendMessage(MsgGenCode.CSProtoChatInfoSync, data, function(rspData, errorCode)
    if errorCode == L_Const.errorCode.ErrCodeSucc then
      local entity = self:getConversation(playerId)
      entity.hasReqChat = true
      self:syncConversation(rspData)
      if callback then
        callback()
      end
    end
  end)
end

function this:req_sendChatInfo(playerId, type, chat, callback)
  local baseInfo = L_FriendStore:getPlayerBaseInfo(playerId)
  local data = {
    id = {
      pid = playerId,
      zoneid = L_FriendStore:getPlayerZoneId(baseInfo)
    },
    msg = chat,
    type = type
  }
  L_Net:sendMessage(MsgGenCode.CSProtoAddFriendChat, data, function(rspData, errorCode)
    if errorCode == L_Const.errorCode.ErrCodeSucc then
      if callback then
        callback()
      end
    else
      L_FlyMsgManager:showNormalMsg(L_WordsTpl:getValue("notice_chat_5"))
    end
  end)
end

function this:req_deleteChatConversation(playerId, callback)
  local baseInfo = L_FriendStore:getPlayerBaseInfo(playerId)
  local data = {
    id = {
      pid = playerId,
      zoneid = L_FriendStore:getPlayerZoneId(baseInfo)
    }
  }
  L_Net:sendMessage(MsgGenCode.CSProtoDelFriendChat, data, function(rspData, errorCode)
    if errorCode == L_Const.errorCode.ErrCodeSucc and callback then
      callback()
    end
  end)
end

function this:req_readChatInfo(playerId, callback)
  local conversation = self:getConversation(playerId)
  if self:getUnreadMessageNum(conversation) <= 0 then
    self:clearUnreadNum(playerId)
    return
  end
  local baseInfo = L_FriendStore:getPlayerBaseInfo(playerId)
  local data = {
    id = {
      pid = playerId,
      zoneid = L_FriendStore:getPlayerZoneId(baseInfo)
    }
  }
  L_Net:sendMessage(MsgGenCode.CSProtoReadFriendChat, data, function(rspData, errorCode)
    if errorCode == L_Const.errorCode.ErrCodeSucc then
      self:clearUnreadNum(playerId)
      if callback then
        callback()
      end
    end
  end)
end

function this:req_createConversation(playerId, callback)
  local baseInfo = L_FriendStore:getPlayerBaseInfo(playerId)
  local data = {
    id = {
      pid = playerId,
      zoneid = L_FriendStore:getPlayerZoneId(baseInfo)
    }
  }
  L_Net:sendMessage(MsgGenCode.CSProtoCreateFriendChat, data, function(rspData, errorCode)
    if errorCode == L_Const.errorCode.ErrCodeSucc then
      self:syncConversationUpgrade(playerId, rspData.upgrade)
      if callback then
        callback()
      end
    end
  end)
end

function this:req_shieldChat(playerId, callback)
  local data = {id = playerId}
  L_Net:sendMessage(MsgGenCode.CSProtoAddChatShield, data, function(rspData, errorCode)
    if errorCode == L_Const.errorCode.ErrCodeSucc then
      self.data.shieldList[playerId] = playerId
      self:call(self.event.refreshChatShield)
      if callback then
        callback()
      end
    end
  end)
end

function this:req_unmaskChat(playerId, callback)
  local data = {id = playerId}
  L_Net:sendMessage(MsgGenCode.CSProtoDelChatShield, data, function(rspData, errorCode)
    if errorCode == L_Const.errorCode.ErrCodeSucc then
      self.data.shieldList[playerId] = nil
      self:call(self.event.refreshChatShield)
      if callback then
        callback()
      end
    end
  end)
end

function this:req_meetingChat(type, chat, callback)
  local data = {msg = chat, type = type}
  L_Net:sendMessage(MsgGenCode.CSProtoWorldMapChat, data, function(rspData, errorCode)
    if errorCode == L_Const.errorCode.ErrCodeSucc then
      if callback then
        callback()
      end
    elseif errorCode == L_Const.errorCode.ErrCodeChatCD then
      L_FlyMsgManager:showNormalMsg(L_WordsTpl:getValue("notice_chot_CD"))
    end
  end)
end

function this:req_collectChatEmojiChange(emojiIdList)
  local data = {u32s = emojiIdList}
  L_Net:sendMessage(MsgGenCode.CSProtoCollectChatEmojiChange, data, function(rspData, errorCode)
  end)
end

function this:req_collectChatEmojiDel(emojiCollectedIndexList)
  local data = {u32s = emojiCollectedIndexList}
  L_Net:sendMessage(MsgGenCode.CSProtoCollectChatEmojiDel, data, function(rspData, errorCode)
  end)
end

function this:rsp_syncMeetingChatInfo(data)
  if data.chats ~= nil then
    for i, v in pairs(data.chats) do
      if not self:getIsShieldChat(v.player_id) and not L_FriendStore:getIsBlackList(v.player_id) and self:checkMsgIsValid(v) then
        local entityMsg = require(L_R.store .. "chat.data.chatMessage").new()
        entityMsg.player_id = v.player_id
        entityMsg.msg = v.msg
        entityMsg.time = v.time
        entityMsg.type = v.type
        entityMsg.isMeeting = true
        table.insert(self.data.meetingConversation.chats, entityMsg)
        if #self.data.meetingConversation.chats > 500 then
          for i1 = 1, #self.data.meetingConversation.chats - 500 do
            table.remove(self.data.meetingConversation.chats, i1)
          end
        end
        self.data.meetingConversation.num = math.clamp(self.data.meetingConversation.num + 1, 0, 500)
        self:call(self.event.refreshMeetingMessage, entityMsg)
      end
    end
  end
end

function this:rsp_syncConversationMsgNum(list)
  for _, v in ipairs(list) do
    local entity = self:getConversation(v)
    if entity then
      entity.num = v.cnt
    end
  end
  self:call(self.event.refreshConversationList)
end

function this:rsp_syncConversationList(data)
  for i, v in pairs(data) do
    self:syncConversation(v)
  end
end

function this:syncConversation(data)
  local entity = self:getConversation(data.id.pid, true)
  local chats = entity.chats
  table.merge(entity, data)
  entity.chats = chats
  if table.isEmpty(data.chats) then
    return
  end
  for i, v in pairs(data.chats) do
    if self:checkMsgIsValid(v) then
      local entityMsg = require(L_R.store .. "chat.data.chatMessage").new()
      entityMsg.player_id = v.player_id
      entityMsg.msg = v.msg
      entityMsg.time = v.time
      entityMsg.type = v.type
      table.insert(entity.chats, entityMsg)
    end
  end
  table.sort(entity.chats, function(a, b)
    return a.time < b.time
  end)
end

function this:rsp_syncConversationMessage(data)
  if data.op == 0 then
    local entity = self:getConversation(data.id.pid, true)
    local msgEntity = require(L_R.store .. "chat.data.chatMessage").new()
    msgEntity.player_id = data.chat.player_id
    msgEntity.msg = data.chat.msg
    msgEntity.time = data.chat.time
    msgEntity.type = data.chat.type
    table.insert(entity.chats, msgEntity)
    entity.upgrade = data.upgrade
    if msgEntity.player_id ~= L_PlayerStore:getPlayerId() then
      entity.num = entity.num + 1
      L_AudioUtil.playSESound("message")
    end
    self:call(self.event.refreshMessage, data)
  elseif data.op == 1 then
    self.data.conversationList[data.id.pid] = nil
    self:call(self.event.deleteConversation)
  end
end

function this:rsp_syncShieldList(data)
  for i, v in pairs(data) do
    self.data.shieldList[v] = v
  end
end

function this:rsp_unmarkChat(data)
  self.data.shieldList[data.del] = nil
end

function this:rsp_chatEmojiSync(data)
end

function this:syncConversationUpgrade(uid, time)
  local entity = self:getConversation(uid, true)
  entity.upgrade = time
  self:call(self.event.refreshConversationList)
end

return this
