local this = class("pageChat", G_UIPageBase)
local COLOR_GREY = C_LuaUtility.ParseHtmlStringColor("#8b8c8f")
local COLOR_BLUE = C_LuaUtility.ParseHtmlStringColor("#4ccbff")

function this:ctor(...)
  this.super.ctor(self, ...)
  self.data = {
    selectPlayerUid = nil,
    selectMeetingChat = false,
    textLimitTimer = nil,
    unreadMsgNum = 0
  }
end

function this.bind()
  return {
    txt_name = "",
    txt_mark = "",
    go_chatPanel = false,
    go_empty = false,
    go_addConversationBtn = true,
    go_deleteBtn = false,
    go_chatMask = false,
    go_textLimit = false,
    go_newMsgBtn = false,
    txt_newMsgBtn = "",
    scrollList_chatPlayer = {
      moduleName = "pages/Chat/cellChatPlayer"
    },
    scrollList_message = {},
    focusItemIndex_messageList = 0,
    go_moduleCommonWords = false,
    go_moduleEmoticon = false,
    module_commonWords = {
      moduleName = "pages/Chat/moduleChatCommonWords"
    },
    module_emotion = {
      moduleName = "pages/Chat/moduleChatEmotion"
    },
    go_moduleCreateConversation = false,
    module_createConversation = {
      moduleName = "pages/Chat/moduleCreateConversation"
    },
    color_btnEmotion = COLOR_GREY
  }
end

function this.methods()
  return {
    onClick_close = function(self)
      L_UI:close(self.pageName)
    end,
    onClick_mask = function(self)
      L_UI:close(self.pageName)
    end,
    onClick_chatBoxMask = function(self)
      self.bind.go_moduleCommonWords = false
      self.bind.go_moduleEmoticon = false
      self.bind.color_btnEmotion = COLOR_GREY
      self.bind.go_chatMask = false
    end,
    onClick_menu = function(self)
      local data = {
        txtContent = L_WordsTpl:getValue("notice_chat_2"),
        confirmCallback = function()
          L_ChatStore:req_deleteChatConversation(self.data.selectPlayerUid)
        end
      }
      L_GameUtil.showCommonTip(data)
    end,
    onClick_commonWorlds = function(self)
      self.bind.go_moduleCommonWords = not self.bind.go_moduleCommonWords
      self.bind.go_chatMask = self.bind.go_moduleCommonWords
      self.bind.go_moduleEmoticon = false
      self.bind.color_btnEmotion = self.bind.go_moduleEmoticon and COLOR_BLUE or COLOR_GREY
    end,
    onClick_emotion = function(self)
      self.bind.go_moduleEmoticon = not self.bind.go_moduleEmoticon
      self.bind.color_btnEmotion = self.bind.go_moduleEmoticon and COLOR_BLUE or COLOR_GREY
      self.bind.go_chatMask = self.bind.go_moduleEmoticon
      self.bind.go_moduleCommonWords = false
    end,
    onClick_send = function(self)
      local txt = self.bindComponents.input_text.text
      self.bindComponents.input_text.text = ""
      if string.isEmpty(string.trim(txt)) then
        L_FlyMsgManager:showNormalMsg(L_WordsTpl:getValue("notice_chat_3"))
        return
      end
      txt = string.gsub(txt, "\n", "")
      if self.data.selectPlayerUid then
        L_ChatStore:req_sendChatInfo(self.data.selectPlayerUid, L_Const.ChatInfoType.CHAT_NORMAL, txt, function()
          self.methods.onClick_chatBoxMask(self)
        end)
      end
      if self.data.selectMeetingChat then
        L_ChatStore:req_meetingChat(L_Const.ChatInfoType.CHAT_NORMAL, txt, function()
          self.methods.onClick_chatBoxMask(self)
        end)
      end
    end,
    onClick_newMsg = function(self)
      self.bind.go_newMsgBtn = false
      self.data.unreadMsgNum = 0
      self.bind.focusItemIndex_messageList = #self.bind.scrollList_message
      self.bindComponents.tableView_chat.verticalNormalizedPosition = 0
    end,
    onClick_addConversation = function(self)
      self.bind.go_chatPanel = false
      self.bind.go_empty = false
      self.bind.go_addConversationBtn = false
      self.bindComponents.ani_chat:Play("anim_chatpanel_createconversation_in")
      self.modules.module_createConversation:initModule(function(uid)
        self.data.selectPlayerUid = uid
        self.bindComponents.ani_chat:Play("anim_chatpanel_createconversation_out")
        self.bind.go_addConversationBtn = true
        self.methods.onClick_chatBoxMask(self)
        self:initPlayerList()
        self:initChatBox()
      end)
    end,
    onCellUse_messageList = function(self, value)
      if value >= #self.bind.scrollList_message - 1 then
        self.bind.go_newMsgBtn = false
        self.data.unreadMsgNum = 0
      end
    end,
    scrollList_chatPlayer = {
      onClick_select = function(self, bind)
        if bind.go_active and self.bind.go_addConversationBtn then
          self.methods.onClick_newMsg(self)
        else
          if not self.bind.go_addConversationBtn then
            self.bind.go_addConversationBtn = true
            self.bindComponents.ani_chat:Play("anim_chatpanel_createconversation_out")
          end
          self.data.selectMeetingChat = bind.meeting == true
          self.data.selectPlayerUid = bind.meeting ~= true and bind.serverData.playerUid or nil
          self:setPlayerListActive()
          self:initChatBox()
        end
        self.methods.onClick_chatBoxMask(self)
      end
    },
    onValueChanged_input = function(self, value)
      if C_LuaUtility.StringLength(value) > 50 then
        self.bindComponents.input_text.text = C_LuaUtility.StringSub(value, 0, 50)
        self.bind.go_textLimit = true
        self:closeLimitTimer()
        self.data.textLimitTimer = Timer.once(3, function()
          self.bind.go_textLimit = false
        end, self, self.gameObject)
      end
    end
  }
