local this = class("pageTask", G_UIPageBase)
local _taskTpl = L_GameTpl:getTaskTpl()
local _TypeId2Module = {
  [1] = "moduleMainTaskInfo",
  [2] = "moduleOtherTaskInfo",
  [3] = "moduleMainTaskInfo",
  [5] = "moduleOtherTaskInfo"
}

function this.bind()
  return {
    tabList = {
      moduleName = "pages/task/cellTaskTab"
    },
    currentTabId = 0,
    taskGrid = {
      moduleName = "pages/task/cellGroupTask"
    },
    moduleMainTaskInfo = {
      moduleName = "pages/task/moduleMainTaskInfo"
    },
    moduleOtherTaskInfo = {
      moduleName = "pages/task/moduleOtherTaskInfo"
    },
    activeToTrace = false,
    activeCancelTrace = false,
    activeFinish = false,
    activeTraceing = false,
    activeMap = false,
    empty_panel = false,
    txtEmptyTip = L_WordsTpl:getValue("ui_task_none"),
    txtEmptyTipSmall = L_WordsTpl:getValue("ui_task_none_small"),
    activeBtns = true
  }
end

function this.methods()
  return {
    onClick_home = function(self)
      L_UI:backToRoot()
    end,
    onClick_close = function(self)
      L_UI:close(self.pageName)
    end,
    onSelectTab = function(self, tabId)
      self:switchTaskPage(tabId)
    end,
    onClickToTrace = function(self)
      self:setTracedTask(true)
    end,
    onClickCancelTrace = function(self)
      self:setTracedTask(false)
    end,
    onClickMap = function(self)
      self:openBigMap()
    end
  }
end

function this:ctor()
  this.super.ctor(self)
end

function this:check(options, callback)
  if L_BattleDataManager:checkPlayerBattle() then
    L_FlyMsgManager:showNormalMsg(L_BattleDataManager:getBattleBlockTips(L_Const.BattleBlockType.OpenTaskView))
    callback(false)
    return
  end
  local result = L_SystemUnlockManager:checkAndTip(L_SystemConst.enum.task)
  callback(result)
end

function this:preOpen(options)
  this.super.preOpen(self, options)
  L_TaskStore:listenCallFunc(L_TaskStore.event.refreshTask, self.onEventRefreshTask, self)
  self.modules.moduleMainTaskInfo:hideTask()
  self.modules.moduleOtherTaskInfo:hideTask()
  self:initTabs()
  self:refreshNewTask()
  options = options or {}
  if options.jumpParams then
    local jumpType = tonumber(options.jumpParams[1])
    if jumpType == 1 then
      options.tabId = tonumber(options.jumpParams[2])
    elseif jumpType == 2 then
      options.taskId = tonumber(options.jumpParams[2])
    end
    if options.taskId and options.taskId > 0 then
      self:jumpTask(options.taskId)
    elseif options.tabId then
      self.bind.currentTabId = options.tabId
    else
      self.bind.currentTabId = self.bind.tabList[1].tabId
    end
  else
    local taskList = C_TaskStore.GetTraceTaskList()
    local openTaskId = options.taskId or 0 < taskList.Count and taskList[0]
    if openTaskId and 0 < openTaskId then
      self:jumpTask(openTaskId)
    elseif options.tabId then
      self.bind.currentTabId = options.tabId
    else
      self.bind.currentTabId = self.bind.tabList[1].tabId
    end
  end
end

function this:close()
  this.super.close(self)
  L_TaskStore:unListenCallFunc(L_TaskStore.event.refreshTask, self.onEventRefreshTask, self)
end

function this:onEventRefreshTask()
  self:refreshNewTask()
  local curModule = self:getCurTaskModule()
  if curModule then
    curModule:showTask(self.typeId)
    self:setEmptyPanelShow(not curModule.isShow)
  end
end

