local this = class("pagePetDuel", G_UIPageBase)
local kiBoDuelTpl = L_GameTpl:getKiboDuelTpl()
local worldSpawnerTpl = L_GameTpl:getWorldSpawnerTpl()
local commonConditionTpl = L_GameTpl:getCommonConditionTpl()
local templateValueTpl = L_GameTpl:getTemplateValueTpl()
local tipType = {
  Normal = 0,
  Error = 1,
  Rapid = 2
}
local animatorPlayDelay = {
  countdownShow = 0,
  cardListShow = 3.6497,
  cardShow1 = 3.65,
  cardShow2 = 3.7163,
  cardShow3 = 3.7997,
  cardShow4 = 4.0497,
  cardNextShow = 4.65,
  energyShow = 3.65,
  energyCellShow = 3.813,
  commonShow = 4.4167,
  hpShow = 4.55
}
local petOrdinaryPos = {
  [1] = {x = -309.8, y = 14.4},
  [2] = {x = -146.2, y = 22.2},
  [3] = {x = 14.9, y = 24.1},
  [4] = {x = 179.5, y = 18.3}
}
local descriptionOrdinaryPos = {
  [1] = {x = -258, y = 0},
  [2] = {x = -81, y = 0},
  [3] = {x = 81, y = 0},
  [4] = {x = 258, y = 0}
}
local feverEffectPath = "Effect/Scene/Kiboduel/pre_petduel_fever.prefab"

function this.bind()
  return {
    timeText = "300",
    playerNameText = "",
    enemyNameText = "",
    playerHpTxt = "",
    enemyHpTxt = "",
    currentCostNum = 0,
    costList = {
      moduleName = "pages/petDuel/cellDuelCostItem"
    },
    petList = {
      moduleName = "pages/petDuel/cellIconPetDuel"
    },
    nextPet = {
      moduleName = "pages/petDuel/cellIconPetDuel"
    },
    summonBtnNodeActive = false,
    skillBtnNodeActive = false,
    fightTipActive = false,
    toggle_fightTip = 0,
    fightTipText = "",
    module_moveBlock = {
      moduleName = "pages/petDuel/moduelPetDuelMovement"
    },
    eSkill = {
      moduleName = "pages/petDuel/cellKiBoDuelSkill"
    },
    rSkill = {
      moduleName = "pages/petDuel/cellKiBoDuelSkill"
    },
    dodgeMount = {
      moduleName = "pages/petDuel/cellKiboDuelDodge"
    },
    miniMap = {
      moduleName = "pages/petDuel/modulePetDuelMiniMap"
    },
    btnDogeActive = true,
    btnJumpActive = true,
    kiBoDescription = {
      moduleName = "pages/petDuel/moduleKiBoDescription"
    },
    rect_kiBoDescription = C_Vector2(0, 0),
    summonNotify = {
      moduleName = "pages/petDuel/moduleSummonNotify"
    },
    summonNotifyModuleActive = true,
    moduleKiBoList = {
      moduleName = "pages/petDuel/moduleKiboList"
    },
    moduleDuelResult = {
      moduleName = "pages/petDuel/moduleDuelResult"
    },
    moduleStatistics = {
      moduleName = "pages/petDuel/moduleBattleStatistics"
    },
    active_statistics = false,
    moduleDuelSKill = {
      moduleName = "pages/petDuel/moduleDuelSkillRelease"
    },
    moduleDuelTarget = {
      moduleName = "pages/petDuel/moduleDuelTarget"
    },
    boardActive = true
  }
end

function this.methods()
  return {
    onClick_Exit = function(self)
      self:dealExit()
    end,
    onClick_dogeBtn = function(self)
      if not self.duelStar then
        return
      end
      L_PlayerManager:fireEvade()
    end,
    onClick_summonBtn = function(self)
      L_KiBoDuelManager:handleKiBoSummonConfirm()
    end,
    onClick_summonCancleBtn = function(self)
      L_KiBoDuelManager:handleKiBoSummonCancel()
    end,
    onClick_Jump = function(self)
      if not self.duelStar then
        return
      end
      L_PlayerManager:fireJump()
    end,
    onClick_eSkill = function(self)
      if L_KiBoDuelManager:getIsPlayAnimation() or not self.duelStar then
        return
      end
      L_KiBoDuelManager:changeSkillStatus(L_Const.skillType.KiBoVersusCommonSkill1, L_KiBoDuelManager.skillStausEnum.waitConfirm)
    end,
    onClick_rSkill = function(self)
      if L_KiBoDuelManager:getIsPlayAnimation() or not self.duelStar then
        return
      end
      L_KiBoDuelManager:changeSkillStatus(L_Const.skillType.KiBoVersusCommonSkill2, L_KiBoDuelManager.skillStausEnum.waitConfirm)
    end
  }
end