end

function this:check(options, callback)
  callback(false)
end

function this:preOpen(options)
  this.super.preOpen(self, options)
  self.data.selectPlayerUid = options.uid
  L_ChatManager:getChatPlayerInfo(function()
    L_ChatStore:listenCallFunc(L_ChatStore.event.refreshConversationList, self.onEvent_refreshConversationList, self)
    L_ChatStore:listenCallFunc(L_ChatStore.event.deleteConversation, self.onEvent_deleteConversation, self)
    L_ChatStore:listenCallFunc(L_ChatStore.event.refreshMessage, self.onEvent_refreshMessage, self)
    L_ChatStore:listenCallFunc(L_ChatStore.event.refreshChatShield, self.onEvent_refreshChatShield, self)
    L_ChatStore:listenCallFunc(L_ChatStore.event.clearUnreadNum, self.onEvent_clearUnreadNum, self)
    L_ChatStore:listenCallFunc(L_ChatStore.event.clearMeetingUnreadNum, self.onEvent_clearMeetingUnreadNum, self)
    L_PlayerStore:listenCallFunc(L_PlayerStore.event.refreshBaseInfo, self.onEvent_refreshBaseInfo, self)
    if L_ChatManager:getCurChatType() == L_Const.chatType.meeting then
      L_ChatStore:listenCallFunc(L_ChatStore.event.refreshMeetingMessage, self.onEvent_refreshMeetingMessage, self)
    end
    self:initPage()
  end)
end

