local WorldFavoDataManager = BaseClass("WorldFavoDataManager")
local AllianceWorldMark = require("Scene.AllianceWorldMark.AllianceWorldMark")
local WorldBookMarkItem = require("DataCenter.WorldFavoData.WorldBookMarkItem")
local ResourceManager = CS.GameEntry.Resource
local Localization = CS.GameEntry.Localization
local TranslateManager = require("DataCenter.MailData.MailTranslateManager")
local BookMarkTemplate = require("DataCenter.WorldFavoData.BookMarkTemplate")
local __init = function(self)
  self.personalMarkDatas = {}
  self.allianceMarkDatas = {}
  self.allianceMarkGoDic = {}
  self.allianceMarkReqDic = {}
  self.personalMarkGoDic = {}
  self.lastGotoPos = ""
  self.lastTab = 0
  self.templateDic = nil
  self:AddListener()
  self:InitAllTemplate()
end
local __delete = function(self)
  self:ClearAll()
  self.personalMarkDatas = {}
  self.allianceMarkDatas = {}
  self.allianceMarkGoDic = {}
  self.allianceMarkReqDic = {}
  self.personalMarkGoDic = {}
  self.lastGotoPos = nil
  self.lastTab = nil
  self.Translate = nil
  self.templateDic = nil
  self:RemoveListener()
end
local InitData = function(self)
  SFSNetwork.SendMessage(MsgDefines.WorldFavoGet, 0)
  SFSNetwork.SendMessage(MsgDefines.WorldGetAllianceMark)
end
local AddListener = function(self)
  EventManager:GetInstance():AddListener(EventId.PveLevelEnter, self.OnExitWorld)
  EventManager:GetInstance():AddListener(EventId.PveLevelExit, self.OnEnterWorld)
  EventManager:GetInstance():AddListener(EventId.OnEnterCrossServer, self.OnRefreshMark)
  EventManager:GetInstance():AddListener(EventId.OnQuitCrossServer, self.OnRefreshMark)
  EventManager:GetInstance():AddListener(EventId.OnEnterWorld, self.OnEnterWorld)
  EventManager:GetInstance():AddListener(EventId.OnEnterCity, self.OnExitWorld)
  EventManager:GetInstance():AddListener(EventId.WorldAllianceMarkTranslateFinish, self.OnWorldTranslateFinish)
end
local RemoveListener = function(self)
  EventManager:GetInstance():RemoveListener(EventId.PveLevelEnter, self.OnExitWorld)
  EventManager:GetInstance():RemoveListener(EventId.PveLevelExit, self.OnEnterWorld)
  EventManager:GetInstance():RemoveListener(EventId.OnEnterCrossServer, self.OnRefreshMark)
  EventManager:GetInstance():RemoveListener(EventId.OnQuitCrossServer, self.OnRefreshMark)
  EventManager:GetInstance():RemoveListener(EventId.OnEnterWorld, self.OnEnterWorld)
  EventManager:GetInstance():RemoveListener(EventId.OnEnterCity, self.OnExitWorld)
  EventManager:GetInstance():RemoveListener(EventId.WorldAllianceMarkTranslateFinish, self.OnWorldTranslateFinish)
end
local ClearAll = function(self)
  self:ClearAllAllianceMarksView()
  self:ClearAllWorldBookmark()
end
local InitAllTemplate = function(self)
  self.templateDic = {}
  LocalController:instance():visitTable(TableName.LW_AllianceMark, function(id, lineData)
    local item = BookMarkTemplate.New()
    item:InitData(lineData)
    self.templateDic[item.type] = item
  end)
end

function WorldFavoDataManager.OnWorldTranslateFinish(markData)
  local self = DataCenter.WorldFavoDataManager
  for markType, v in pairs(self.allianceMarkGoDic) do
    if markType == markData.type then
      self.allianceMarkGoDic[markType]:OnTranslateFinish(markData)
      markData:SetTranslateFinishState(1)
      break
    end
  end
end

local InitBookmarkDict = function(self, message)
  self.personalMarkDatas = {}
  if message.favo ~= nil then
    local favoList = message.favo
    table.walk(favoList, function(k, v)
      local oneData = BookMark.New()
      oneData:ParseData(v)
      if oneData.server > 0 and 0 < oneData.pos then
        local key = oneData.server * 100000000 + oneData.pos
        self.personalMarkDatas[key] = oneData
      end
    end)
  end
