local this = class("priorityShowQueueManager")
this:importPartialClass(require("ui.manager.priorityShowQueue.priorityShowQueueCheckFuncs"))
local _uiViewTpl = L_GameTpl:getUiViewTpl()

function this:ctor()
  self.uniqueId = 0
  self.isFreeze = true
  self.blockValue = 0
  self.showQueueList = {}
  for _, v in pairs(L_ShowQueueConst.showQueueEnum) do
    self.showQueueList[v] = require("ui.manager.priorityShowQueue.priorityShowQueue").new(self)
  end
  self.ability = C_TagStateManager.CreateState(C_TagStateDefine.PagePopup)
  self.executor = self.ability:GetLuaExecutor()
  
  function self.executor.onExecute(tab)
    self:_open(tab)
  end
end

function this:getUniqueId()
  self.uniqueId = self.uniqueId + 1
  return self.uniqueId
end

function this:initialize()
  L_UI:addListener(L_UI.pageEvent.closed, self.onEvent_closedPage, self)
  L_UI:addListener(L_UI.pageEvent.showed, self.onEvent_showed, self)
  L_GameEventStore:listenCallFunc(L_GameEventStore.event.gameEventSync, self.checkSignInSystem, self)
  L_GameStore:listenCallFunc(L_GameStore.event.enterGame, self.checkSignInSystem, self)
  L_SystemUnlockStore:listenCallFunc(L_SystemUnlockStore.event.updateSystem, self.refreshSystem, self)
  L_FlyMsgManager:addListener(L_FlyMsgManager.event.flyMsgPopupEnd, self.onEvent_flyMsgPopupEnd, self)
  L_BattleManager:addListener(L_BattleManager.event.exitBattle, self.onEvent_exitBattle, self)
  L_BattleManager:addListener(L_BattleManager.event.battleStart, self.onEvent_battleStart, self)
  L_LoadingManager:addListener(L_LoadingManager.event.loadingProgressStart, self.onEvent_loadingStart, self)
  L_LoadingManager:addListener(L_LoadingManager.event.loadingProgressUpdate, self.updateLoading, self)
  L_LoadingManager:addListener(L_LoadingManager.event.loadingProgressEnd, self.onEvent_loadingEnd, self)
  for _, v in pairs(self.showQueueList) do
    v:initialize()
  end
  self:freeze(false)
end

function this:freeze(isFreeze, blockType)
  if blockType then
    if isFreeze then
      self.blockValue = self.blockValue | math.pow(2, blockType)
    else
      self.blockValue = self.blockValue & ~math.pow(2, blockType)
    end
  else
    self.isFreeze = isFreeze
  end
  if not isFreeze then
    self:delayTryDuelPriorityShowData()
  end
end

function this:dispose()
  for _, v in pairs(self.showQueueList) do
    v:dispose(true)
  end
  L_TimerManager:clearTimer(self)
  L_UI:removeListener(L_UI.pageEvent.closed, self.onEvent_closedPage, self)
  L_UI:removeListener(L_UI.pageEvent.showed, self.onEvent_showed, self)
  L_GameEventStore:unListenCallFunc(L_GameEventStore.event.gameEventSync, self.checkSignInSystem)
  L_GameStore:unListenCallFunc(L_GameStore.event.enterGame, self.checkSignInSystem, self)
  L_SystemUnlockStore:unListenCallFunc(L_SystemUnlockStore.event.updateSystem, self.refreshSystem)
  L_FlyMsgManager:removeListener(L_FlyMsgManager.event.flyMsgPopupEnd, self.onEvent_flyMsgPopupEnd)
  L_BattleManager:removeListener(L_BattleManager.event.exitBattle, self.onEvent_exitBattle)
  L_BattleManager:removeListener(L_BattleManager.event.battleStart, self.onEvent_exitBattle)
  L_LoadingManager:removeListener(L_LoadingManager.event.loadingProgressStart, self.onEvent_loadingStart, self)
  L_LoadingManager:removeListener(L_LoadingManager.event.loadingProgressUpdate, self.updateLoading, self)
  L_LoadingManager:removeListener(L_LoadingManager.event.loadingProgressEnd, self.onEvent_loadingEnd, self)
end

function this:onEvent_loadingStart()
  self:freeze(true, L_ShowQueueConst.blockType.Loading)
