local LWNewsCenterManager = BaseClass("LWNewsCenterManager")
local NewsCenterData = require("DataCenter.LWNewsCenterManager.NewsCenterData")
local cd = 30000
local Localization = CS.GameEntry.Localization
local languageConfig = {
  [Language.English] = "en-us",
  [Language.Arabic] = "ar",
  [Language.German] = "de",
  [Language.French] = "fr",
  [Language.Japanese] = "ja",
  [Language.Korean] = "ko-kr",
  [Language.ChineseTraditional] = "zh-tw"
}

function LWNewsCenterManager:__init()
end

function LWNewsCenterManager:__delete()
  CS.ZendeskSupportView.Close()
end

function LWNewsCenterManager:InitData()
  self.infos = nil
  self.newsDataDic = {}
  self.newsAdd = {}
  self.maxNewsUidDic = {}
  self.cacheNewsInfo = {}
  self.reset = false
  SFSNetwork.SendMessage(MsgDefines.GetNewsInfo)
end

function LWNewsCenterManager:Startup()
end

function LWNewsCenterManager:OnGetNewsInfo(infos)
  if not infos or #infos == 0 then
    return
  end
  self.infos = {}
  for i, info in pairs(infos) do
    info.key = info.bigType .. "_" .. info.smallType .. "_" .. info.createTime
    info.prefKey = "NEWS_NEW_MARK_" .. info.uuid
    info.isNew = CommonUtil.PlayerPrefsGetInt(info.prefKey, 0) == 0
    
    function info:SetRead()
      if self.isNew then
        CommonUtil.PlayerPrefsSetInt(self.prefKey, 1)
        self.isNew = false
      end
    end
    
    table.insert(self.infos, info)
  end
end