end
local TryAddAllianceMask = function(self, point, server, markType, name, delayTime, notice, param)
  SFSNetwork.SendMessage(MsgDefines.WorldAddAllianceMark, point, server, markType, name, delayTime, notice, param)
end
local TryDelAllianceMask = function(self, markType)
  SFSNetwork.SendMessage(MsgDefines.WorldDelAllianceMark, markType)
end
local OnInitAllianceMarkDic = function(self, message)
  self:ClearAllAllianceMarksView()
  self.allianceMarkDatas = {}
  if not self.Translate then
    self.Translate = TranslateManager.New()
  end
  if message.markInfoArr then
    for i, v in ipairs(message.markInfoArr) do
      local newOne = AllianceMarkData.New()
      newOne:SetTranslateHandler(self.Translate)
      newOne:ParseData(v)
      if newOne.server > 0 and 0 < newOne.pos then
        local k = newOne.type
        if k == MarkType.Alliance_rally then
          DataCenter.AllianceRallyPointDataManager:OnInitSelfRallyPoint(v)
        elseif k == MarkType.Alliance_OtherServerRally then
          DataCenter.AllianceRallyPointDataManager:OnInitOtherServerRallyPoint(v)
        else
          self.allianceMarkDatas[k] = newOne
          if self:IsShow(newOne) then
            self:CreateAllianceMarkOnMap(newOne.type)
          end
        end
      end
    end
  end
end
local HandleAddAllianceMarkMessage = function(self, msg)
  if msg.markInfo then
    if not self.Translate then
      self.Translate = TranslateManager.New()
    end
    local newOne = AllianceMarkData.New()
    newOne:ParseData(msg.markInfo)
    newOne:SetTranslateHandler(self.Translate)
    if newOne.server > 0 and 0 < newOne.pos then
      local k = newOne.type
      if AllianceRallyType[k] then
        DataCenter.AllianceRallyPointDataManager:OnAddRallyPoint(msg.markInfo)
        return false
      else
        self.allianceMarkDatas[k] = newOne
        if self:IsShow(newOne) then
          self:CreateAllianceMarkOnMap(k)
        end
      end
      return true
    end
  end
end
local OnDelAllianceMark = function(self, msg)
  if msg.markInfo then
    if msg.markInfo.markType == MarkType.Alliance_rally or msg.markInfo.markType == MarkType.Alliance_OtherServerRally then
      DataCenter.AllianceRallyPointDataManager:DeleteOneRallyPoint(msg.markInfo.markType)
      return false
    else
      self:DelAllianceMarkOnMap(msg.markInfo.markType)
      self.allianceMarkDatas[msg.markInfo.markType] = nil
      return true
    end
  end
end
local OnAddAllianceMarkPush = function(self, msg)
  local isAllianceMark = self:HandleAddAllianceMarkMessage(msg)
  if isAllianceMark == true and msg.userInfo then
    UIUtil.ShowTips(Localization:GetString("390818", msg.userInfo.name))
  end
end
local OnDelAllianceMarkPush = function(self, msg)
  local isAllianceMark = self:OnDelAllianceMark(msg)
  if isAllianceMark and msg.userInfo then
    UIUtil.ShowTips(Localization:GetString("390819", msg.userInfo.name))
  end
end

function WorldFavoDataManager:ClearAllianceMarks()
  self:ClearAllAllianceMarksView()
  self.allianceMarkDatas = {}
end

local ClearAllAllianceMarksView = function(self)
  for i, v in pairs(self.allianceMarkGoDic) do
    v:Destroy()
  end
  self.allianceMarkGoDic = {}
  for i, v in pairs(self.allianceMarkReqDic) do
    v:Destroy()
  end
  self.allianceMarkReqDic = {}
end
local DelAllianceMarkOnMap = function(self, tempType)
  if self.allianceMarkGoDic and self.allianceMarkGoDic[tempType] then
    self.allianceMarkGoDic[tempType]:Destroy()
    self.allianceMarkGoDic[tempType] = nil
  end
  if self.allianceMarkReqDic and self.allianceMarkReqDic[tempType] then
    self.allianceMarkReqDic[tempType]:Destroy()
    self.allianceMarkReqDic[tempType] = nil
  end
