local module = class("moduleTask", G_UIModuleBase)
local _NewTaskShowTime = L_GameConstTpl:getValue("NEWTASK_TIME", true, 2000) / 1000
local _taskTpl = L_GameTpl:getTaskTpl()
module.timeOperateType = {
  pause = 1,
  resume = 2,
  stop = 3,
  start = 4
}

function module.bind()
  return {
    go_moduleTask = false,
    goTask = true,
    taskListActive = false,
    activeNewTask = false,
    taskList = {
      moduleName = "pages/task/cellTaskItem"
    }
  }
end

function module.methods()
  return {
    onClick_task = function(self)
      L_SystemBreakManager:jumpTo(L_SystemConst.enum.task)
    end
  }
end

function module:open()
  L_TaskStore:listenCallFunc(L_TaskStore.event.refreshTask, self.onEvent_taskUpdateHandle, self)
  L_SceneManager:addListener(L_SceneManager.event.switchSceneEnd, self.taskUpdateHandle, self)
  self._syncChallengeDataHandler = handler(self, self.onEvent_syncChallengeData)
  AzurWorld.ChallengeMgr:RegisterEvent(C_EChallengeEvent.SyncChallengeData, self._syncChallengeDataHandler)
  self._onChallengeTargetOpenHandler = handler(self, self.onChallengeStart)
  self._onChallengeTargetCloseHandler = handler(self, self.onChallengeStop)
  C_WorldEvent.instance:Listen(C_EWorldEvent.OnChallengeTargetOpen, self._onChallengeTargetOpenHandler)
  C_WorldEvent.instance:Listen(C_EWorldEvent.OnChallengeTargetCloseDone, self._onChallengeTargetCloseHandler)
  self.bind.isShow = false
  self:initSystem()
  self:bindPcKey()
end

function module:initSystem()
  self.systemToTrans = {
    [L_SystemConst.enum.task] = {
      self.gameObject.tranform
    }
  }
  for systemId, v in pairs(self.systemToTrans) do
    v.locker = L_SystemUnlockManager:tryGenerateLocker(systemId)
    if v.locker then
      self:refreshSystem(systemId, false)
      v.locker:setCallback(self.refreshSystem, self, self.gameObject)
    end
  end
end

function module:refreshSystem(systemId, isUnlock)
  local node = self.systemToTrans[systemId]
  local locker = node.locker
  for _, v in ipairs(node) do
    locker:tryShowOrHide(v, isUnlock)
  end
end

function module:onChallengeStart(et, ed)
  self.bind.go_moduleTask = false
  self.newChallengeTargetShowing = true
end

function module:onChallengeStop(et, ed)
  self.bind.go_moduleTask = true
  self.newChallengeTargetShowing = false
end

function module:destroyAllLocker()
  for _, v in pairs(self.systemToTrans) do
    local locker = v.locker
    if locker then
      L_SystemUnlockManager:removeLocker(locker)
    end
  end
end

function module:bindPcKey()
  L_ShortCutManager:addShortKeyFlag(self, L_Const.settingType.openTask, L_Const.AnchorType.Right, self.bindComponents.transBtnTask)
end

function module:show()
  self.bind.isShow = true
  if self.taskEventUpdate or self.isPlayingCompleteOrNewAnim or not self.data then
    self:taskUpdateAndNewAnim()
  else
    for i = 1, #self.bind.taskList do
      if self.bind.taskList:getItemCls(i) then
        self.bind.taskList:getItemCls(i):refreshTimers()
      end
    end
  end
  self:setTaskModuleActiveByChallengeData()
end

function module:hide()
  self.bind.isShow = false
  L_TimerManager:clearTimer(self)
  for i = 1, #self.bind.taskList do
    if self.bind.taskList:getItemCls(i) then
      self.bind.taskList:getItemCls(i):reset()
    end
  end
end

function module:close()
  L_TimerManager:clearTimer(self)
  L_TaskStore:unListenCallFunc(L_TaskStore.event.refreshTask, self.onEvent_taskUpdateHandle)
  L_SceneManager:removeListener(L_SceneManager.event.switchSceneEnd, self.taskUpdateHandle)
  AzurWorld.ChallengeMgr:UnregisterEvent(C_EChallengeEvent.SyncChallengeData, self._syncChallengeDataHandler)
  C_WorldEvent.instance:Cancel(C_EWorldEvent.OnChallengeTargetOpen, self._onChallengeTargetOpenHandler)
  C_WorldEvent.instance:Cancel(C_EWorldEvent.OnChallengeTargetCloseDone, self._onChallengeTargetCloseHandler)
  self:destroyAllLocker()
  L_ShortCutManager:clearShortKeyFlag(self)
end