function this:close(options)
  this.super.close(self, options)
  L_ChatStore:unListenCallFunc(L_ChatStore.event.refreshConversationList, self.onEvent_refreshConversationList)
  L_ChatStore:unListenCallFunc(L_ChatStore.event.deleteConversation, self.onEvent_deleteConversation)
  L_ChatStore:unListenCallFunc(L_ChatStore.event.refreshMessage, self.onEvent_refreshMessage)
  L_ChatStore:unListenCallFunc(L_ChatStore.event.refreshChatShield, self.onEvent_refreshChatShield)
  L_ChatStore:unListenCallFunc(L_ChatStore.event.clearUnreadNum, self.onEvent_clearUnreadNum)
  L_ChatStore:unListenCallFunc(L_ChatStore.event.clearMeetingUnreadNum, self.onEvent_clearMeetingUnreadNum)
  L_PlayerStore:unListenCallFunc(L_PlayerStore.event.refreshBaseInfo, self.onEvent_refreshBaseInfo)
  if L_ChatManager:getCurChatType() == L_Const.chatType.meeting then
    L_ChatStore:unListenCallFunc(L_ChatStore.event.refreshMeetingMessage, self.onEvent_refreshMeetingMessage)
  end
  self:closeLimitTimer()
end

function this:show()
  L_ShortCutManager:registerShortCut(self.pageName, C_InputManager_KeyType.EPageChatReturn, function()
    if not self.bind.go_chatPanel then
      return
    end
    if self.bindComponents.input_text.isFocused then
      self.methods.onClick_send(self)
    else
      self.bindComponents.input_text:ActivateInputField()
    end
  end)
end

function this:initPage()
  self.bind.go_addConversationBtn = true
  self.bind.go_moduleCreateConversation = false
  self:initPlayerList()
  self:initChatBox()
  self:initAllEmojiInfo()
end

function this:initChatBox()
  local chatValid = self.data.selectMeetingChat or self.data.selectPlayerUid ~= nil
  if self.bind.go_addConversationBtn then
    self.bind.go_chatPanel = chatValid
  end
  self.bind.go_empty = not chatValid
  if chatValid then
    if self.data.selectPlayerUid then
      L_ChatStore:req_getChatInfo(self.data.selectPlayerUid, function()
        local baseInfo = L_FriendStore:getPlayerBaseInfo(self.data.selectPlayerUid)
        self.bind.txt_name = L_FriendStore:getPlayerName(baseInfo)
        local friend = L_FriendStore:getPlayerItem(L_FriendStore:getFriendList(), self.data.selectPlayerUid)
        self.bind.txt_mark = string.isEmpty(friend:getFriendMark()) and "" or string.format("(%s)", friend:getFriendMark())
        self.bind.go_deleteBtn = true
        local conversation = L_ChatStore:getConversation(self.data.selectPlayerUid)
        self:initMessageList(conversation)
      end)
    end
    if self.data.selectMeetingChat then
      self.bind.txt_name = L_WordsTpl:getValue("info_chat_1")
      self.bind.txt_mark = ""
      self.bind.go_deleteBtn = false
      local conversation = L_ChatStore:getMeetingConversation()
      self:initMessageList(conversation)
    end
  else
    self.bind.txt_name = ""
    self.bind.txt_mark = ""
    self.bind.go_chatMask = false
    self.bind.txt_newMsgBtn = ""
    self.bind.go_moduleCommonWords = false
    self.bind.go_moduleEmoticon = false
    self.bind.color_btnEmotion = COLOR_GREY
    self.bind.go_newMsgBtn = false
    self.data.unreadMsgNum = 0
    self.bind.scrollList_message:clear()
    self.bind.focusItemIndex_messageList = 0
  end
end