end
local CreateAllianceMarkOnMap = function(self, tempType)
  if not CS.SceneManager:IsInWorld() then
    return
  end
  if self.allianceMarkDatas and self.allianceMarkDatas[tempType] then
    local markInfo = self.allianceMarkDatas[tempType]
    if not self.allianceMarkReqDic[tempType] then
      local request = ResourceManager:InstantiateAsync(DataCenter.WorldFavoDataManager:GetBookMarkPrefabPath(tempType))
      self.allianceMarkReqDic[tempType] = request
      request:completed("+", function()
        if self.allianceMarkDatas[tempType] == nil then
          request:Destroy()
        elseif self.allianceMarkGoDic[tempType] or not CS.SceneManager:IsInWorld() then
          Logger.LogInfo("[FavPoint]Too late... Destroy request")
          request:Destroy()
        else
          self.allianceMarkGoDic[tempType] = nil
          if request.isError then
            return
          end
          request.gameObject:SetActive(true)
          request.gameObject.transform:SetParent(CS.SceneManager.World.DynamicObjNode)
          request.gameObject.transform:Set_localScale(ResetScale.x, ResetScale.y, ResetScale.z)
          request.gameObject.name = "AllianceMark_" .. tempType
          local newAllianceMark = AllianceWorldMark.New()
          newAllianceMark:OnCreate(request)
          self.allianceMarkGoDic[tempType] = newAllianceMark
          self.allianceMarkGoDic[tempType]:ShowMark(markInfo)
        end
      end)
    elseif self.allianceMarkGoDic[tempType] then
      self.allianceMarkGoDic[tempType]:ShowMark(markInfo)
    end
  end
end
local CheckIfAllianceMarkInUse = function(self, tempType)
  return self.allianceMarkDatas and self.allianceMarkDatas[tempType]
end
local CheckIfPointInUse = function(self, pos)
  for i, v in pairs(self.allianceMarkDatas) do
    if v.pos == pos then
      return true
    end
  end
  return false
end
local AddBookmark = function(self, point, server, name, type, topFlag, param)
  SFSNetwork.SendMessage(MsgDefines.WorldFavoAdd, name, point, type, server, topFlag, 0, 1, param)
end

function WorldFavoDataManager:AddBookmarkSucceed(message)
  local oneData = BookMark.New()
  oneData.pos = message.point
  oneData.server = message.server
  oneData.name = message.name
  oneData.type = message.type
  oneData.topFlag = message.topFlag
  oneData.pointInfo = message.pointInfo
  if oneData.server > 0 and oneData.pos > 0 then
    local key = oneData.server * 100000000 + oneData.pos
    self.personalMarkDatas[key] = oneData
  end
end

local UpdateBookmark = function(self, point, server, createTime)
  local key = server * 100000000 + point
  if self.personalMarkDatas[key] ~= nil then
    self.personalMarkDatas[key].createTime = createTime
    self:CreateWorldBookmark(self.personalMarkDatas[key])
  end
end
local DelBookmark = function(self, point, server)
  local key = server * 100000000 + point
  if self.personalMarkDatas[key] ~= nil then
    self.personalMarkDatas[key] = nil
  end
  self:RemoveWorldBookmark(key)
end
local DelBookmarkByType = function(self, type)
  local keysToRemove = {}
  for k, v in pairs(self.personalMarkDatas) do
    if v.type == type then
      table.insert(keysToRemove, k)
    end
  end
  for _, k in ipairs(keysToRemove) do
    self.personalMarkDatas[k] = nil
    self:RemoveWorldBookmark(k)
  end
end
local GetBookmark = function(self, point, server, onlySelf)
  local targetP = point - point % 10
  local data
  local key = server * 100000000 + targetP
  for i, v in pairs(self.personalMarkDatas) do
    local tempPoint = i - i % 10
    if tempPoint == key then
      data = v
      break
    end
  end
  if onlySelf then
    return data
  end
  if not data and self.allianceMarkDatas then
    for i, v in pairs(self.allianceMarkDatas) do
      if v.pos == point and v.server == server then
        data = v
        break
      end
    end
  end
  return data
end
local GetAllianceBookmark = function(self, point, server)
  local data
  if self.allianceMarkDatas then
    for i, v in pairs(self.allianceMarkDatas) do
      if v.pos == point and v.server == server then
        data = v
        break
      end
    end
  end
  return data
end
local GetAllianceBookmarkByType = function(self, type, server)
  local data
  if self.allianceMarkDatas then
    data = self.allianceMarkDatas[type]
    if data and data.server == server then
      return data
    end
  end
  return data
end
local GetBookListByType = function(self, type)
  local showList = {}
  if type == MarkType.Special or type == MarkType.Friend or type == MarkType.Enemy then
    table.walk(self.personalMarkDatas, function(k, v)
      if v.type == type then
        showList[k] = v
      end
    end)
  else
    showList = self.allianceMarkDatas
  end
  return showList