function this:preOpen(options)
  printLog("KIBODUEL_DEBUG:pagePetDuel.lua:preOpen")
  self:refreshInputMap()
  self.bind.boardActive = true
  self.maxCost = 0
  self:playPageEffect(false, false)
  L_KiBoDuelManager:addListener(L_KiBoDuelManager.event.changeSkillStatus, self.onChangeSkillStatus, self)
  L_KiBoDuelManager:addListener(L_KiBoDuelManager.event.kiBoSummonStart, self.refreshSummonControl, self)
  L_KiBoDuelManager:addListener(L_KiBoDuelManager.event.kiBoSummonConfirm, self.summonConfirmed, self)
  L_KiBoDuelManager:addListener(L_KiBoDuelManager.event.kiBoSummonCancel, self.summonCancled, self)
  L_KiBoDuelManager:addListener(L_KiBoDuelManager.event.kiBoDuelEntityCreated, self.onKiBoDuelEntityCreated, self)
  L_KiBoDuelManager:addListener(L_KiBoDuelManager.event.refreshKiBoDuelCost, self.refreshKiBoDuelCost, self)
  L_KiBoDuelManager:addListener(L_KiBoDuelManager.event.refreshTowerHp, self.onRefreshTowerHp, self)
  L_KiBoDuelManager:addListener(L_KiBoDuelManager.event.refreshSummonField, self.refreshSummonField, self)
  L_KiBoDuelManager:addListener(L_KiBoDuelManager.event.startRapidState, self.onStartRapidState, self)
  self.duelEndHandler = self.duelEndHandler or handler(self, self.onCampainInfoSync)
  C_ExternalManager.AddEvent(C_EExternalEventType.BattleResultCall, self.duelEndHandler)
  L_UI:addListener(L_UI.pageEvent.closed, self.onPageClose, self)
  L_KiBoDuelManager:addListener(L_KiBoDuelManager.event.restartKiBoDuel, self.restartKiBoDuel, self)
  L_PlayerManager:addListener(L_PlayerManager.event.playMount, self.refreshButtonStatus, self)
  L_PlayerManager:addListener(L_PlayerManager.event.outMount, self.refreshButtonStatus, self)
  L_PlayerManager:addListener(L_PlayerManager.event.outMountEnd, self.refreshButtonStatus, self)
  L_UI:addListener(L_UI.pageEvent.preOpen, self.onPageOpen, self)
  
  function self.onPlayerExitFlyState()
    self:refreshButtonStatus()
  end
  
  C_ExternalManager.AddEvent(C_EExternalEventType.PlayerEnterFlyState, self.onPlayerExitFlyState)
  self:resetPercentValue()
  self.duelId = L_PetDuelStore:getCurChallengeLevelId() or 1001
  self:initPage()
end

function this:playPageEffect(isShow, isPlayAni, isUseTime, isBlockCountDown)
  if not (self.bindComponents.cardsAnimator and self.bindComponents.healthyAnimator and self.bindComponents.countDownAnimator and self.bindComponents.energyAnimator) or not self.bindComponents.commonAnimator then
    return
  end
  if not self.isBind then
    return
  end
  if isUseTime then
    Timer.once(animatorPlayDelay.countdownShow, function()
      self.bindComponents.countDownAnimator:SetBool("PlayAnim", isPlayAni)
      self.bindComponents.countDownAnimator:SetBool("Show", isShow)
    end, self, self.gameObject)
    Timer.once(animatorPlayDelay.hpShow, function()
      self.bindComponents.healthyAnimator:SetBool("PlayAnim", isPlayAni)
      self.bindComponents.healthyAnimator:SetBool("Show", isShow)
    end, self, self.gameObject)
    Timer.once(animatorPlayDelay.cardListShow, function()
      self.bindComponents.cardsAnimator:SetBool("PlayAnim", isPlayAni)
      self.bindComponents.cardsAnimator:SetBool("Show", isShow)
      L_AudioUtil.playSound("Play_SFX_System_QiboChallenge_Card_Appear")
    end, self, self.gameObject)
    Timer.once(animatorPlayDelay.energyShow, function()
      self.bindComponents.energyAnimator:SetBool("PlayAnim", isPlayAni)
      self.bindComponents.energyAnimator:SetBool("Show", isShow)
    end, self, self.gameObject)
    Timer.once(animatorPlayDelay.commonShow, function()
      self.bindComponents.commonAnimator:SetBool("PlayAnim", isPlayAni)
      self.bindComponents.commonAnimator:SetBool("Show", isShow)
    end, self, self.gameObject)
    Timer.once(animatorPlayDelay.commonShow, function()
      self.bindComponents.bottomAnimator:SetBool("PlayAnim", isPlayAni)
      self.bindComponents.bottomAnimator:SetBool("Show", isShow)
    end, self, self.gameObject)
  else
    if not isBlockCountDown then
      self.bindComponents.countDownAnimator:SetBool("PlayAnim", isPlayAni)
      self.bindComponents.countDownAnimator:SetBool("Show", isShow)
    else
      self.bindComponents.countDownAnimator:SetBool("PlayAnim", false)
      self.bindComponents.countDownAnimator:SetBool("Show", false)
    end
    self.bindComponents.healthyAnimator:SetBool("PlayAnim", isPlayAni)
    self.bindComponents.healthyAnimator:SetBool("Show", isShow)
    self.bindComponents.cardsAnimator:SetBool("PlayAnim", isPlayAni)
    self.bindComponents.cardsAnimator:SetBool("Show", isShow)
    self.bindComponents.energyAnimator:SetBool("PlayAnim", isPlayAni)
    self.bindComponents.energyAnimator:SetBool("Show", isShow)
    self.bindComponents.commonAnimator:SetBool("PlayAnim", isPlayAni)
    self.bindComponents.commonAnimator:SetBool("Show", isShow)
    self.bindComponents.bottomAnimator:SetBool("PlayAnim", isPlayAni)
    self.bindComponents.bottomAnimator:SetBool("Show", isShow)
  end
  local cardNum = #self.bind.petList + 1
  for i = 1, cardNum do
    if i < cardNum then
      local delayTime = animatorPlayDelay["cardShow" .. i] or 0
      if not isUseTime then
        delayTime = 0
      end
      local petItem = self.bind.petList:getItemCls(i)
      petItem:playAnimator(isShow, isPlayAni, delayTime)
    elseif i >= cardNum and isShow == false then
      local nextDelayTime = animatorPlayDelay.cardNextShow or 0
      if not isUseTime then
        nextDelayTime = 0
      end
      self.modules.nextPet:playNextAnimation("anim_petduel_card_nextcard_init_hide", nextDelayTime)
    elseif i >= cardNum and isShow ~= false then
      local nextDelayTime = animatorPlayDelay.cardNextShow or 0
      if not isUseTime then
        nextDelayTime = 0
      end
      self.modules.nextPet:playNextAnimation("anim_petduel_card_nextcard_show", nextDelayTime)
    end
  end