function this:initPlayerList()
  local conversationList = L_ChatManager:getConversationList()
  local tmp = {}
  for i, v in ipairs(conversationList) do
    if v.conversationType == L_Const.chatType.meeting then
      table.insert(tmp, {
        serverData = v.serverData,
        meeting = true,
        txt_name_active = L_WordsTpl:getValue("info_chat_1"),
        txt_name_normal = L_WordsTpl:getValue("info_chat_1"),
        go_meetingHead_active = true,
        go_meetingHead_normal = true,
        go_head = false
      })
    elseif v.conversationType == L_Const.chatType.personal and v.serverData.playerUid ~= 0 then
      local baseInfo = L_FriendStore:getPlayerBaseInfo(v.serverData.playerUid)
      table.insert(tmp, {
        serverData = v.serverData,
        url_head = L_FriendStore:getPlayerAvatarsHead(baseInfo),
        go_active = false,
        go_normal = false,
        txt_name_active = L_FriendStore:getPlayerName(baseInfo),
        txt_name_normal = L_FriendStore:getPlayerName(baseInfo)
      })
    end
  end
  if 0 < #tmp then
    if not L_ChatStore:getConversation(self.data.selectPlayerUid) then
      local selectConversation = tmp[1]
      self.data.selectMeetingChat = selectConversation.meeting == true
      self.data.selectPlayerUid = selectConversation.meeting ~= true and selectConversation.serverData.playerUid or nil
    else
      self.data.selectMeetingChat = false
    end
  else
    self.data.selectPlayerUid = nil
    self.data.selectMeetingChat = false
  end
  self.bind.scrollList_chatPlayer:clear()
  self.bind.scrollList_chatPlayer:insert_array(tmp)
  self:setPlayerListActive()
end

function this:initAllEmojiInfo()
end

function this:setPlayerListActive()
  for i = 1, #self.bind.scrollList_chatPlayer do
    local active = false
    local item = self.bind.scrollList_chatPlayer:getValue(i)
    if item.meeting and self.data.selectMeetingChat then
      active = true
    end
    if item.serverData and item.serverData.playerUid == self.data.selectPlayerUid then
      active = true
    end
    self.bind.scrollList_chatPlayer:change(i, {
      go_active = active,
      go_normal = not active
    })
  end
end

function this:initMessageList(conversation)
  local msgList = L_ChatStore:getMessageList(conversation)
  local tmp = {}
  local lastMsg
  for i, v in pairs(msgList) do
    if self.data.selectMeetingChat then
      local recordMsg = L_ChatManager:parseSwitchMeetingMsg(lastMsg, v)
      if not table.isEmpty(recordMsg) then
        for i1, v1 in ipairs(recordMsg) do
          table.insert(tmp, v1)
        end
      end
    end
    local timeMsg = L_ChatManager:parseTimeMsg(lastMsg, v)
    if timeMsg then
      table.insert(tmp, timeMsg)
    end
    lastMsg = v
    local msg = L_ChatManager:parseMsg(v)
    table.insert(tmp, msg)
  end
  local lastTime = lastMsg and L_ChatStore:getMessageTime(lastMsg) or 0
  local record = L_ChatStore:getMeetingSwitchLineRecord()
  if self.data.selectMeetingChat then
    for i, v in ipairs(record) do
      if lastTime < v.time then
        table.insert(tmp, L_ChatManager:generateSwitchMeetingMsg(v))
      end
    end
  end
  self.bind.scrollList_message:clear()
  self.bind.scrollList_message:insert_array(tmp)
  self.methods.onClick_newMsg(self)
  if self.data.selectPlayerUid then
    L_ChatStore:req_readChatInfo(self.data.selectPlayerUid)
  end
  if self.data.selectMeetingChat then
    L_ChatStore:clearMeetingUnreadNum()
  end
end

function this:insertNewMsg(message)
  local num = #self.bind.scrollList_message
  local lastMsg = num ~= 0 and self.bind.scrollList_message:getValue(num).serverData or nil
  local timeMsg = L_ChatManager:parseTimeMsg(lastMsg, message)
  if timeMsg then
    self.bind.scrollList_message:insert(timeMsg)
  end
  local msg = L_ChatManager:parseMsg(message)
  self.bind.scrollList_message:insert(msg)
  if self.data.selectPlayerUid then
    L_ChatStore:req_readChatInfo(self.data.selectPlayerUid)
  end
  if self.data.selectMeetingChat then
    L_ChatStore:clearMeetingUnreadNum()
  end
  local count = #self.modules.scrollList_message
  for i, v in pairs(self.modules.scrollList_message) do
    if i == count then
      v:playInitFX()
    end
  end
end

function this:closeLimitTimer()
  if self.data.textLimitTimer == nil then
    return
  end
  self.data.textLimitTimer:destroy()
  self.data.textLimitTimer = nil