end
local GetAllianceBookmarkUnusedType = function(self)
  if self.allianceMarkDatas then
    for i = MarkType.Alliance_Attack, MarkType.Alliance_17 do
      if not self.allianceMarkDatas[i] then
        return i
      end
    end
  end
  return MarkType.Alliance_Attack
end
local GetAllBookList = function(self)
  return self.personalMarkDatas
end
local GetLastGotoPos = function(self)
  return self.lastGotoPos
end
local SetLastGotoPos = function(self, posStr)
  self.lastGotoPos = posStr
end
local SetLastTab = function(self, tab)
  self.lastTab = tab
end
local GetLastTab = function(self)
  return self.lastTab
end
local OnExitWorld = function()
  DataCenter.WorldFavoDataManager:ClearAll()
end
local OnEnterWorld = function()
  if BattleFieldUtil.InBattleField() then
    return
  end
  if not CS.SceneManager:IsInWorld() then
    return
  end
  local self = DataCenter.WorldFavoDataManager
  self.curServerId = LuaEntry.Player:GetCurServerId()
  self:CreateAllAllianceMark()
  self:CreateAllWorldBookmark()
end
local OnRefreshMark = function()
  local self = DataCenter.WorldFavoDataManager
  if self.curServerId and SeasonUtil.IsInSameMap(self.curServerId, ServerEnum.View) then
    return
  end
  self.curServerId = LuaEntry.Player:GetCurServerId()
  self:ClearAll()
  if CS.SceneManager:IsInWorld() and not BattleFieldUtil.InBattleField() then
    self:CreateAllAllianceMark()
    self:CreateAllWorldBookmark()
  end
end

function WorldFavoDataManager:IsShow(markData)
  if markData.server <= 0 or 0 >= markData.pos then
    return false
  end
  return SeasonUtil.IsInSameMap(markData.server, ServerEnum.View)
end

function WorldFavoDataManager:CreateAllAllianceMark()
  for k, v in pairs(self.allianceMarkDatas) do
    if self:IsShow(v) then
      self:CreateAllianceMarkOnMap(k)
    end
  end
end

local CreateAllWorldBookmark = function(self)
  for i, v in pairs(self.personalMarkDatas) do
    if self:IsShow(v) then
      self:CreateWorldBookmark(v)
    end
  end
end
local CreateWorldBookmark = function(self, bookMark)
  if bookMark then
    local key = bookMark.server * 100000000 + bookMark.pos
    local item = self.personalMarkGoDic[key]
    if not item then
      item = WorldBookMarkItem.New()
      self.personalMarkGoDic[key] = item
    end
    item:Load(bookMark)
  end
end
local RemoveWorldBookmark = function(self, key)
  local item = self.personalMarkGoDic[key]
  if item then
    item:Unload()
    self.personalMarkGoDic[key] = nil
  end
end
local ClearAllWorldBookmark = function(self)
  local allBookMark = self.personalMarkGoDic
  for i, v in pairs(allBookMark) do
    v:Unload()
  end
  self.personalMarkGoDic = {}
end
local GetBookMarkName = function(self, markType, isTranslate)
  local name
  if self.templateDic then
    name = self.templateDic[markType] and self.templateDic[markType].name
    if name then
      if name == "" then
        return name
      end
      return isTranslate and Localization:GetString(name) or name
    end
  end
  name = AllianceMarkName[markType] or ""
  if name == "" then
    return name
  end
  return isTranslate and Localization:GetString(name) or name
end
local GetBookMarkIconName = function(self, markType)
  if self.templateDic then
    local icon = self.templateDic[markType] and self.templateDic[markType].icon
    if icon then
      return icon
    end
  end
  return AllianceMarkIconName[markType] or ""
end
local GetBookMapMarkIconName = function(self, markType)
  if self.templateDic then
    local icon = self.templateDic[markType] and self.templateDic[markType].mail_icon
    if icon then
      return icon
    end
  end
  return AllianceMapMarkIconName[markType] or ""
end
local GetBookMarkPrefabPath = function(self, markType)
  if self.templateDic then
    local prefabPath = self.templateDic[markType] and self.templateDic[markType].prefab
    if prefabPath then
      return prefabPath
    end
  end
  return AllianceMarkPrefabPath[markType] or ""
end
local GetBookMarkDefaultName = function(self, markType)
  if self.templateDic then
    local defaultName = self.templateDic[markType] and self.templateDic[markType].text
    if not string.IsNullOrEmpty(defaultName) then
      return defaultName
    end
  end