end

function this:onEvent_loadingEnd()
  self:freeze(false, L_ShowQueueConst.blockType.Loading)
end

function this:updateLoading(options)
  if options.progress >= 1 then
    return
  end
  self:freeze(options.progress < 1, L_ShowQueueConst.blockType.Loading)
end

function this:onEvent_battleStart()
  self:freeze(true, L_ShowQueueConst.blockType.Battle)
end

function this:onEvent_exitBattle()
  self:freeze(false, L_ShowQueueConst.blockType.Battle)
end

function this:onEvent_flyMsgPopupEnd(flyMsgType, uuid)
  self:tryCloseAndShowNext(L_ShowQueueConst.priorityDataType.flyMsg, flyMsgType, uuid)
end

function this:tryCloseAndShowNext(...)
  for i, v in pairs(self.showQueueList) do
    if v.highestPriorityData ~= nil and v.highestPriorityData:checkIsCurData(...) then
      v:hide()
    end
  end
  self:delayTryDuelPriorityShowData()
end

function this:onEvent_closedPage(pageName)
  self:tryCloseAndShowNext(L_ShowQueueConst.priorityDataType.ui, pageName)
end

function this:onEvent_showed()
  self:tryDuelPriorityShowData()
end

function this:addPriorityShowData(priorityShowData)
  if not priorityShowData then
    return
  end
  printf("priorityShowQueueManager", "addPriorityShowData ", priorityShowData:getDesc())
  local queue = priorityShowData:getShowQueue()
  local showQueue = self.showQueueList[queue]
  priorityShowData._uuid = self:getUniqueId()
  showQueue:addPriorityShowData(priorityShowData)
  self:delayTryDuelPriorityShowData()
end

function this:checkUINeedCheckQueue(pageName)
  local tpl = _uiViewTpl:getTplByName(pageName)
  return tpl
end

function this:checkUiInQueue(pageName, uid)
  local tpl = self:checkUINeedCheckQueue(pageName)
  if tpl and _uiViewTpl:getQueueType(tpl) == L_ShowQueueConst.queueType.single then
    for _, queue in pairs(self.showQueueList) do
      if queue:checkPriorityDataExist(_uiViewTpl:getPanelType(tpl), pageName, uid) then
        return true
      end
    end
  end
  return false
end

function this:open(pageName, options, callback)
  local tab = table.pack(pageName, options, callback)
  self.executor:TryExecute(tab)
end

function this:_open(tab)
  local pageName, options, callback = table.unpack(tab)
  if not self:checkUINeedCheckQueue(pageName) then
    L_UI:open(pageName, options, callback, true)
    return
  end
  if self:checkUiInQueue(pageName) then
    return
  end
  local priorityShowData = require("ui.manager.priorityShowQueue.uiPriorityShowData").new({
    params = {
      pageName,
      options,
      function(isOpen)
        if not isOpen then
          printf("priorityShowQueueManager", "pageName open check  fail  ", pageName)
          self:onEvent_closedPage(pageName)
        end
        if callback then
          callback(isOpen)
        end
      end
    }
  })
  self:addPriorityShowData(priorityShowData)
end

function this:delayTryDuelPriorityShowData()
  L_TimerManager:newOrResetTimer(self, "delayTimer", function()
    self:tryDuelPriorityShowData()
  end, 0.1)
end

function this:tryDuelPriorityShowData()
  if self.isFreeze then
    return
  end
  if not self.showQueueList[L_ShowQueueConst.showQueueEnum.tip]:isOnShow() then
    self.showQueueList[L_ShowQueueConst.showQueueEnum.tip]:show()
  end
end

function this:checkSignInSystem()
  if not L_GameStore:isEntered() then
    return
  end
  local data = L_GameEventStore:getDataByType(L_Const.ActivityType.AT_SIGN)
  local eModel = data and data:isValid() and data:getGameEvent()
  if eModel and eModel:needShow() and not self:checkUiInQueue("pageAttendance") and not L_UI:checkPageShown("pageAttendance", true) then
    L_UI:open("pageAttendance")
  end
end

function this:refreshSystem(id)
  if not L_GameStore:isEntered() then
    return
  end
  self:checkSignInSystem()
end

return this