end

function this:onPageOpen(pageName)
  if pageName == "pageMountRoulette" then
    C_WorldProxy:GetInstance():Pause()
    self:setUIActive(false)
    self:playPageEffect(false, false)
  end
end

function this:onPageClose(pageName)
  printLog("KIBODUEL_DEBUG:pagePetDuel.lua:onPageClose", pageName)
  if pageName == "pageMountRoulette" then
    C_WorldProxy:GetInstance():Resume()
    self:setUIActive(true)
    self:playPageEffect(true, false)
  end
  if pageName == "loading" then
  end
  if string.find(pageName, "dialog") then
    C_WorldProxy:GetInstance():Resume()
    self:refreshInputMap()
  end
  local curPage = L_UI:currentPage(L_UI.groupKeys.stack)
  if curPage == self.pageName then
    self:refreshInputMap()
  end
end

function this:setUIActive(isShow)
  self.bind.active_statistics = isShow
end

function this:close()
  L_KiBoDuelManager:removeListener(L_KiBoDuelManager.event.changeSkillStatus, self.onChangeSkillStatus, self)
  L_KiBoDuelManager:removeListener(L_KiBoDuelManager.event.kiBoSummonStart, self.refreshSummonControl, self)
  L_KiBoDuelManager:removeListener(L_KiBoDuelManager.event.kiBoSummonConfirm, self.summonConfirmed, self)
  L_KiBoDuelManager:removeListener(L_KiBoDuelManager.event.kiBoSummonCancel, self.summonCancled, self)
  L_KiBoDuelManager:removeListener(L_KiBoDuelManager.event.kiBoDuelEntityCreated, self.onKiBoDuelEntityCreated, self)
  L_KiBoDuelManager:removeListener(L_KiBoDuelManager.event.refreshKiBoDuelCost, self.refreshKiBoDuelCost, self)
  L_KiBoDuelManager:removeListener(L_KiBoDuelManager.event.refreshTowerHp, self.onRefreshTowerHp, self)
  L_KiBoDuelManager:removeListener(L_KiBoDuelManager.event.refreshSummonField, self.refreshSummonField, self)
  L_KiBoDuelManager:removeListener(L_KiBoDuelManager.event.startRapidState, self.onStartRapidState, self)
  C_ExternalManager.RemoveEvent(C_EExternalEventType.BattleResultCall, self.duelEndHandler)
  L_UI:removeListener(L_UI.pageEvent.closed, self.onPageClose, self)
  L_KiBoDuelManager:removeListener(L_KiBoDuelManager.event.restartKiBoDuel, self.restartKiBoDuel, self)
  L_PlayerManager:removeListener(L_PlayerManager.event.playMount, self.refreshButtonStatus, self)
  L_PlayerManager:removeListener(L_PlayerManager.event.outMount, self.refreshButtonStatus, self)
  L_PlayerManager:removeListener(L_PlayerManager.event.outMountEnd, self.refreshButtonStatus, self)
  C_ExternalManager.RemoveEvent(C_EExternalEventType.PlayerEnterFlyState, self.refreshButtonStatus)
  L_UI:removeListener(L_UI.pageEvent.preOpen, self.onPageOpen, self)
  if self.openingTimer ~= nil then
    Timer.remove(self.openingTimer)
    self.openingTimer = nil
  end
  self:disposeDuelTimer()
  L_KiBoDuelManager:setRapidState(false)
  self:playFeverEffect(false)
  L_ShortCutManager:removeShortCut(C_EWorldType.KiboDuel)
  L_KiBoDuelManager:exitDuel()
  self.openedCountDown = false