function LWNewsCenterManager:OnPushNewNews(info)
  if not info then
    return
  end
  if not self.infos then
    self.infos = {}
  end
  local capacity = LuaEntry.DataConfig:TryGetNum("news_setting", "k1", 30)
  while capacity <= #self.infos do
    table.remove(self.infos, #self.infos)
  end
  info.key = info.bigType .. "_" .. info.smallType .. "_" .. info.createTime
  info.prefKey = "NEWS_NEW_MARK_" .. info.uuid
  info.isNew = CommonUtil.PlayerPrefsGetInt(info.prefKey, 0) == 0
  
  function info:SetRead()
    if self.isNew then
      CommonUtil.PlayerPrefsSetInt(self.prefKey, 1)
      self.isNew = false
    end
  end
  
  table.insert(self.infos, 1, info)
end

function LWNewsCenterManager:OnNewsLiked(newsUuid, likeNum)
  if not self.infos then
    return
  end
  for _, info in ipairs(self.infos) do
    if info.uuid == newsUuid then
      info.likeNum = likeNum
      EventManager:GetInstance():Broadcast(ChatEventEnum.CHAT_NEWSCENTER_UPLIKECOUNT, info)
      break
    end
  end
end

local Tab = {Zone = 1, Alliance = 2}

function LWNewsCenterManager:GetFirstUnreadNews()
  local firstUnreadNews
  local infos = DataCenter.LWNewsCenterManager:FilterNews(Tab.Zone)
  if infos then
    for _, info in ipairs(infos) do
      if info.isNew then
        firstUnreadNews = info
        break
      end
    end
  end
  return firstUnreadNews
end

function LWNewsCenterManager:ChangeMainBubbleState(isOn)
  if self.showBubble ~= isOn then
    self.showBubble = isOn
    EventManager:GetInstance():Broadcast(EventId.CHAT_NEWSCENTER_BUBBLESTATE_UPDATA)
  end
end

function LWNewsCenterManager:GetIsShowBubble()
  return self.showBubble
end

function LWNewsCenterManager:GetRedDontCount()
  local infos = DataCenter.LWNewsCenterManager:FilterNews(Tab.Zone)
  local count = 0
  if infos then
    for _, info in ipairs(infos) do
      if info.isNew then
        count = count + 1
      end
    end
  end
  return count
end

local __FilterPersonalBattleNews = function(info, tab)
  local player = LuaEntry.Player
  if tab == Tab.Zone then
    return player.serverId == info.dataObj.atk.user.serverId or player.serverId == info.dataObj.def.user.serverId
  elseif tab == Tab.Alliance then
    return (player.serverId == info.dataObj.atk.user.serverId or player.serverId == info.dataObj.def.user.serverId) and (player.allianceId == info.dataObj.atk.user.alId or player.allianceId == info.dataObj.def.user.alId)
  else
    return false
  end
end
local __FilterAllianceBattleNews = function(info, tab)
  local player = LuaEntry.Player
  if tab == Tab.Zone then
    return player.serverId == info.dataObj.side1.serverId or player.serverId == info.dataObj.side2.serverId
  elseif tab == Tab.Alliance then
    return (player.serverId == info.dataObj.side1.serverId or player.serverId == info.dataObj.side2.serverId) and (player.allianceId == info.dataObj.side1.allianceId or player.allianceId == info.dataObj.side2.allianceId)
  else
    return false
  end
end
local __FilterOccupyCityNews = function(info, tab)
  local player = LuaEntry.Player
  if tab == Tab.Zone then
    return player.serverId == info.dataObj.atk.serverId or player.serverId == info.dataObj.def.serverId
  elseif tab == Tab.Alliance then
    return (player.serverId == info.dataObj.atk.serverId or player.serverId == info.dataObj.def.serverId) and (player.allianceId == info.dataObj.atk.alId or player.allianceId == info.dataObj.def.alId)
  else
    return false
  end
end
local __FilterAppointOfficalNews = function(info, tab)
  local player = LuaEntry.Player
  if tab == Tab.Zone then
    return player.serverId == info.dataObj.king.serverId or info.dataObj.target and player.serverId == info.dataObj.target.serverId
  elseif tab == Tab.Alliance then
    return (player.serverId == info.dataObj.king.serverId or info.dataObj.target and player.serverId == info.dataObj.target.serverId) and (player.allianceId == info.dataObj.king.allianceId or info.dataObj.target and player.allianceId == info.dataObj.target.allianceId)
  else
    return false
  end
end
local __FilterTrainRobNews = function(info, tab)
  local player = LuaEntry.Player
  if tab == Tab.Zone then
    return player.serverId == info.dataObj.serverId
  elseif tab == Tab.Alliance then
    return player.serverId == info.dataObj.serverId and player.allianceId == info.dataObj.allianceId
  else
    return false
  end
end
local __FilterArenaChampionNews = function(info, tab)
  if not info.dataObj.serverArr then
    info.dataObj.allianceId = tonumber(info.dataObj.allianceId) or 0
    info.dataObj.serverArr = {
      tonumber(info.dataObj.serverId) or 0
    }
    info.dataObj.serverArrStr = "#" .. info.dataObj.serverId
    local otherServerIdArr = string.split(info.dataObj.otherServerId, "|")
    for i, otherServerId in ipairs(otherServerIdArr) do
      if not string.IsNullOrEmpty(otherServerId) then
        table.insert(info.dataObj.serverArr, tonumber(otherServerId) or 0)
        info.dataObj.serverArrStr = info.dataObj.serverArrStr .. " #" .. otherServerId
      end
    end
  end
  local player = LuaEntry.Player
  if tab == Tab.Zone then
    return table.indexof(info.dataObj.serverArr, player.serverId)
  elseif tab == Tab.Alliance then
    return table.indexof(info.dataObj.serverArr, player.serverId) and player.allianceId == info.dataObj.allianceId
  else
    return false
  end
end
local __FilterFuncs = {
  [NewsSubType.PERSONAL_BATTLE] = __FilterPersonalBattleNews,
  [NewsSubType.ALLIANCE_BATTLE] = __FilterAllianceBattleNews,
  [NewsSubType.ALLIANCE_ATK_ALLIANCE_CITY] = __FilterOccupyCityNews,
  [NewsSubType.APPOINT_OFFICAL] = __FilterAppointOfficalNews,
  [NewsSubType.TRAIN_ROB] = __FilterTrainRobNews,
  [NewsSubType.ARENA_CHAMPION] = __FilterArenaChampionNews
}

function LWNewsCenterManager:FilterNews(tab)
  if self.infos == nil then
    return {}
  end
  local infos = {}
  for _, info in pairs(self.infos) do
    local filterFunc = __FilterFuncs[info.smallType]
    if filterFunc and filterFunc(info, tab) then
      table.insert(infos, info)
    end
  end
  return infos
end

function LWNewsCenterManager:InitNewsCenter(reset)
  self.reset = reset
  ChatManager2:GetInstance().Net:SendSFSMessage(ChatMsgDefines.NewsCenterInit)
end

function LWNewsCenterManager:UpdateNewsCenterLike(data)
  if data.type and data.uuid then
    local newsData = self:GetNewsData(data.type, data.uuid)
    if newsData then
      newsData:UpLikeCount()
      EventManager:GetInstance():Broadcast(ChatEventEnum.CHAT_NEWSCENTER_UPLIKECOUNT, newsData)
    end
  end
end

function LWNewsCenterManager:GetServerNews(type)
  local newsDataList = self:GetNewsCenterInfoListByType(type)
  local priority = 0
  if newsDataList and 0 < #newsDataList then
    priority = newsDataList[#newsDataList].priority
  end
  ChatManager2:GetInstance().Net:SendSFSMessage(ChatMsgDefines.GetNewCenter, type, priority)
end

function LWNewsCenterManager:InitNewsCenterDatas(serverData)
  if not serverData then
    return
  end
  for i, data in pairs(serverData) do
    self:UpdateNewsCenter(data)
  end
  if not self.reset then
    local isNew = self:GetNewsRed() and true or false
    self:ChangeMainBubbleState(isNew)
  end
  EventManager:GetInstance():Broadcast(ChatEventEnum.CHAT_NEWSCENTER_INIT)
end

function LWNewsCenterManager:UpdateNewsCenter(serverData)
  local newsType = serverData.type
  if not self.newsDataDic[newsType] then
    self.newsDataDic[newsType] = {}
  end
  local newsData
  local dataList = serverData.news
  for i = 1, #dataList do
    newsData = NewsCenterData.New(self)
    newsData:onParseServerData(dataList[i])
    if newsData.uuid then
      self.newsDataDic[newsType][newsData.uuid] = newsData
      if not self.maxNewsUidDic[newsType] then
        self.maxNewsUidDic[newsType] = newsData.uuid
      elseif newsData.uuid > self.maxNewsUidDic[newsType] then
        self.maxNewsUidDic[newsType] = newsData.uuid
      end
    end
  end
  if 0 < #dataList then
    EventManager:GetInstance():Broadcast(ChatEventEnum.CHAT_NEWSCENTER_UPDATA, newsType)
  end
end

function LWNewsCenterManager:SortListByDic(dic)
  local dataList = {}
  for uid, data in pairs(dic) do
    if data:IsCanShow() then
      table.insert(dataList, data)
    end
  end
  table.sort(dataList, function(a, b)
    if a.priority > b.priority then
      return true
    end
  end)
  return dataList
end

function LWNewsCenterManager:GetNewsData(tabType, uid)
  if not (tabType and uid) or not self.newsDataDic[tabType] then
    return
  end
  return self.newsDataDic[tabType][uid]
end

function LWNewsCenterManager:GetNewsCenterInfoListByType(newsType)
  if self.newsDataDic[newsType] then
    return self:SortListByDic(self.newsDataDic[newsType]) or {}
  end
end

function LWNewsCenterManager:GetNewsCount(newsType)
  local list = self:GetNewsCenterInfoListByType(newsType)
  local count = 0
  for i, data in pairs(list) do
    if data.isNew then
      count = count + 1
    end
  end
  return count
end

function LWNewsCenterManager:UpdateRed(tabTypeList)
  self.newsAdd = self.newsAdd or {}
  if tabTypeList and 0 < #tabTypeList then
    self:ChangeMainBubbleState(true)
    for i, tabType in pairs(tabTypeList) do
      self.newsAdd[tabType] = true
      EventManager:GetInstance():Broadcast(ChatEventEnum.CHAT_NEWSCENTER_ADDPUSH)
    end
  end
end

function LWNewsCenterManager:GetRed(tabTyp)
  return self.newsAdd and self.newsAdd[tabTyp]
end

function LWNewsCenterManager:SetRedDotId(tabType)
  if tabType and self.maxNewsUidDic[tabType] then
    CommonUtil.PlayerPrefsSetLong("newsCenterRed" .. tabType, self.maxNewsUidDic[tabType])
    self.newsAdd[tabType] = nil
  end
end

function LWNewsCenterManager:GetRedDotId(tabType)
  return CommonUtil.PlayerPrefsGetLong("newsCenterRed" .. tabType, 0)
end

function LWNewsCenterManager:GetRedNew(tabType)
  local dataList = self:GetNewsCenterInfoListByType(tabType)
  if not dataList then
    return
  end
  for i = 1, #dataList do
    if dataList[i].isNew then
      return true
    end
  end
  return self.newsAdd[tabType]
end

function LWNewsCenterManager:GetNewsRed()
  local guid = self:GetRedNew(ChatNewsCenterTabType.StrategyGuide)
  local cement = self:GetRedNew(ChatNewsCenterTabType.Announcement)
  return guid or cement
end

function LWNewsCenterManager:SetUpdateTime()
end

function LWNewsCenterManager:HasAdd()
  return self.newsAdd[ChatNewsCenterTabType.StrategyGuide] or self.newsAdd[ChatNewsCenterTabType.Announcement]
end

function LWNewsCenterManager:GetCacheInfo()
end

function LWNewsCenterManager:UpdateCacheData(uuid, info)
  if uuid and not self.cacheNewsInfo[uuid] then
    if info then
      local newsData = NewsCenterData.New(self)
      newsData:onParseServerData(info)
      self.cacheNewsInfo[info.uuid] = info
    else
      self.cacheNewsInfo[uuid] = false
    end
    EventManager:GetInstance():Broadcast(ChatEventEnum.CHAT_NEWSCENTER_CACHEUPDATE, uuid)
  end
end

function LWNewsCenterManager:GetCacheInfo(uuid, type)
  if self.cacheNewsInfo[uuid] ~= nil then
    return self.cacheNewsInfo[uuid]
  else
    local language = Localization:GetLanguage()
    local abbr = "en"
    for k, v in pairs(SuportedServerLanguagesLocalName) do
      if v == language then
        abbr = k
      end
    end
    ChatManager2:GetInstance().Net:SendMessage(ChatMsgDefines.UserNewsCenter, uuid, type, abbr)
  end
  return nil
end

function LWNewsCenterManager:ResetData()
  self.newsDataDic = {}
  self.newsAdd = {}
  self.maxNewsUidDic = {}
  self:InitNewsCenter(true)
end

function LWNewsCenterManager:GetConfigLanguage(lanKey)
  local language = "en-us"
  if languageConfig[lanKey] then
    language = languageConfig[lanKey]
  end
  return language
end

function LWNewsCenterManager:GetRedDotKey(tabType)
  return "NewsRedDotSetting" .. tabType
end

function LWNewsCenterManager:GetNotRedSetting(tabType)
  return CommonUtil.PlayerPrefsGetBool(self:GetRedDotKey(tabType), true)
end

function LWNewsCenterManager:SetNotRedSetting(tabType, isOn)
  local curSetting = self:GetNotRedSetting(tabType)
  if curSetting ~= isOn then
    CommonUtil.PlayerPrefsSetBool(self:GetRedDotKey(tabType), isOn)
    EventManager:GetInstance():Broadcast(ChatEventEnum.CHAT_NEWSCENTER_REDDOTSETTING_UPDATA)
  end
end

return LWNewsCenterManager