function module:onEvent_taskUpdateHandle()
  if not self.bind.isShow then
    self.taskEventUpdate = true
    return
  end
  if self.isPlayingCompleteOrNewAnim then
    return
  end
  self.taskEventUpdate = false
  self.isPlayingCompleteOrNewAnim = true
  if self.data and #self.data > 0 then
    local animFinish = #self.modules.taskList
    local completeAnimCB = function()
      animFinish = animFinish - 1
      if animFinish == 0 then
        self:taskUpdateAndNewAnim()
      end
    end
    for i = 1, #self.modules.taskList do
      self.modules.taskList[i]:tryPlayUpdateAnim(completeAnimCB)
    end
  else
    self:taskUpdateAndNewAnim()
  end
end

function module:taskUpdateAndNewAnim()
  self.taskEventUpdate = false
  local newTaskId = self:getFirstNewTask()
  if newTaskId then
    local data = self:createTaskData(newTaskId)
    if data then
      self.bind.activeNewTask = true
      self.isPlayingCompleteOrNewAnim = true
      data.isNewTask = true
      if not self.data then
        self.data = {}
      end
      self.data[1] = data
      for i = 2, #self.data do
        self.data[i].taskId = -1
        self.data[i].nodeId = -1
      end
      self:showOrHideTaskList(true)
      self.bind.taskList:freshAll(self.data)
      L_TimerManager:newOrResetTimer(self, "refreshNewTask", function()
        self:taskUpdateAndNewAnim()
      end, _NewTaskShowTime)
      return
    end
  end
  local taskIds = C_TaskStore.GetTraceTaskList()
  if self.isPlayingCompleteOrNewAnim and self.data[1] and self.data[1].isNewTask and taskIds[0] ~= self.data[1].taskId then
    self.modules.taskList[1]:playHideAnim(function()
      self:taskUpdateHandle()
    end)
    return
  end
  self:taskUpdateHandle()
end

function module:getFirstNewTask()
  local ids = C_TaskManager.GetTaskExecuteTaskId()
  for i = 0, ids.Count - 1 do
    local taskId = ids[i]
    local tplTask = _taskTpl:getTplById(taskId)
    if _taskTpl:getNewShow(tplTask) == 1 and _taskTpl:getType(tplTask) ~= L_Const.taskType.guide then
      local key = "ModuleNewTask_" .. taskId
      if not L_CommonUtil.getLocalValue(key) then
        L_CommonUtil.setLocalValue(key, "1")
        return ids[i]
      end
    end
  end
end

function module:taskUpdateHandle()
  if not self.bind.isShow then
    return
  end
  self.bind.activeNewTask = false
  self.isPlayingCompleteOrNewAnim = false
  local taskIds = C_TaskStore.GetTraceTaskList()
  local datas = {}
  for i = 0, taskIds.Count - 1 do
    local taskId = taskIds[i]
    local data = self:createTaskData(taskId)
    if data then
      table.insert(datas, data)
    end
  end
  self.data = datas
  self:showOrHideTaskList(0 < #self.data)
  self.bind.taskList:freshAll(self.data)
  self:refreshTaskCutKey()
end

function module:createTaskData(taskId)
  local nodeId = C_TaskManager.GetExcuteNode(taskId)
  if nodeId then
    local taskData = {
      taskId = taskId,
      nodeId = nodeId,
      isNewTask = false
    }
    return taskData
  end
end

function module:refreshTaskCutKey()
  if not L_SystemUnlockManager:check(L_SystemConst.enum.map) then
    return
  end
  for i = 1, #self.bind.taskList do
    local class = self.bind.taskList:getItemCls(i)
    if class and class.traceList then
      class:hideCutKey()
    end
  end
  local traceClass
  for i = 1, #self.bind.taskList do
    local class = self.bind.taskList:getItemCls(i)
    if class then
      if not class.traceList then
        return
      end
      local len = #class.traceList
      if 1 < len then
        return
      end
      if len == 1 then
        if traceClass then
          return
        end
        traceClass = class
      end
    end
  end
  if traceClass then
    traceClass:showCutKey()
  end
end

function module:clearTask()
  self.bind.taskList:clear()
  self:showOrHideTaskList(false)
end

function module:showOrHideTaskList(isShow)
  self.bind.taskListActive = isShow
  self.bind.goTask = not isShow
end

function module:activate()
  self:open()
  self:show()
end

function module:deActivate()
  self:hide()
  self:close()
end

function module:onEvent_syncChallengeData()
  self:setTaskModuleActiveByChallengeData()
end

function module:setTaskModuleActiveByChallengeData()
  local showData = AzurWorld.ChallengeMgr:GetShowChallengeData()
  local groupData = showData.groupData
  local showTaskModule = groupData.state == C_EChallengeState.None and not self.newChallengeTargetShowing
  self.bind.go_moduleTask = showTaskModule
end

return module