end

function this:show(options)
  C_ExternalManager.DispatchEvent(C_EExternalEventType.PetFightStart)
  self.bind.boardActive = true
  self.modules.module_moveBlock:refresh()
  self:refreshInputMap()
  if self.duelStar then
    self:playPageEffect(true, false, false, true)
    self:playCostInitAnimation()
  end
end

function this:refreshInputMap()
  if self.duelStar then
    L_ShortCutManager:removeShortCut(C_EWorldType.KiboDuel)
    L_ShortCutManager:registerPageMainShortCut(C_EWorldType.KiboDuel)
    if L_KiBoDuelManager:isInSummon() then
      C_InputManager.SetInputmap(C_InputManager_MapType.KiBoDuelSummon, true)
    elseif L_KiBoDuelManager:isInReleaseSkill() then
      C_InputManager.SetInputmap(C_InputManager_MapType.KiBoDuelSkill, true)
    else
      C_InputManager.SetInputmap(C_InputManager_MapType.KiBoDuelMap, true)
    end
  else
    C_InputManager.SetInputmap(C_InputManager_MapType.BlanketInputMap, true)
  end
end

function this:restartKiBoDuel()
  C_InputManager.SetInputmap(C_InputManager_MapType.BlanketInputMap, true)
  self.openedCountDown = false
  self.duelStar = false
  self.cost = 0
  self.lastCost = 0
  self.selectedIndex = nil
  self.currentCost = nil
  self.bind.costList:clear()
  self.bind.petList:clear()
  self:resetPercentValue()
  self:playPageEffect(false, false)
  self:initPage()
  printLog("KIBODUEL_DEBUG:restartKiBoDuel", self.openedCountDown)
end

function this:resetPercentValue()
  self.blueMaxHp = 100
  self.redMaxHp = 100
  self.blueHp = 100
  self.redHp = 100
  printLog("KIBODUEL_DEBUG:restartKiBoDuel", "resetPercentValue")
end

function this:initPage()
  self:playFeverEffect(false)
  self.bind.playerNameText = L_PlayerStore:getPlayerName()
  local tpl = kiBoDuelTpl:getTplById(self.duelId)
  self.duelTime = kiBoDuelTpl:getTime(tpl)
  self.bind.timeText = tostring(self.duelTime)
  local npcSpawnerID = kiBoDuelTpl:getNpcSpawnerID(tpl)
  local tpl_worldSpawner = worldSpawnerTpl:getTplById(npcSpawnerID)
  self.bind.enemyNameText = worldSpawnerTpl:getName(tpl_worldSpawner)
  self.bind.playerHpTxt = string.format("%s", tostring(self.blueMaxHp) .. "%")
  self.bind.enemyHpTxt = string.format("%s", tostring(self.redMaxHp) .. "%")
  self.bindComponents.playerHealthy:InitHp(1)
  self.bindComponents.enemyHealthy:InitHp(1)
  self.modules.miniMap:initMap(self.duelId)
  self:initPetFormation()
  self:refreshKiBoDuelCost()
  self:refreshButtonStatus()
  self:initSkills()
end

function this:initSkills()
  self.modules.eSkill:initSkillType(L_Const.skillType.KiBoVersusCommonSkill1, true)
  self.modules.rSkill:initSkillType(L_Const.skillType.KiBoVersusCommonSkill2, true)
end

function this:onKiBoDuelEntityCreated()
  self.blueMaxHp, self.redMaxHp = L_KiBoDuelManager:getTowerMaxHp()
  self.blueHp = self.blueMaxHp
  self.redHp = self.redMaxHp
end

function this:onRefreshTowerHp(data)
  self.blueMaxHp, self.redMaxHp = L_KiBoDuelManager:getTowerMaxHp()
  if data.isBlue then
    local value = data.hp / self.blueMaxHp
    self.bindComponents.playerHealthy:SetHp(value)
    self.blueHp = data.hp
    self.bind.playerHpTxt = string.format("%.0f", value * 100) .. "%"
  else
    local value = data.hp / self.redMaxHp
    printLog(L_WordsTpl:getValue("ui_kiboDuel_01"), L_WordsTpl:getValue("ui_kiboDuel_02:") .. data.hp .. L_WordsTpl:getValue(" ui_kiboDuel_03:") .. self.redMaxHp)
    self.bindComponents.enemyHealthy:SetHp(value)
    self.redHp = data.hp
    self.bind.enemyHpTxt = string.format("%.0f", value * 100) .. "%"
  end
end

