local this = class("moduleStarHealing", G_UIModuleBase)
local worldCityTpl = L_GameTpl:getWorldCityTpl()

function this.bind()
  return {
    hintTip_active = false,
    txt_starHealing = "0",
    list_hintTip = {
      moduleName = "pages/main/cellHealingHint"
    },
    go_recovery = false,
    sortingOrder = 0
  }
end

function this.methods()
  return {
    onPointEnter_showTip = function(self)
      local sceneId = AzurWorldInstance.CurWorldId
      local cityTpl = worldCityTpl:getTplById(sceneId)
      if worldCityTpl:getCharge(cityTpl) and worldCityTpl:getCharge(cityTpl) > 0 then
        L_FlyMsgManager:showNormalMsg(L_WordsTpl:getValue("notice_charge_close") or L_WordsTpl:getValue("notice_charge_close_02"))
        return
      end
      self.bind.hintTip_active = true
    end,
    onPointExit_hideTip = function(self)
      self.bind.hintTip_active = false
    end
  }
end

function this:open()
  L_StarHealingStore:listenCallFunc(L_StarHealingStore.event.starHealingChargeRefresh, self.setCharge, self)
  L_StarHealingStore:listenCallFunc(L_StarHealingStore.event.popModuleStartHealing, self.popModuleStartHealing, self)
  self:initCharge()
  self:initSystem()
  self.uiBinding.gameObject:ActiveTrans(not L_DungeonManager:getIsInTrainTaskDungeon())
end

function this:close()
  L_StarHealingStore:unListenCallFunc(L_StarHealingStore.event.starHealingChargeRefresh, self.setCharge)
  L_StarHealingStore:unListenCallFunc(L_StarHealingStore.event.popModuleStartHealing, self.popModuleStartHealing, self)
  self:destroyAllLocker()
end

function this:show()
  self:setCharge()
end

function this:hide()
  self.bind.go_recovery = false
  self.bindComponents.ani_recovery:Stop()
end

function this:initSystem()
  self.systemToTrans = {
    [L_SystemConst.enum.recover] = {
      self.gameObject.transform
    }
  }
  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 this: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 this:destroyAllLocker()
  for _, v in pairs(self.systemToTrans) do
    local locker = v.locker
    if locker then
      L_SystemUnlockManager:removeLocker(locker)
    end
  end
end

function this:setChargeUI(value)
  self.bind.txt_starHealing = L_WordsTpl:getValue("notice_moduleStarHealing", {
    [0] = value
  })
  self:refreshList(value)
  self.bindComponents.meshRenderer_goProgress.materials[0]:SetFloat("_wave_progress", self:mapPercentageToWaveProgress(value))
  if value == 0 then
    self.bindComponents.ani_goProgress:Play("anim_maincity_charge_empty")
  else
    self.bindComponents.ani_goProgress:Play("anim_maincity_charge_reset")
  end
end

function this:initCharge()
  self.bind.go_recovery = false
  self.bindComponents.ani_moduleStarHealing:Play("anim_maincity_charge_out")
  self.aniCharge = false
  local chargeData = L_StarHealingStore:getCharge()
  if chargeData.cur_value == 0 then
    self.bindComponents.ani_goProgress:Play("anim_maincity_charge_empty")
  else
    self.bindComponents.ani_goProgress:Play("anim_maincity_charge_reset")
  end
end

function this:popModuleStartHealing(bIfPop)
  self.bind.sortingOrder = bIfPop and 100 or 0
end

function this:setCharge(isIncrease)
  local chargeData = L_StarHealingStore:getCharge()
  if chargeData.cur_value == 0 then
    self.bindComponents.ani_goProgress:Play("anim_maincity_charge_empty")
  else
    self.bindComponents.ani_goProgress:Play("anim_maincity_charge_reset")
  end
  if not isIncrease then
    self:setChargeUI(chargeData.cur_value)
  else
    self:disposeTween()
    self.bindComponents.ani_goProgress:Stop("anim_maincity_charge_in_wave")
    self.bindComponents.ani_goProgress:Play("anim_maincity_charge_in_wave")
    local chargeBefore = L_StarHealingStore:getOldChargeValue()
    local getter = function()
      return chargeBefore
    end
    local setter = function(r)
      if self.bindComponents and L_CommonUtil.isValid(self.bindComponents.meshRenderer_goProgress) then
        self:setChargeUI(math.floor(r))
      end
    end
    self.increaseTween = DOTween.To(getter, setter, chargeData.cur_value, 1)
    self.increaseTween:SetTarget(self.bindComponents.meshRenderer_goProgress)
  end
end

function this:mapPercentageToWaveProgress(percentage)
  if percentage == 0 then
    return 0.061
  elseif percentage <= 99 then
    return percentage / 99 * 0.8 + 0.061
  else
    return 1
  end
end

function this:disposeTween()
  if self.healingTween then
    self.healingTween:Kill()
    self.healingTween = nil
  end
  if self.increaseTween then
    self.increaseTween:Kill()
    self.increaseTween = nil
  end
end

function this:activate()
  self:open()
  self:openModules()
  self:show()
  self:showModules()
end

function this:deActivate()
  self:hide()
  self:hideModules()
  self:close()
  self:closeModules()
end

function this:refreshList(value)
  local listData = {}
  for i = 1, 3 do
    local tmp = {
      cellId = i,
      hasSelect = true,
      satietyValue = value
    }
    table.insert(listData, tmp)
  end
  self.bind.list_hintTip:clear()
  self.bind.list_hintTip:insert_array(listData)
end

return this