function this:initTabs()
  local typeTpl = L_GameTpl:getTaskTypeTpl()
  local datas = {}
  local traceId = L_TaskStore:getTracedTask()
  local guideTasks = C_TaskManager:GetCurTaskIdsByType(L_Const.taskType.guide)
  local guideTaskTace = guideTasks.Count > 0
  local traceTabType = L_TaskManager:getTaskTabType(traceId)
  for _, v in pairs(typeTpl.data) do
    if typeTpl:getShow(v) ~= 0 then
      local trace = v.id == L_Const.taskTabType.guide or v.id == traceTabType
      if v.id == L_Const.taskTabType.guide then
        trace = guideTaskTace
      else
        trace = v.id == traceTabType
      end
      table.insert(datas, {
        tabId = v.id,
        order = typeTpl:getOrder(v),
        txtNameOn = typeTpl:getName(v),
        txtNameOff = typeTpl:getName(v),
        txtNameSubOn = typeTpl:getEnglishName(v),
        txtNameSubOff = typeTpl:getEnglishName(v),
        txtIconOn = typeTpl:getTypeIcon(v),
        txtIconOff = typeTpl:getTypeIcon(v),
        activeLine = true,
        activeTraceOn = trace,
        activeTraceOff = trace
      })
    end
  end
  table.sort(datas, function(a, b)
    return a.order < b.order
  end)
  datas[#datas].activeLine = false
  self.bind.tabList:clear()
  self.bind.tabList:insert_array(datas)
end

function this:refreshTabTrace()
  local traceId = L_TaskStore:getTracedTask()
  local traceTabType = L_TaskManager:getTaskTabType(traceId)
  for i = 1, #self.modules.tabList do
    local tabItem = self.modules.tabList[i]
    local trace = tabItem.bind.tabId == traceTabType or tabItem.bind.tabId == L_Const.taskTabType.guide
    tabItem.bind.activeTraceOn = trace
    tabItem.bind.activeTraceOff = trace
  end
end

function this:switchTaskPage(typeId)
  local playAnim = self.typeId ~= nil
  local lastModule = self:getCurTaskModule()
  local curModule = self:getTaskModule(typeId)
  self.typeId = typeId
  if not curModule then
    if lastModule then
      lastModule:hideTask()
    end
    self:setEmptyPanelShow(true, false)
    return
  end
  curModule:showTask(typeId, playAnim and not self.isEmpty)
  if curModule.isShow and lastModule and lastModule ~= curModule then
    lastModule:hideTask()
  end
  self:setEmptyPanelShow(not curModule.isShow, lastModule, playAnim)
end

function this:getCurTaskModule()
  if self.isEmpty then
    return
  end
  return self:getTaskModule(self.typeId)
end

function this:getTaskModule(typeId)
  if not typeId then
    return
  end
  local moduleKey = _TypeId2Module[typeId]
  if not moduleKey then
    errorf("\232\175\165\231\177\187\229\158\139\230\156\170\229\188\128\229\143\145 " .. tostring(typeId))
  end
  return self.modules[moduleKey]
end

function this:jumpTask(taskId)
  local tabType = L_TaskManager:getTaskTabType(taskId)
  local module = self:getTaskModule(tabType)
  if module then
    module:setDefaultOpenTaskId(taskId)
  end
  if tabType ~= self.bind.currentTabId then
    self.bind.currentTabId = tabType
  end
end

function this:setEmptyPanelShow(show, laskModule, playAnim)
  if self.isEmpty == show then
    return
  end
  self.isEmpty = show
  self.bind.activeBtns = not show
  if not playAnim then
    self.bind.empty_panel = show
    if self.isEmpty and laskModule then
      laskModule:hideTask()
    end
    return
  end
  self.bindComponents.animEmpty:Stop()
  self.bindComponents.animContent:Stop()
  if show then
    self.bindComponents.animEmpty:Play("anim_task_empty_show")
    self.bindComponents.animContent:Play("anim_task_content_hide")
    self.bind.empty_panel = true
    self:AddChangeTypeAnimTimer(0.333, function()
      if laskModule then
        laskModule:hideTask()
      end
    end)
  else
    self.bindComponents.animEmpty:Play("anim_task_empty_hide")
    self.bindComponents.animContent:Play("anim_task_content_show")
    self:AddChangeTypeAnimTimer(0.233, function()
      self.bind.empty_panel = false
      L_AudioUtil.playSound("Play_SFX_System_UI_Mission_Open")
    end)
  end
end

function this:AddChangeTypeAnimTimer(time, cb)
  L_TimerManager:newOrResetTimer(self, "ChangeType", cb, time)
end

function this:onShowTask(taskId)
  self:handleCurrentTaskBtn(taskId)
  self:removeNewTask(taskId)
end

function this:handleCurrentTaskBtn(taskId)
  self.taskId = taskId
  if L_TaskManager:IsTaskInLimitStep(taskId) then
    self.bind.activeToTrace = false
    self.bind.activeTraceing = false
    self.bind.activeCancelTrace = false
    self.bind.activeMap = false
    return
  end
  local traceId = L_TaskStore:getTracedTask()
  local isGuide = L_TaskManager:getTaskType(taskId) == L_Const.taskType.guide
  if isGuide then
    self.bind.activeToTrace = false
    self.bind.activeTraceing = true
    self.bind.activeCancelTrace = false
    local list = C_TaskManager.GetTaskNodeCommonData(self.taskId)
    local flag = false
    for i = 0, list.Count - 1 do
      local data = list[i]
      if 0 < data.sceneId and 0 < data.birthId then
        flag = true
        break
      end
    end
    self.bind.activeMap = flag and L_SystemUnlockStore:getSystemIsOpen(L_SystemConst.enum.adventure)
  elseif traceId == taskId then
    self.bind.activeToTrace = false
    self.bind.activeTraceing = false
    self.bind.activeCancelTrace = true
    self.bind.activeMap = L_SystemUnlockStore:getSystemIsOpen(L_SystemConst.enum.adventure)
  else
    self.bind.activeToTrace = true
    self.bind.activeTraceing = false
    self.bind.activeCancelTrace = false
    self.bind.activeMap = false
  end
end

function this:refreshTraceTask()
  self:refreshTabTrace()
  local module = self:getCurTaskModule()
  if module and module.refreshTrace then
    module:refreshTrace()
  end
  self:handleCurrentTaskBtn(self.taskId)
end

function this:setTracedTask(isTrace)
  if self.taskId == L_TaskStore:getTracedTask() then
    if not isTrace then
      L_TaskStore:disposeTraceTask(function()
        self:refreshTraceTask()
      end)
    end
    return
  end
  if not isTrace then
    return
  end
  L_GameUtil.showCommonTip({
    txtTitle = L_WordsTpl:getValue("task_changetasktrace_title"),
    txtContent = L_WordsTpl:getValue("task_changetasktrace_content"),
    closeCallback = function()
      L_TaskStore:setTraceTask(self.taskId, function()
        self:openBigMap(function()
          L_UI:close(self.pageName)
        end)
      end)
    end,
    hideConfirm = true,
    hideCancel = true
  })
end

function this:refreshNewTask()
  local ids = C_TaskManager.GetTaskExecuteTaskId()
  self.newTasks = {}
  for i = 0, ids.Count - 1 do
    if not L_CommonUtil.getLocalValue("NewTask_" .. ids[i]) then
      local tplTask = _taskTpl:getTplById(ids[i])
      local type = _taskTpl:getTabType(tplTask)
      if not self.newTasks[type] then
        self.newTasks[type] = {}
      end
      self.newTasks[type][ids[i]] = true
    end
  end
  for _, v in ipairs(self.modules.tabList) do
    if not table.isEmpty(self.newTasks[v.bind.tabId]) then
      v.bind.activeRed = true
    end
  end
end

function this:removeNewTask(taskId)
  local tplTask = _taskTpl:getTplById(taskId)
  local type = _taskTpl:getTabType(tplTask)
  if self.newTasks[type] and self.newTasks[type][taskId] then
    self.newTasks[type][taskId] = nil
    L_CommonUtil.setLocalValue("NewTask_" .. taskId, "1")
    if table.isEmpty(self.newTasks[type]) then
      for _, v in ipairs(self.modules.tabList) do
        if v.bind.tabId == type then
          v.bind.activeRed = false
        end
      end
    end
  end
end

function this:openBigMap(cb)
  if not self.taskId then
    return
  end
  C_TaskManager.OpenMapByTaskId(self.taskId, -1, -1, cb)
end

return this