function this:initPetFormation()
  self.formationQueue = L_KiBoDuelManager:getFormationGuid()
  self.petListData = {}
  for i = 1, 4 do
    if self.formationQueue:getLength() > 0 then
      local data = self.formationQueue:deQueue()
      table.insert(self.petListData, {
        isNext = false,
        guid = data.guid,
        petInfo = data,
        index = i
      })
    end
  end
  self.nextPetInfo = self.formationQueue:deQueue()
  table.insert(self.petListData, {
    isNext = true,
    guid = self.nextPetInfo.guid,
    petInfo = self.nextPetInfo,
    index = #self.petListData + 1
  })
  self:initPetList()
  for i = 1, #self.bind.petList do
    self.bind.petList:getItemCls(i):playAnimator(false, false, 0)
  end
end

function this:initPetList(index)
  self.petListData = self.petListData or {}
  if #self.bind.petList == #self.petListData then
    for i = 1, #self.petListData do
      if index == i then
        self.bind.petList:getItemCls(i):playAnimator(false, true, 0)
      end
      self.bind.petList:change(i, self.petListData[i])
      if index == i then
        self.bind.petList:getItemCls(i):playAnimator(true, true, 0)
      end
    end
  else
    self.bind.petList:clear()
    self.bind.petList:insert_array(self.petListData)
  end
end