end
local GetBookMarkNameLength = function(self)
  local maxLength = LuaEntry.DataConfig:TryGetStr("alliance_mark", "k1", 50)
  maxLength = maxLength and tonumber(maxLength)
  return maxLength
end
local CheckBookMarkNameLength = function(self, name)
  if string.IsNullOrEmpty(name) then
    return true
  end
  local maxLength = self:GetBookMarkNameLength()
  if maxLength < string.len(name) then
    UIUtil.ShowTips(Localization:GetString("alliance_tag_opt_UI_6", maxLength))
    return false
  end
  return true
end
WorldFavoDataManager.__init = __init
WorldFavoDataManager.InitData = InitData
WorldFavoDataManager.__delete = __delete
WorldFavoDataManager.AddListener = AddListener
WorldFavoDataManager.RemoveListener = RemoveListener
WorldFavoDataManager.InitBookmarkDict = InitBookmarkDict
WorldFavoDataManager.AddBookmark = AddBookmark
WorldFavoDataManager.UpdateBookmark = UpdateBookmark
WorldFavoDataManager.DelBookmark = DelBookmark
WorldFavoDataManager.DelBookmarkByType = DelBookmarkByType
WorldFavoDataManager.GetBookmark = GetBookmark
WorldFavoDataManager.GetBookListByType = GetBookListByType
WorldFavoDataManager.GetLastGotoPos = GetLastGotoPos
WorldFavoDataManager.SetLastGotoPos = SetLastGotoPos
WorldFavoDataManager.GetAllBookList = GetAllBookList
WorldFavoDataManager.OnInitAllianceMarkDic = OnInitAllianceMarkDic
WorldFavoDataManager.TryAddAllianceMask = TryAddAllianceMask
WorldFavoDataManager.TryDelAllianceMask = TryDelAllianceMask
WorldFavoDataManager.HandleAddAllianceMarkMessage = HandleAddAllianceMarkMessage
WorldFavoDataManager.OnDelAllianceMark = OnDelAllianceMark
WorldFavoDataManager.OnAddAllianceMarkPush = OnAddAllianceMarkPush
WorldFavoDataManager.OnDelAllianceMarkPush = OnDelAllianceMarkPush
WorldFavoDataManager.CreateAllianceMarkOnMap = CreateAllianceMarkOnMap
WorldFavoDataManager.DelAllianceMarkOnMap = DelAllianceMarkOnMap
WorldFavoDataManager.CheckIfAllianceMarkInUse = CheckIfAllianceMarkInUse
WorldFavoDataManager.CheckIfPointInUse = CheckIfPointInUse
WorldFavoDataManager.ClearAllAllianceMarksView = ClearAllAllianceMarksView
WorldFavoDataManager.SetLastTab = SetLastTab
WorldFavoDataManager.GetLastTab = GetLastTab
WorldFavoDataManager.OnExitWorld = OnExitWorld
WorldFavoDataManager.OnEnterWorld = OnEnterWorld
WorldFavoDataManager.OnRefreshMark = OnRefreshMark
WorldFavoDataManager.CreateAllWorldBookmark = CreateAllWorldBookmark
WorldFavoDataManager.CreateWorldBookmark = CreateWorldBookmark
WorldFavoDataManager.RemoveWorldBookmark = RemoveWorldBookmark
WorldFavoDataManager.GetAllianceBookmark = GetAllianceBookmark
WorldFavoDataManager.ClearAllWorldBookmark = ClearAllWorldBookmark
WorldFavoDataManager.ClearAll = ClearAll
WorldFavoDataManager.InitAllTemplate = InitAllTemplate
WorldFavoDataManager.GetBookMarkName = GetBookMarkName
WorldFavoDataManager.GetBookMarkIconName = GetBookMarkIconName
WorldFavoDataManager.GetBookMapMarkIconName = GetBookMapMarkIconName
WorldFavoDataManager.GetBookMarkPrefabPath = GetBookMarkPrefabPath
WorldFavoDataManager.GetBookMarkDefaultName = GetBookMarkDefaultName
WorldFavoDataManager.GetAllianceBookmarkByType = GetAllianceBookmarkByType
WorldFavoDataManager.GetAllianceBookmarkUnusedType = GetAllianceBookmarkUnusedType
WorldFavoDataManager.GetBookMarkNameLength = GetBookMarkNameLength
WorldFavoDataManager.CheckBookMarkNameLength = CheckBookMarkNameLength
return WorldFavoDataManager