end

function this:onEvent_refreshMessage(message)
  if message.id.pid == self.data.selectPlayerUid then
    if self.bindComponents.tableView_chat.verticalNormalizedPosition > 0.001 and not L_ChatStore:getIsMessageSendByMyself(message.chat) then
      self.bind.go_newMsgBtn = true
      self.data.unreadMsgNum = self.data.unreadMsgNum + 1
      self.bind.txt_newMsgBtn = L_WordsTpl:getValue("notice_chat_4", {
        [0] = self.data.unreadMsgNum
      })
      self:insertNewMsg(message.chat)
    else
      self:insertNewMsg(message.chat)
      self.methods.onClick_newMsg(self)
    end
  elseif #self.bind.scrollList_chatPlayer == 0 then
    self:initPage()
  else
    self:initPlayerList()
  end
end

function this:onEvent_refreshMeetingMessage(message)
  local func = function()
    if self.data.selectMeetingChat then
      if self.bindComponents.tableView_chat.verticalNormalizedPosition > 0.001 and not L_ChatStore:getIsMessageSendByMyself(message) then
        self.bind.go_newMsgBtn = true
        self.data.unreadMsgNum = self.data.unreadMsgNum + 1
        self.bind.txt_newMsgBtn = L_WordsTpl:getValue("notice_chat_4", {
          [0] = self.data.unreadMsgNum
        })
        self:insertNewMsg(message)
      else
        self:insertNewMsg(message)
        self.methods.onClick_newMsg(self)
      end
    else
      for i = 1, #self.bind.scrollList_chatPlayer do
        local item = self.bind.scrollList_chatPlayer:getValue(i)
        if item.meeting then
          self.bind.scrollList_chatPlayer:change(i, {
            serverData = L_ChatStore:getMeetingConversation()
          })
        end
        self.bind.scrollList_chatPlayer:change()
      end
    end
  end
  if not L_FriendStore:getPlayerBaseInfo(L_ChatStore:getMessageSender(message)) then
    local types = {
      L_Const.PlayerBasicQueryType.PBQT_NAME,
      L_Const.PlayerBasicQueryType.PBQT_FACE_MINI
    }
    L_FriendManager:requestBaseInfo(types, {
      L_ChatStore:getMessageSender(message)
    }, func)
  else
    func()
  end
end

function this:onEvent_refreshConversationList()
  self:initPlayerList()
end

function this:onEvent_deleteConversation()
  self:initPlayerList()
  self:initChatBox()
end

function this:onEvent_refreshBaseInfo()
  local conversation = {}
  if self.data.selectPlayerUid then
    conversation = L_ChatStore:getConversation(self.data.selectPlayerUid)
  end
  if self.data.selectMeetingChat then
    conversation = L_ChatStore:getMeetingConversation()
  end
  self:initMessageList(conversation)
end

function this:onEvent_refreshChatShield()
  local conversation = {}
  if self.data.selectPlayerUid then
    conversation = L_ChatStore:getConversation(self.data.selectPlayerUid)
  end
  if self.data.selectMeetingChat then
    conversation = L_ChatStore:getMeetingConversation()
  end
  self:initMessageList(conversation)
end

function this:onEvent_clearUnreadNum(playerUid)
  for i = 1, #self.bind.scrollList_chatPlayer do
    local item = self.bind.scrollList_chatPlayer:getValue(i)
    if item.serverData and item.serverData.playerUid == playerUid then
      self.bind.scrollList_chatPlayer:change(i, {
        serverData = L_ChatStore:getConversation(playerUid)
      })
    end
  end
end

function this:onEvent_clearMeetingUnreadNum()
  for i = 1, #self.bind.scrollList_chatPlayer do
    local item = self.bind.scrollList_chatPlayer:getValue(i)
    if item.meeting and self.data.selectMeetingChat then
      self.bind.scrollList_chatPlayer:change(i, {
        serverData = L_ChatStore:getMeetingConversation()
      })
    end
  end
end

return this