function this:summonConfirmed()
  if self.selectedIndex == nil then
    return
  end
  L_AudioUtil.playSound("Play_SFX_System_QiboChallenge_Card_Use")
  self.bindComponents.energyAnimator:Play("anim_petduel_energy_num_toPrev")
  L_KiBoDuelManager:setIsPlayAnimation(true)
  Timer.once(1.3, function()
    L_KiBoDuelManager:setIsPlayAnimation(false)
    self.bindComponents.energyAnimator:Play("anim_petduel_energy_num_init")
  end, self, self.gameObject)
  local index = self.selectedIndex
  self.bind.petList:getItemCls(index):setCastStatus(true)
  self.bind.petList:getItemCls(index):playCellAnimation("anim_petduel_card_cast")
  L_TimerManager:newOrResetTimer(self, "nextCardDraw", function()
    L_AudioUtil.playSound("Play_SFX_System_QiboChallenge_Card_Reload")
    self.modules.nextPet:playNextAnimation("anim_petduel_card_nextcard_draw")
    L_TimerManager:stopTimer(self, "nextCardDraw")
    self.bind.petList:getItemCls(index):setCastStatus(false)
    self:refreshPetListStatus(nil, true)
    self:initPetList(index)
    Timer.once(0.3, function()
      self.nextPetInfo = self.formationQueue:deQueue()
      table.remove(self.petListData, #self.petListData)
      table.insert(self.petListData, {
        isNext = true,
        guid = self.nextPetInfo.guid,
        petInfo = self.nextPetInfo,
        index = #self.petListData + 1
      })
      self:initPetList(#self.petListData)
      self:refreshPetListCd(true)
    end, self)
    self.selectedIndex = nil
    self.lastCost = nil
    self.cost = nil
    self:refreshPetListCd(true)
    self.bind.fightTipActive = false
    L_TimerManager:newOrResetTimer(self, "nextCardShow", function()
      self.modules.nextPet:playNextAnimation("anim_petduel_card_nextcard_show")
      L_TimerManager:stopTimer(self, "nextCardShow")
    end, 0.433)
  end, 0.6)
  local res = {}
  for _, v in pairs(self.petListData) do
    if v.index ~= self.selectedIndex then
      table.insert(res, v)
    end
    if v.index == self.selectedIndex then
      self.formationQueue:enQueue(v.petInfo)
      L_KiBoDuelManager:playerSummonKiBo(v.petInfo)
    end
  end
  table.insert(res, {
    isNext = false,
    guid = self.nextPetInfo.guid,
    petInfo = self.nextPetInfo,
    index = self.selectedIndex
  })
  table.sort(res, function(a, b)
    return a.index < b.index
  end)
  self.petListData = res
end

function this:playCostCastAnimation(cost)
  if cost == nil then
    return
  end
  for i = 1, cost do
    self.bind.costList:getItemCls(i):triggerCast()
  end
  Timer.once(0.1, function()
    for i = 1, cost do
      local index = i
      self.bind.costList:getItemCls(index):setShowAnimator(false)
      Timer.once(0.3, function()
        self.bind.costList:change(index, self.costData[index])
        self.bind.costList:getItemCls(index):setSetelected(false)
        self.bind.costList:getItemCls(index):playForceInit()
        Timer.once(0.1, function()
          self.bind.costList:getItemCls(index):setShowAnimator(true)
        end, self, self.gameObject)
      end, self, self.gameObject)
    end
    Timer.once(0.4, function()
      for i = cost + 1, self.maxCost do
        self.bind.costList:change(i, self.costData[i])
      end
      self.isPlayingCast = false
    end)
  end, self, self.gameObject)
end

function this:getPetDuelCost(id, isTrial)
  if not isTrial then
    local petData = L_PetStore:getPetItem(id)
    if petData then
      return self:getPetCost(petData.id)
    end
  else
    local trialPetTpl = L_GameTpl:getTrialPetTpl()
    local trialTpl = trialPetTpl:getTplById(id)
    local petId = trialPetTpl:getTrialPet(trialTpl)
    return self:getPetCost(petId)
  end
end

function this:getPetCost(petId)
  local tempTpl = templateValueTpl:getTplById(petId)
  local cost = templateValueTpl:getPetBaseAttribute(tempTpl)[L_Const.kiBoDuelEnum.petCost]
  return cost or 0
end

function this:summonCancled()
  self.cost = 0
  self:playSelecedAnimation(self.cost, self.lastCost)
  self.lastCost = self.cost
  self.selectedIndex = nil
  self:refreshPetListStatus(nil, false)
  if self.tipType ~= tipType.Rapid then
    self.bind.fightTipActive = false
  end
end

function this:refreshSummonControl(index)
  if self.selectedIndex == index then
    return
  end
  if index ~= nil and self.petListData[index] then
    L_KiBoDuelManager:setIsPlayAnimation(true)
    Timer.once(0.25, function()
      L_KiBoDuelManager:setIsPlayAnimation(false)
    end)
    self.lastCost = self.cost or 0
    self.cost = self:getPetDuelCost(self.petListData[index].petInfo.id, self.petListData[index].petInfo.is_trial)
    if self.cost > self.currentCost then
      return
    end
    L_AudioUtil.playSound("Play_SFX_System_QiboChallenge_Card_Select")
    self.bind.rect_kiBoDescription = C_Vector2(descriptionOrdinaryPos[index].x, descriptionOrdinaryPos[index].y)
    self.modules.kiBoDescription:initModule(self.petListData[index].petInfo)
    L_KiBoDuelManager:setSummonStatus(L_KiBoDuelManager.summonStausEnum.inSummon)
    local guid = self.petListData[index].petInfo.guid
    C_KiBoDuelLuaWrapper.KiBoSummonStart(guid)
    L_KiBoDuelManager:updatePetHealingIcon()
    self:disposeOpenTipTimer()
    self.bind.fightTipActive = true
    self:refreshSummonField()
    self:playSelecedAnimation(self.cost, self.lastCost)
  end
  self:refreshPetListStatus(index)
  self.selectedIndex = index
end

function this:playSelecedAnimation(cost, lastCost)
  for i = 1, self.maxCost do
    self.bind.costList:getItemCls(i):playSelectedAnimator(i <= cost, lastCost)
  end
end

function this:refreshSummonField()
  if L_KiBoDuelManager:getSummonFieldStatus() then
    self.tipType = tipType.Normal
    self:dealTipShowAnim(L_WordsTpl:getValue("notice_kibo_duel_in_battle_05"))
  else
    self.tipType = tipType.Error
    self:dealTipShowAnim(L_WordsTpl:getValue("notice_kibo_duel_in_battle_06"))
  end
end

function this:refreshPetListStatus(index, isUse)
  for i = 1, #self.bind.petList do
    local value = self.bind.petList:getValue(i, "index")
    self.bind.petList:getItemCls(i):refreshSelect(index == value, isUse)
  end
  self:refreshButtonStatus()
end

function this:refreshKiBoDuelCost(currentCost, nextTime, startTime)
  local tpl = kiBoDuelTpl:getTplById(self.duelId)
  local cost = kiBoDuelTpl:getCost(tpl)
  local maxCost = cost[L_Const.kiBoDuelEnum.costLimit]
  self.maxCost = maxCost
  local inRecover = true
  if not currentCost then
    currentCost = cost[L_Const.kiBoDuelEnum.originalCost]
    inRecover = false
  end
  self.refreshCostTime = nextTime
  local bPlay = false
  if not math.isEmpty(self.currentCost) then
    bPlay = currentCost > self.currentCost
  end
  local bPlayCast = self.currentCost ~= nil and currentCost < self.currentCost
  self.currentCost = currentCost
  if bPlay then
    L_AudioUtil.playSound("Play_SFX_System_QiboChallenge_Energy_Get")
    self.bindComponents.energyAnimator:Play("anim_petduel_energy_num_toNext")
    Timer.once(1, function()
      if not (self.isBind and self.bindComponents) or self.bindComponents.energyAnimator then
        return
      end
      self.bindComponents.energyAnimator:Play("anim_petduel_energy_num_init")
    end, self, self.gameObject)
    Timer.once(0.132, function()
      if not self.isBind then
        return
      end
      self.bind.currentCostNum = currentCost
    end, self, self.gameObject)
  else
    self.bind.currentCostNum = currentCost
  end
  local costData = {}
  for i = 1, maxCost do
    table.insert(costData, {
      refreshCostTime = self.refreshCostTime,
      inRecover = inRecover,
      index = i,
      currentCost = currentCost,
      startTime = startTime
    })
  end
  self.costData = costData
  if bPlayCast then
    self.isPlayingCast = true
    self:playCostCastAnimation(self.cost)
  end
  if inRecover then
    for i = 1, self.maxCost do
      self.bind.costList:change(i, costData[i])
    end
  else
    self.bind.costList:clear()
    self.bind.costList:insert_array(costData)
  end
  self:refreshPetListCd(inRecover)
end

function this:refreshPetListCd(inRecover)
  local tpl = kiBoDuelTpl:getTplById(self.duelId)
  local cost = kiBoDuelTpl:getCost(tpl)
  for i = 1, #self.bind.petList do
    self.bind.petList:getItemCls(i):refreshKiBoDuelCost({
      refreshCostTime = self.refreshCostTime,
      speed = cost[L_Const.kiBoDuelEnum.costRecoverSpeed],
      currentCost = self.currentCost,
      inRecover = inRecover
    })
  end
end

function this:startOpenCountDown()
  printLog("KIBODUEL_DEBUG:startOpenCountDown", self.openedCountDown)
  if self.openedCountDown then
    return
  end
  self.openedCountDown = true
  self.startCountDown = 3
  L_AudioUtil.playSound("Play_SFX_System_QiboChallenge_Begin")
  L_KiBoDuelManager:startDuel()
  self:dealControlInput(true)
  self:playPageEffect(true, true, true)
  self:playCostInitAnimation()
  self.openingTimer = Timer.repeated(1, function()
    self.startCountDown = self.startCountDown - 1
    if self.startCountDown < 1 then
      if self.openingTimer then
        Timer.remove(self.openingTimer)
      end
      self.openingTimer = nil
      return
    end
  end, self, self.gameObject)
  self:setUIActive(false)
  Timer.once(4.45, function()
    if not self.isBind then
      return
    end
    self:setUIActive(true)
    self:dealStart()
  end, self, self.gameObject)
end

function this:playCostInitAnimation()
  for i = 1, self.maxCost do
    self.bind.costList:getItemCls(i):setShowAnimator(false)
  end
  Timer.once(animatorPlayDelay.energyCellShow, function()
    for i = 1, self.maxCost do
      self.bind.costList:getItemCls(i):playInitAnimation(true)
    end
  end, self, self.gameObject)
end

function this:dealControlInput(isShow)
  local uiListener = L_UI._auxiliaries.uiListener.cls
  uiListener:controlCameraLock(self.pageName, isShow)
  if isShow then
    C_InputManager.DeactivatePlayerInput()
  else
    C_InputManager.ActivatePlayerInput()
  end
end

function this:dealStart()
  self:onKiBoDuelEntityCreated()
  self.duelStar = true
  L_KiBoDuelManager:setSummonStatus(L_KiBoDuelManager.summonStausEnum.normal)
  if self.openingTimer then
    Timer.remove(self.openingTimer)
  end
  self.openingTimer = nil
  self:dealControlInput(false)
  C_InputManager.SetInputmap(C_InputManager_MapType.KiBoDuelMap, true)
  L_ShortCutManager:removeShortCut(C_EWorldType.KiboDuel)
  L_ShortCutManager:registerPageMainShortCut(C_EWorldType.KiboDuel)
  self.tipType = tipType.Normal
  self:dealTipShowAnim(L_WordsTpl:getValue("notice_kibo_duel_in_battle_01"))
  printLog("KIBODUEL_DEBUG:dealStart", self.openedCountDown)
  L_PetDuelStore:req_CSProtoKiboRealStart()
  C_DriveManager.DispatchDrive(C_EExternalDrive.KiBoBattleUITimeOver)
  self.openTipTimer = Timer.once(5, function()
    if not self.isBind then
      return
    end
    self.bind.fightTipActive = false
    self:disposeOpenTipTimer()
  end)
  self:setDuelTime()
  self.isSusscess = L_PetDuelStore:getIsSuccess(self.duelId)
end

function this:dealTipShowAnim(strValue)
  self.bind.toggle_fightTip = self.tipType
  if self.bind.fightTipActive then
    self.bind.fightTipActive = false
  end
  self:disposeTimer()
  if self.lastStrValue ~= strValue and not self.isProtect then
    self.bind.fightTipActive = true
    self.bind.fightTipText = strValue
    return
  end
  self.bind.fightTipActive = true
  self.bind.fightTipText = strValue
  self.tipAnimTimer = Timer.once(1.333, function()
    if not self.isBind then
      return
    end
    self.bind.fightTipActive = false
  end, self, self.gameObject)
  self.isProtect = true
  self.protectTimer = Timer.once(0.5, function()
    self.isProtect = false
  end, self, self.gameObject)
  self.lastStrValue = strValue
end

function this:disposeTimer()
  if self.tipAnimTimer then
    Timer.remove(self.tipAnimTimer)
    self.tipAnimTimer = nil
  end
  if self.protectTimer then
    Timer.remove(self.protectTimer)
    self.protectTimer = nil
  end
end

function this:disposeOpenTipTimer()
  if self.openTipTimer then
    Timer.remove(self.openTipTimer)
  end
  self.openTipTimer = nil
end

function this:setDuelTime()
  self:disposeDuelTimer()
  self.duelTimer = Timer.repeated(0.1, function()
    self:setTimeLabel()
  end, self, self.gameObject)
end

function this:setTimeLabel()
  self.leftTime = self.duelTime - math.floor(L_KiBoDuelManager:getDuelTime())
  if self.leftTime < 0 then
    self.leftTime = 0
    self:disposeDuelTimer()
    return
  end
  local rapidTime = self:getRapidTime()
  L_KiBoDuelManager:setRapidState(rapidTime < L_KiBoDuelManager:getDuelTime())
  self.bind.timeText = tostring(self.leftTime)
end

function this:getRapidTime()
  if not self.duelId then
    return 99999999999
  end
  local tpl = kiBoDuelTpl:getTplById(self.duelId)
  local rapidTimes = kiBoDuelTpl:getCostTime(tpl)
  if not rapidTimes and not rapidTimes[1] and not rapidTimes[1][1] then
    return 99999999999
  end
  local rapidTime = rapidTimes[1][1]
  return rapidTime
end

function this:disposeDuelTimer()
  if self.duelTimer then
    Timer.remove(self.duelTimer)
  end
  self.duelTimer = nil
end

function this:refreshButtonStatus()
  self.bind.btnJumpActive = not L_PlayerManager:isInMounting()
  self.bind.btnDogeActive = not L_PlayerManager:isInMounting()
  self.bind.skillBtnNodeActive = not L_KiBoDuelManager:isInSummon()
  self.bind.summonBtnNodeActive = L_KiBoDuelManager:isInSummon()
end

function this:escHandle()
  if L_KiBoDuelManager:isInSummon() then
    L_KiBoDuelManager:handleKiBoSummonCancel()
    return
  end
  if L_KiBoDuelManager:isInReleaseSkill() then
    L_KiBoDuelManager:handleCancelSkillRelease()
    return
  end
  if not self.duelStar then
    return
  end
  self:dealExit()
end

function this:dealExit()
  if C_InputManager.GetCurrentInputMapType() == C_InputManager_MapType.BlanketInputMap then
    return
  end
  local data_tip = {
    txtTitle = L_WordsTpl:getValue("notice_kibo_duel_in_battle_10"),
    txtContent = L_WordsTpl:getValue("notice_kibo_duel_in_battle_11"),
    txtConfirm = L_WordsTpl:getValue("notice_kibo_duel_in_battle_10"),
    confirmCallback = function()
      L_KiBoDuelManager:quitKiBoDuel()
    end,
    pageClosedCallback = function()
      C_WorldProxy:GetInstance():Resume()
    end,
    duelId = self.duelId,
    leftTime = self.leftTime
  }
  C_WorldProxy:GetInstance():Pause()
  L_UI:open("pagePetDuelExit", data_tip)
end

function this:onCampainInfoSync(data)
  self:disposeDuelTimer()
  local isWin = data.finishType == C_EBattlerServerFinishType.Win
  local isFirst = isWin and not self.isSusscess
  local options = {
    winStatus = isWin,
    duelTime = self.leftTime,
    duelId = self.duelId,
    isFirstWin = isFirst,
    blueHp = self.blueHp,
    blueHpPercent = self.blueHp / self.blueMaxHp,
    redHpPercent = self.redHp / self.redMaxHp
  }
  L_UI:open("pagePetFinishDuel", options)
  L_KiBoDuelManager:exitDuel()
end

function this:onStartRapidState(isRapid)
  if isRapid then
    self.isProtect = false
    self.tipType = tipType.Rapid
    self:dealTipShowAnim(L_WordsTpl:getValue("notice_kibo_duel_in_battle_12", {
      [0] = self:getRapidTime()
    }))
    self.isProtect = true
  end
  self:playFeverEffect(isRapid)
end

function this:playFeverEffect(isPlay)
  if isPlay and not L_CommonUtil.isValid(self.feverEffect) then
    L_AudioUtil.playSound("Play_SFX_System_QiboChallenge_RushTime_Begin")
    L_ResPool:asyncGameObject(feverEffectPath, function(go)
      self.feverEffect = go
      local feverTrans = self.feverEffect.transform
      feverTrans:SetParent(C_CameraManager.mainCamera.transform)
      L_Vector3.setLocalPos(feverTrans, L_Vector3.zero)
      L_Vector3.setLocalRot(feverTrans, L_Vector3.zero)
    end)
  end
  if not isPlay and L_CommonUtil.isValid(self.feverEffect) then
    L_AudioUtil.playSound("Play_SFX_System_QiboChallenge_RushTime_End")
    Unity.GameObject.Destroy(self.feverEffect)
    self.feverEffect = nil
  end
  self.bindComponents.energyAnimator:SetBool("Fever", isPlay)
end

function this:onChangeSkillStatus()
  self:refreshButtonStatus()
  local isInReleaseSkill = L_KiBoDuelManager:isInReleaseSkill()
  self:controlCardShow(not isInReleaseSkill)
  self:controlSkillShow(isInReleaseSkill)
end

function this:controlCardShow(isShow)
  self.bindComponents.cardsAnimator:SetBool("PlayAnim", false)
  self.bindComponents.cardsAnimator:SetBool("Show", isShow)
end

function this:controlSkillShow(isShow)
  self.bindComponents.bottomAnimator:SetBool("Skill", isShow)
end

function this:hideBoard()
  self.bind.boardActive = false
end

return this
