local this = {}
local eggTpl = L_GameTpl:getPetEggTpl()
local petDna = L_GameTpl:getDnaTpl()
local petHobbyTpl = L_GameTpl:getPetHobbyTpl()
local petInfoTpl = L_GameTpl:getPetTpl()
local _petLearingEnumTpl = L_GameTpl:getPetLearingEnumTpl()
local petLearningAblityTpl = L_GameTpl:getPetLearningAblityTpl()
local petInheritanceTpl = L_GameTpl:getPetAttributeinheritanceTpl()
local petGradeTpl = L_GameTpl:getPetGradeTpl()
local petLevelTpl = L_GameTpl:getPetLevelTpl()
local battleInfoTpl = L_GameTpl:getBattleInfoTpl()
local gameConstTpl = L_GameTpl:getGameConstTpl()
local petVoiceWordsSystemTpl = L_GameTpl:getPetVoiceWordsSystemTpl()
local templateValueTpl = L_GameTpl:getTemplateValueTpl()
local _petFavorabilityTpl = L_GameTpl:getPetFavorabilityTpl()
local csHomeManager, csPetStore

function this:init()
  this.super.init(self)
  self.data = {
    selectGuids = {},
    curSelectedEggGuid = 0,
    curSelectedPetGuid = 0,
    petEggList = {},
    petAttrDic = {},
    petList = {},
    petBoxList = {},
    petBoxNameList = {},
    petBoxIndex = {},
    friendPetList = {},
    petEntityGuidToEntityId = {},
    beta_bgIcon = {
      [1] = "Pet/tex_pet_frame_redonebg",
      [2] = "Pet/tex_pet_frame_greenonebg",
      [3] = "Pet/tex_pet_frame_yellowonebg",
      [4] = "Pet/tex_pet_frame_blueonebg",
      [5] = "Pet/tex_pet_frame_coloronebg"
    },
    alpha_bgIcon = {
      [1] = "Page/Pet/tex_pet_frame_redtwobg",
      [2] = "Page/Pet/tex_pet_frame_greentwobg",
      [3] = "Page/Pet/tex_pet_frame_yellowtwobg",
      [4] = "Page/Pet/tex_pet_frame_bluetwobg",
      [5] = "Page/Pet/tex_pet_frame_colortwobg"
    },
    link_bgIcon = {
      [1] = "Page/Pet/tex_pet_dec_redline",
      [2] = "Page/Pet/tex_pet_dec_greenline",
      [3] = "Page/Pet/tex_pet_dec_yellowline",
      [4] = "Page/Pet/tex_pet_dec_blueline",
      [5] = "Page/Pet/tex_pet_dec_colorline"
    },
    setHasInitSync = false,
    petMaxLevel = tonumber(petLevelTpl:getMaxLevel()),
    free_reward_num = 0,
    petSkillSlotList = gameConstTpl:getValue("PET_SKILLDISPLAY"),
    petSpecialSkill = gameConstTpl:getValue("PET_SIGNATURESKILLLIST"),
    petNormalSkill = gameConstTpl:getValue("PET_SKILLLIST"),
    petRandomSkillRange = gameConstTpl:getValue("PET_RPROPERTYSKILLLIST"),
    petFixedSkillRange = gameConstTpl:getValue("PET_FPROPERTYSKILLLIST"),
    petBreakSkill = gameConstTpl:getValue("PET_BREAKSKILLLIST"),
    petBoxLimit = gameConstTpl:getValue("PET_BOX_LIMIT"),
    petBoxNum = gameConstTpl:getValue("PET_BOX_NUM"),
    petSkillInfoQueue = L_Struct.getQueue(),
    isPlayingEvoTimeLine = false,
    free_egg_reward_num = 0
  }
  self:getInitPetBox()
end

function this:getCurSelectedEggGuid()
  return self.data.curSelectedEggGuid
end

function this:getPetEggList()
  return self.data.petEggList
end

function this:getUnhatchEggNum()
  local num = 0
  for _, v in pairs(self.data.petEggList) do
    if not L_PetStore:checkIsEggHatch(v.guid) then
      num = num + 1
    end
  end
  return num
end

function this:getPetBoxList(index)
  if index == nil then
    return self.data.petBoxList
  end
  if self.data.petBoxList[index] == nil then
    return nil
  end
  return self.data.petBoxList[index]
end

function this:getPetBoxIsFull(index)
  index = index >= self.data.petBoxNum and self.data.petBoxNum or index
  index = index <= 1 and 1 or index
  local count = 0
  for i, v in ipairs(self.data.petBoxList[index]) do
    if math.isEmpty(v) then
      return false, i
    end
    count = count + 1
  end
  return true
end

function this:getPetBoxIsEmpty(index)
  local count = 0
  for i, v in ipairs(self.data.petBoxList[index]) do
    if not math.isEmpty(v) then
      count = count + 1
    end
  end
  if count < 1 then
    return true
  else
    return false
  end
end

function this:getFirstOrderPet()
  for i = 1, 10 do
    if not self:getPetBoxIsEmpty(i) then
      return self:getPetBoxFirstPet(i)
    end
  end
  return nil
end

function this:getPetBoxFirstPet(index)
  for i, v in ipairs(self.data.petBoxList[index]) do
    if not math.isEmpty(v) then
      return v
    end
  end
  return 0
end

function this:getAllPetBoxIsFull()
  for i = 1, self.data.petBoxNum do
    local isFull, emptySlot = self:getPetBoxIsFull(i)
    if not isFull then
      return false, {index = i, slot = emptySlot}
    end
  end
  return true, nil
end

function this:getPetBoxName(index)
  local nameList = self:getPetBoxNameList()
  if not nameList then
    return ""
  end
  return nameList[index] or ""
end

function this:getPetBoxNameList()
  return self.data.petBoxNameList
end

function this:getPetBoxNum()
  return self.data.petBoxNum
end

function this:getInitPetBox()
  for i = 1, self.data.petBoxNum do
    self.data.petBoxList[i] = {}
    self.data.petBoxNameList[i] = L_WordsTpl:getValue("ui_petState", {
      [0] = i
    })
  end
  for _, v in ipairs(self.data.petBoxList) do
    for i = 1, self.data.petBoxLimit do
      v[i] = 0
    end
  end
end

function this:getPetFreeRewardNum()
  return self.data.free_reward_num
end

function this:getPetListCount()
  local count = 0
  for i, _ in pairs(self.data.petList) do
    count = count + 1
  end
  return count
end

function this:getPetCountIsOverBox()
  local count = self:getPetListCount()
  return count >= self.data.petBoxLimit * self.data.petBoxNum
end

function this:getPetList()
  local res = {}
  for _, v in pairs(self.data.petList) do
    if not v:getIsTrial() then
      table.insert(res, v)
    end
  end
  return res
end

function this:getFriendPetList()
  return self.data.friendPetList
end

function this:getPetMaxLevel(isLimit)
  if not isLimit then
    return self.data.petMaxLevel
  end
  local maxLevel = 1
  local curWorldLevel = L_WorldLevelStore:getTaskMaxLevel()
  local tpl = petLevelTpl:getConditionMaxLevel(curWorldLevel)
  if tpl then
    maxLevel = petLevelTpl:getLv(tpl)
    return maxLevel
  end
  return self.data.petMaxLevel
end

function this:getPetEggItem(uid, isCreate)
  local petEggList = self:getPetEggList()
  local entity = petEggList[uid]
  if entity == nil and isCreate then
    entity = require(L_R.store .. "pet.data.petEggItem").new()
    self.data.petEggList[uid] = entity
    entity.guid = uid
  end
  return entity
end

function this:getPetNum(configId)
  local data = {}
  local petList = self:getPetList()
  for _, v in pairs(petList) do
    if v:petCfgId() == configId then
      table.insert(data, v)
    end
  end
  return #data
end

function this:getPetEggNum(configId)
  local data = {}
  local petEggList = self:getPetEggList()
  for i, v in pairs(petEggList) do
    if v.configId == configId then
      table.insert(data, v)
    end
  end
  if table.isEmpty(data) then
    return 0
  end
  return #data
end

local hatchHouseGroupId = 3023

function this:getPetEggUnitState(uid, bldGuid)
  local hatchGuids = L_HomeStore:getHomeBuildingUidsByGroupId(hatchHouseGroupId)
  if not hatchGuids then
    return L_PetConst.PetEggState.Idle, self:getEggIncubationTime(self:getPetEggItem(uid).configId, bldGuid)
  end
  for _, guid in ipairs(hatchGuids) do
    local buildingDatas = L_HomeStore:getHomeBuildingByGuid(guid)
    if buildingDatas.hatch and buildingDatas.hatch.hatch_infos then
      for i = 1, #buildingDatas.hatch.hatch_infos do
        local hatchInfoUnit = buildingDatas.hatch.hatch_infos[i]
        if hatchInfoUnit.egg_guid == uid then
          if hatchInfoUnit.start_time <= 0 then
            return L_PetConst.PetEggState.QueueAndNotHatching, self:getEggIncubationTime(self:getPetEggItem(uid).configId, bldGuid)
          end
          if L_TimeUtil:getServerTime() >= hatchInfoUnit.finish_time then
            return L_PetConst.PetEggState.Hatched
          end
          if L_TimeUtil:getServerTime() >= hatchInfoUnit.start_time then
            local totalTime = hatchInfoUnit.finish_time - hatchInfoUnit.start_time
            return L_PetConst.PetEggState.Hatching, hatchInfoUnit.finish_time - L_TimeUtil:getServerTime(), totalTime
          end
        end
      end
    end
  end
  return L_PetConst.PetEggState.Idle, self:getEggIncubationTime(self:getPetEggItem(uid).configId, bldGuid)
end

function this:checkPetEggInHomeBuilding(eggUid, bldUid)
  local eggState = self:getPetEggUnitState(eggUid)
  if eggState == L_PetConst.PetEggState.Idle then
    return true
  end
  local hatchInfos = self:getHatchQueueInfo(bldUid)
  for i = 1, #hatchInfos do
    local hatchUnitInfo = hatchInfos[i]
    if hatchUnitInfo.egg_guid == eggUid then
      return true
    end
  end
  return false
end

function this:getHatchQueueInfo(guid)
  local buildingDatas = L_HomeStore:getHomeBuildingByGuid(guid)
  if buildingDatas and buildingDatas.hatch and buildingDatas.hatch.hatch_infos then
    return buildingDatas.hatch.hatch_infos
  end
  return {}
end

function this:checkHatchBldInHatchingState(bldUid)
  local hatchInfos = self:getHatchQueueInfo(bldUid)
  for i = 1, #hatchInfos do
    local hatchUnitInfo = hatchInfos[i]
    if hatchUnitInfo.egg_guid > 0 then
      if 0 >= hatchUnitInfo.start_time then
        return true
      elseif L_TimeUtil:getServerTime() < hatchUnitInfo.finish_time then
        return true
      end
    end
  end
  return false
end

function this:getPetItem(uid, isCreate)
  local entity = self.data.petList[uid]
  if entity == nil and isCreate then
    entity = require(L_R.store .. "pet.data.petItem").new()
    self.data.petList[uid] = entity
  end
  return entity
end

function this:getFriendPetItem(pid, guid, isCreate)
  if pid == nil then
    return nil
  end
  if self.data.friendPetList[pid] == nil then
    self.data.friendPetList[pid] = {}
  end
  local friendPetList = self.data.friendPetList[pid]
  local entity = friendPetList[guid]
  if entity == nil and isCreate then
    entity = require(L_R.store .. "pet.data.friendPetItem").new()
    self.data.friendPetList[pid][guid] = entity
  end
  return entity
end

function this:cleanFriendPetList()
  self.data.friendPetList = {}
end

function this:resetSelectGuids()
  self.data.selectGuids = {}
  self:call(self.event.setSelectReleasePet)
end

function this:getSelectGuids()
  return self.data.selectGuids
end

function this:setSelectGuids(guids)
  self.data.selectGuids = guids
  if #self.data.selectGuids ~= 0 then
    local lastGuid = self.data.selectGuids[#self.data.selectGuids]
    self:call(self.event.setSelectReleasePet, lastGuid)
  end
end

function this:setSelectReleasePet(guid)
  local key = table.keyOf(self.data.selectGuids, guid)
  if key ~= nil then
    table.remove(self.data.selectGuids, key)
  else
    table.insert(self.data.selectGuids, guid)
  end
  if #self.data.selectGuids ~= 0 then
    local lastGuid = self.data.selectGuids[#self.data.selectGuids]
    self:call(self.event.setSelectReleasePet, lastGuid)
  else
    self:call(self.event.setSelectReleasePet, guid)
  end
end

function this:setCurSelectPetId(guid)
  self.data.curSelectedPetGuid = guid
  self:call(self.event.setCurPetId, guid)
end

function this:getCurSelectPetId()
  return self.data.curSelectedPetGuid
end

function this:getPetSkillInfoQueue()
  return self.data.petSkillInfoQueue
end

function this:getIsPlayingTimeLine()
  return self.data.isPlayingEvoTimeLine
end

function this:setIsPlayingTimeLine(bool)
  self.data.isPlayingEvoTimeLine = bool
end

function this:getEggIncubationTime(petEggConfigId, bldUid)
  local tpl = eggTpl:getTplById(petEggConfigId)
  local IncubationTime = eggTpl:getEggTime(tpl)
  bldUid = bldUid or 0
  local bldDatas = L_HomeStore:getHomeBuildingByGuid(bldUid)
  if bldDatas then
    local decreaseValue = L_HomeBuffManager:getPetEggHatchTimeValue(petEggConfigId, L_HomeBuffManager:getPetEggHatchCondition(petEggConfigId), {
      petGuid = bldDatas.station_pet_guid
    })
    local decreasePercent = L_HomeBuffManager:getPetEggHatchTimePercent(petEggConfigId, L_HomeBuffManager:getPetEggHatchCondition(petEggConfigId), {
      petGuid = bldDatas.station_pet_guid
    })
    IncubationTime = IncubationTime * (1 - decreasePercent)
    IncubationTime = IncubationTime - decreaseValue
  end
  IncubationTime = math.floor(IncubationTime)
  local hatchMinTime = gameConstTpl:getValue("HOME_HATCH_BOTTOM_TIME")
  IncubationTime = IncubationTime >= hatchMinTime and IncubationTime or hatchMinTime
  return IncubationTime
end

function this:getEggElementId(uid)
  local tpl = eggTpl:getTplById(uid)
  local elementId = eggTpl:getElement(tpl)
  return elementId
end

function this:getPetAttrInfo(petGuid)
  local attrInfo = self.data.petAttrDic[petGuid]
  if attrInfo == nil then
    attrInfo = require(L_R.store .. "pet.data.petAttrInfo").new(petGuid)
    self.data.petAttrDic[petGuid] = attrInfo
  end
  return attrInfo
end

function this:getPetPropertyMap(petGuid)
  local info = self:getPetAttrInfo(petGuid)
  return info.attrMap
end

function this:getPetPropertyInherentSkills(petGuid)
  local info = self:getPetAttrInfo(petGuid)
  return info.inherentSkills
end

function this:getPetPropertyGeneSkills(petGuid)
  local info = self:getPetAttrInfo(petGuid)
  return info.geneSkills
end

function this:getFilterPetData(petList, compareData)
  if table.isEmpty(petList) then
    return {}
  end
  local countList = {}
  for _, v in pairs(petList) do
    table.insert(countList, v)
  end
  if table.isEmpty(compareData) then
    return countList
  end
  local tempList = {}
  for k, n in pairs(compareData.raceFilter) do
    tempList[n] = n
  end
  local recoredMove = {}
  for k, n in pairs(countList) do
    local isExsist = false
    for i, v in pairs(n.race) do
      if tempList[v] ~= nil and not table.isEmpty(tempList) then
        isExsist = true
      end
    end
    if isExsist == false and not table.isEmpty(tempList) then
      table.insert(recoredMove, n.guid)
    end
  end
  for i, v in pairs(recoredMove) do
    for k, n in pairs(countList) do
      if n.guid == v then
        table.remove(countList, k)
        break
      end
    end
  end
  tempList = {}
  for k, n in pairs(compareData.elementFilter) do
    tempList[n] = n
  end
  recoredMove = {}
  for k, n in pairs(countList) do
    local isExsist = false
    for i, v in pairs(n.element) do
      if tempList[v] ~= nil and not table.isEmpty(tempList) then
        isExsist = true
      end
    end
    if isExsist == false and not table.isEmpty(tempList) then
      table.insert(recoredMove, n.guid)
    end
  end
  for i, v in pairs(recoredMove) do
    for k, n in pairs(countList) do
      if n.guid == v then
        table.remove(countList, k)
        break
      end
    end
  end
  tempList = {}
  for k, n in pairs(compareData.rideFilter) do
    tempList[n] = n
  end
  recoredMove = {}
  for k, n in pairs(countList) do
    local isExsist = false
    local index = {}
    if not math.isEmpty(n.speed) then
      table.insert(index, 1)
    end
    if petInfoTpl:getIsBattle(petInfoTpl:getTplById(n.id)) then
      table.insert(index, 2)
    end
    for i, v in pairs(index) do
      if tempList[v] ~= nil and not table.isEmpty(tempList) then
        isExsist = true
      end
    end
    if isExsist == false and not table.isEmpty(tempList) then
      table.insert(recoredMove, n.guid)
    end
  end
  for i, v in pairs(recoredMove) do
    for k, n in pairs(countList) do
      if n.guid == v then
        table.remove(countList, k)
        break
      end
    end
  end
  return countList
end

function this:getPetGene(guid, gene_id)
  local pet = self:getPetItem(guid)
  if pet ~= nil then
    local petGene = pet.gene_infos
    for i, v in pairs(petGene) do
      if v.gene_id == gene_id then
        local skillLevelTpl = L_GameTpl:getSkillLevelTpl()
        local skillTpl = L_GameTpl:getSkillTpl()
        local tpl = skillLevelTpl:getTplByIdAndLevel(v.gene_id, v.gene_lv)
        if tpl ~= nil then
          local nameTpl = skillTpl:getTplById(tonumber(skillLevelTpl:getSkillGroupId(tpl)))
          local dnaTpl = petDna:getTplById(tonumber(skillLevelTpl:getSkillGroupId(tpl)))
          local dnaRarity = petDna:getRarity(dnaTpl)
          local dnaIcon = petDna:getIcon(dnaTpl)
          local skillName = skillTpl:getName(nameTpl)
          local dnaLength = petDna:getLength(dnaTpl)
          local skillDescribe = skillLevelTpl:getSkillDescribe(tpl)
          local data = {
            geneId = v.gene_id,
            lv = v.gene_lv,
            describe = skillDescribe,
            name = skillName,
            starLv = v.gene_lv,
            rarity = dnaRarity,
            length = dnaLength,
            icon = dnaIcon
          }
          return data
        end
      end
    end
  end
  return nil
end

function this:getNewSkillSlotInfo(petData, petSlotInfo, add_guid)
  add_guid = add_guid or {}
  local updateSkill = {}
  local newSkill = {}
  local convertSkill = {}
  petData.id = petData.config_id
  petData.skills = petData.inherent_skills
  local innerSkills = self:getPetSkills(petData, false, false, true)
  local targetSlotList = {}
  for i, v in pairs(innerSkills) do
    targetSlotList[v.skillSlot] = v.skillSlot
  end
  local skill = petData.inherent_skills or {}
  petSlotInfo = petSlotInfo or {}
  local isNewPet = false
  if not table.isEmpty(add_guid) then
    for i, v in pairs(add_guid) do
      if v == petData.guid then
        isNewPet = true
        break
      end
    end
  end
  for _, v in pairs(skill) do
    if targetSlotList[v.skill_slot] then
      local curSlotData = petSlotInfo[v.skill_slot]
      if curSlotData == nil then
        table.insert(newSkill, v)
        petSlotInfo[v.skill_slot] = v
      elseif curSlotData.skill_id ~= v.skill_id or curSlotData.skill_lv ~= v.skill_lv then
        v.oldInfo = petSlotInfo[v.skill_slot]
        if curSlotData.skill_id ~= v.skill_id then
          table.insert(convertSkill, {old_Skill = curSlotData, convert_Skill = v})
        else
          table.insert(updateSkill, v)
        end
        petSlotInfo[v.skill_slot] = v
      end
    end
  end
  if 0 < #updateSkill and self.data.setHasInitSync == true and not isNewPet then
    self:call(self.event.updatePetSkill, updateSkill, 2)
  end
  if 0 < #newSkill and self.data.setHasInitSync == true and not isNewPet then
    self:call(self.event.getNewPetSkill, newSkill, 1)
  end
  if 0 < #convertSkill and self.data.setHasInitSync == true and not isNewPet then
    self:call(self.event.convertPetSkill, convertSkill, 3)
  end
  return petSlotInfo
end

function this:getAllPetEggGuid()
  local guidList = {}
  for i, v in pairs(self.data.petEggList) do
    table.insert(guidList, v.guid)
  end
  return guidList
end

function this:getPetFeatureSkill(pet)
  local innerSkills = pet.skills or {}
  local skillLevelTpl = L_GameTpl:getSkillLevelTpl()
  local skillTpl = L_GameTpl:getSkillTpl()
  local randomSlot = self.data.petRandomSkillRange
  local fixedSlot = self.data.petFixedSkillRange
  local featureList = {}
  for _, n in pairs(innerSkills) do
    if n.skill_slot <= randomSlot[2] and n.skill_slot >= randomSlot[1] then
      table.insert(featureList, n)
    elseif n.skill_slot <= fixedSlot[2] and n.skill_slot >= fixedSlot[1] then
      table.insert(featureList, n)
    end
  end
  local freatureSkill = {}
  for i, v in pairs(featureList) do
    local tpl = skillLevelTpl:getTplByIdAndLevel(v.skill_id, v.skill_lv)
    if tpl ~= nil then
      local skillId = skillLevelTpl:getSkillGroupId(tpl)
      local nameTpl = skillTpl:getTplById(tonumber(skillId))
      local skillName = skillTpl:getName(nameTpl)
      local skillDescribe = skillLevelTpl:getSkillDescribe(tpl)
      local skillIcon = skillTpl:getIcon(nameTpl)
      table.insert(freatureSkill, {
        index = v.skill_id,
        skillLv = "Lv." .. v.skill_lv,
        skillLevelShow = false,
        levelLabel = true,
        itemIcon = skillIcon,
        describe = skillDescribe,
        skillName = skillName,
        skillSlot = v.skill_slot,
        skillElement = skillTpl:getSkillElement(nameTpl)
      })
    end
  end
  return freatureSkill
end

function this:getPetSkills(pet, showLockSkills, showGeneSkills, showInnerSkills)
  local innerSkills = pet.skills or {}
  local geneSkills = pet.gene_infos or {}
  local innerData = {}
  if showInnerSkills == true then
    local tpl = petInfoTpl:getTplById(pet.id)
    local fixedSkillList = petInfoTpl:getFixedSkillList(tpl)
    local filter = {}
    for i, v in pairs(fixedSkillList) do
      filter[i] = v
    end
    local specialSkill = {}
    local normalSkill = {}
    local breakSkill = {}
    local totalSkill = {}
    for _, v in pairs(innerSkills) do
      if v.skill_slot == self.data.petSpecialSkill then
        table.insert(specialSkill, v)
      end
      if v.skill_slot >= self.data.petNormalSkill[1] and v.skill_slot <= self.data.petNormalSkill[2] and filter[v.skill_slot] == nil then
        table.insert(normalSkill, v)
      end
      if v.skill_slot == self.data.petBreakSkill then
        table.insert(breakSkill, v)
      end
    end
    table.fill(totalSkill, specialSkill)
    table.fill(totalSkill, normalSkill)
    table.fill(totalSkill, breakSkill)
    for i, v in ipairs(totalSkill) do
      local skillLevelTpl = L_GameTpl:getSkillLevelTpl()
      local skillTpl = L_GameTpl:getSkillTpl()
      local tpl = skillLevelTpl:getTplByIdAndLevel(v.skill_id, v.skill_lv)
      if tpl ~= nil then
        local skillId = skillLevelTpl:getSkillGroupId(tpl)
        local nameTpl = skillTpl:getTplById(tonumber(skillId))
        local skillName = skillTpl:getName(nameTpl)
        local skillDescribe = skillLevelTpl:getSkillDescribe(tpl)
        local skillIcon = skillTpl:getIcon(nameTpl)
        table.insert(innerData, {
          index = v.skill_slot,
          skillLv = "Lv." .. v.skill_lv,
          skillId = v.skill_id,
          skillLevelShow = false,
          levelLabel = true,
          itemIcon = skillIcon,
          describe = skillDescribe,
          skillName = skillName,
          skillElement = skillTpl:getSkillElement(nameTpl),
          skillSlot = v.skill_slot
        })
      end
    end
  end
  local data = {}
  if showGeneSkills == true then
    local unlockConditions = L_PetManager:getGeneUnlockConditions()
    if geneSkills ~= nil then
      for _, n in pairs(geneSkills) do
        local lock = pet.lv < (unlockConditions[n.pos] or 0)
        local skillLevelTpl = L_GameTpl:getSkillLevelTpl()
        local skillTpl = L_GameTpl:getSkillTpl()
        local tpl = skillLevelTpl:getTplByIdAndLevel(n.gene_id, 1)
        if showLockSkills == false then
          if lock == false and tpl ~= nil then
            local nameTpl = skillTpl:getTplById(tonumber(skillLevelTpl:getSkillGroupId(tpl)))
            local dnaTpl = petDna:getTplById(tonumber(skillLevelTpl:getSkillGroupId(tpl)))
            local dnaRarity = petDna:getRarity(dnaTpl)
            local skillName = skillTpl:getName(nameTpl)
            local skillDescribe = skillLevelTpl:getSkillDescribe(tpl)
            local skillIcon = skillTpl:getIcon(nameTpl)
            table.insert(data, {
              index = n.gene_id,
              geneId = n.gene_id,
              skillLv = "Lv." .. n.gene_lv,
              skillLevelShow = n.gene_lv ~= 0,
              levelLabel = false,
              itemIcon = skillIcon,
              describe = skillDescribe,
              skillName = skillName,
              starLv = n.gene_lv,
              rarity = dnaRarity,
              genePos = n.pos,
              petId = pet.guid
            })
          end
        elseif tpl ~= nil then
          local nameTpl = skillTpl:getTplById(tonumber(skillLevelTpl:getSkillGroupId(tpl)))
          local dnaTpl = petDna:getTplById(tonumber(skillLevelTpl:getSkillGroupId(tpl)))
          local dnaRarity = petDna:getRarity(dnaTpl)
          local skillName = skillTpl:getName(nameTpl)
          local skillDescribe = skillLevelTpl:getSkillDescribe(tpl)
          local skillIcon = skillTpl:getIcon(nameTpl)
          table.insert(data, {
            index = n.gene_id,
            geneId = n.gene_id,
            skillLv = "Lv." .. n.gene_lv,
            skillLevelShow = n.gene_lv ~= 0,
            levelLabel = false,
            itemIcon = skillIcon,
            describe = skillDescribe,
            skillName = skillName,
            starLv = n.gene_lv,
            rarity = dnaRarity,
            genePos = n.pos,
            show_lockBg = lock == true,
            petId = pet.guid
          })
        end
      end
    end
  end
  local list = {}
  for i, v in pairs(innerData) do
    table.insert(list, v)
  end
  for i, v in pairs(data) do
    table.insert(list, v)
  end
  if showGeneSkills == false and showInnerSkills == true then
    return innerData
  end
  return list
end

function this:getPetComprehension(petData)
  local comprehension = petData.comprehension
  local comprehensionLst = {}
  for i, v in pairs(comprehension) do
    table.insert(comprehensionLst, v)
  end
  local comprehensionSortList = {}
  for i = 1, #comprehensionLst do
    local enumNum = _petLearingEnumTpl:getEnumNum(_petLearingEnumTpl:getTplById(i))
    for n, k in pairs(comprehensionLst) do
      if k.attr_id == enumNum then
        comprehensionSortList[i] = k
        break
      end
    end
  end
  local comprehensionLstRank = {}
  for i = 1, #comprehensionSortList do
    local enumData = _petLearingEnumTpl:getTplByEnumId(comprehensionSortList[i].attr_id)
    local comprehensionRangeList = petLearningAblityTpl:getTplByEnumId(enumData.id)
    for k, v in pairs(comprehensionRangeList) do
      if comprehensionSortList[i].value <= v.range[2] and comprehensionSortList[i].value > v.range[1] then
        comprehensionLstRank[i] = {
          id = v.id,
          enumId = comprehensionSortList[i].attr_id
        }
        break
      end
    end
  end
  local property = {}
  property.comprehensionRank = comprehensionLstRank
  return property
end

function this:getPetProperty(petData, lv, rankUpPetId, debug)
  local tempLv = lv or petData.lv
  local baseValue = templateValueTpl:getPetConfigAtt(petData.id, tempLv)
  local heroInheritance = {}
  local petLv_limit_switch = L_GameConstTpl:getValue("PET_LEVEL_LIMIT_SWITCH")
  if not math.isEmpty(petData.hero_id) then
    local hero = L_HeroStore:getHero(petData.hero_id)
    local heroLevel = L_HeroStore:getHeroLevel(hero)
    if heroLevel <= petData.lv and petLv_limit_switch == 1 then
      tempLv = heroLevel
    end
    heroInheritance = self:getHeroInheritanceAttr(hero, petData.favor_lv or 0)
  end
  if rankUpPetId ~= nil then
    baseValue = templateValueTpl:getPetConfigAtt(rankUpPetId, tempLv)
  end
  local comprehension = petData.comprehension
  local comprehensionLst = {}
  for i, v in pairs(comprehension) do
    table.insert(comprehensionLst, v)
  end
  local comprehensionSortList = {}
  for i = 1, #comprehensionLst do
    if _petLearingEnumTpl:getTplById(i) then
      local enumNum = _petLearingEnumTpl:getEnumNum(_petLearingEnumTpl:getTplById(i))
      for _, k in ipairs(comprehensionLst) do
        if k.attr_id == enumNum then
          comprehensionSortList[i] = k
          break
        end
      end
    end
  end
  local comprehensionLstRank = {}
  for i = 1, #comprehensionSortList do
    local enumData = _petLearingEnumTpl:getTplByEnumId(comprehensionSortList[i].attr_id)
    local comprehensionRangeList = petLearningAblityTpl:getTplByEnumId(enumData.id)
    for k, v in pairs(comprehensionRangeList) do
      if comprehensionSortList[i].value <= v.range[2] and comprehensionSortList[i].value > v.range[1] then
        comprehensionLstRank[i] = {
          id = v.id,
          enumId = comprehensionSortList[i].attr_id
        }
        break
      end
    end
  end
  local hobbyTpl = petHobbyTpl:getTplById(petData.feature)
  local factors = petHobbyTpl:getBaseAttribute(hobbyTpl)
  local hobbyFactor = {}
  local petbaseAttributeList = {}
  local comprehensionFactor = {}
  for i = 1, #_petLearingEnumTpl:getAllEnum() do
    petbaseAttributeList[i] = baseValue[_petLearingEnumTpl:getEnumNum(_petLearingEnumTpl:getTplById(i))]
    hobbyFactor[i] = factors[_petLearingEnumTpl:getEnumNum(_petLearingEnumTpl:getTplById(i))]
    heroInheritance[i] = heroInheritance[i] or 0
    for _, v in pairs(comprehensionLst) do
      if _petLearingEnumTpl:getEnumNum(_petLearingEnumTpl:getTplById(i)) == v.attr_id then
        comprehensionFactor[i] = v.value / 100
        break
      end
    end
  end
  local property, finishGroup = self:getAttribute(petbaseAttributeList, hobbyFactor, comprehensionFactor, heroInheritance)
  local extraHeritance = {}
  if not math.isEmpty(petData.hero_id) then
    local hero = L_HeroStore:getHero(petData.hero_id)
    extraHeritance = self:getExtraInheritanceAttr(hero, finishGroup, petData.favor_lv or 0)
  end
  local catalogAttr = L_CatalogStore:getPetAllAttr(petData.id)
  for i, v in pairs(catalogAttr) do
    if not extraHeritance[i] then
      extraHeritance[i] = 0
    end
    extraHeritance[i] = extraHeritance[i] + v
  end
  local debugStrs = {}
  if debug then
    for i = 1, 6 do
      local debugStr = ""
      debugStr = debugStr .. L_WordsTpl:getValue("ui_systemMessage_25") .. petbaseAttributeList[i]
      debugStr = debugStr .. L_WordsTpl:getValue("ui_pageHomeCenterPetStationedManage_01") .. tempLv
      debugStr = debugStr .. L_WordsTpl:getValue("ui_systemMessage_26") .. hobbyFactor[i]
      debugStr = debugStr .. L_WordsTpl:getValue("ui_systemMessage_27") .. comprehensionFactor[i]
      debugStr = debugStr .. L_WordsTpl:getValue("ui_systemMessage_28") .. heroInheritance[i]
      debugStrs[i] = debugStr
    end
  end
  local forBattleProperty = self:getBattleStructProperty(petbaseAttributeList, hobbyFactor, comprehensionFactor, heroInheritance, baseValue, extraHeritance)
  for i, v in pairs(property) do
    baseValue[i] = v
  end
  for i, v in pairs(extraHeritance) do
    baseValue[i] = baseValue[i] + v
  end
  property = baseValue
  property.battlStructProperty = forBattleProperty
  property.comprehensionRank = comprehensionLstRank
  local grade, gradeRank = L_PetStore:getPetGradeNew(petData.guid)
  property.grade = grade
  property.gradeRank = gradeRank
  return property, debugStrs
end

function this:getPetOriginalProperty(petData, lv, rankUpPetId)
  local tempLv = lv or petData.lv
  local baseValue = templateValueTpl:getPetConfigAtt(petData.id, tempLv)
  if rankUpPetId ~= nil then
    baseValue = templateValueTpl:getPetConfigAtt(rankUpPetId, tempLv)
  end
  local comprehension = petData.comprehension
  local comprehensionList = {}
  for i, v in pairs(comprehension) do
    table.insert(comprehensionList, v)
  end
  local comprehensionSortList = {}
  for i = 1, #comprehensionList do
    local enumNum = _petLearingEnumTpl:getEnumNum(_petLearingEnumTpl:getTplById(i))
    for _, v in pairs(comprehensionList) do
      if v.attr_id == enumNum then
        comprehensionSortList[i] = v
        break
      end
    end
  end
  local comprehensionLstRank = {}
  for i = 1, #comprehensionSortList do
    local enumData = _petLearingEnumTpl:getTplByEnumId(comprehensionSortList[i].attr_id)
    local comprehensionRangeList = petLearningAblityTpl:getTplByEnumId(enumData.id)
    for k, v in pairs(comprehensionRangeList) do
      if comprehensionSortList[i].value <= v.range[2] and comprehensionSortList[i].value > v.range[1] then
        comprehensionLstRank[i] = {
          id = v.id,
          enumId = comprehensionSortList[i].attr_id
        }
        break
      end
    end
  end
  local hobbyTpl = petHobbyTpl:getTplById(petData.feature)
  local factors = petHobbyTpl:getBaseAttribute(hobbyTpl)
  local hobbyFactor = {}
  local petbaseAttributeList = {}
  local comprehensionFactor = {}
  for i = 1, #_petLearingEnumTpl:getAllEnum() do
    petbaseAttributeList[i] = baseValue[_petLearingEnumTpl:getEnumNum(_petLearingEnumTpl:getTplById(i))]
    hobbyFactor[i] = factors[_petLearingEnumTpl:getEnumNum(_petLearingEnumTpl:getTplById(i))]
    for _, v in pairs(comprehensionList) do
      if _petLearingEnumTpl:getEnumNum(_petLearingEnumTpl:getTplById(i)) == v.attr_id then
        comprehensionFactor[i] = v.value / 100
        break
      end
    end
  end
  local property, _ = self:getAttribute(petbaseAttributeList, hobbyFactor, comprehensionFactor, {})
  for i, v in pairs(property) do
    baseValue[i] = v
  end
  local catalogAttr = L_CatalogStore:getPetAllAttr(petData.id)
  for i, v in pairs(catalogAttr) do
    baseValue[i] = baseValue[i] + v
  end
  property = baseValue
  property.comprehensionRank = comprehensionLstRank
  property.grade, property.gradeRank = L_PetStore:getPetGradeNew(petData.guid)
  return property
end

function this:getAttribute(baseValue, hobbyFactor, comprehension, heroInheritance)
  local newValue = {}
  local finishAttrId = {}
  for i, v in ipairs(baseValue) do
    local attrEnumId = _petLearingEnumTpl:getEnumNum(_petLearingEnumTpl:getTplById(i))
    heroInheritance[i] = heroInheritance[i] or 0
    if battleInfoTpl:getHasGroup(attrEnumId) then
      local group = battleInfoTpl:getGroupById(attrEnumId)
      local basicId = battleInfoTpl:getAttrVal(group[1])
      local perId = battleInfoTpl:getAttrVal(group[2])
      local extraId = battleInfoTpl:getAttrVal(group[3])
      newValue[basicId] = 0
      newValue[perId] = 0
      newValue[extraId] = 0
      finishAttrId[basicId] = 1
      finishAttrId[perId] = 1
      finishAttrId[extraId] = 1
      if battleInfoTpl:getIsRatio(battleInfoTpl:getTplById(attrEnumId)) == 0 then
        local data = v * hobbyFactor[i] * comprehension[i]
        newValue[basicId] = math.integrate(data)
        newValue[extraId] = math.floor(heroInheritance[i])
      else
        newValue[basicId] = math.floor(v + hobbyFactor[i] * 100 + comprehension[i] * 100)
        newValue[extraId] = math.floor(heroInheritance[i])
      end
    else
      local base, extra = 0
      finishAttrId[attrEnumId] = 1
      if battleInfoTpl:getIsRatio(battleInfoTpl:getTplById(attrEnumId)) == 0 then
        base = v * hobbyFactor[i] * comprehension[i]
        extra = heroInheritance[i]
        newValue[attrEnumId] = math.floor(base + extra)
      else
        base = v + hobbyFactor[i] * 100 + comprehension[i] * 100
        extra = heroInheritance[i]
        newValue[attrEnumId] = math.floor(base + extra)
      end
    end
  end
  return newValue, finishAttrId
end

function this:getPetAttFinalValue(petProperty, attrEnumId, petGuid)
  local value
  if battleInfoTpl:getHasGroup(attrEnumId) then
    local group = battleInfoTpl:getGroupById(attrEnumId)
    local basicId = battleInfoTpl:getAttrVal(group[1])
    local perId = battleInfoTpl:getAttrVal(group[2])
    local extraId = battleInfoTpl:getAttrVal(group[3])
    petProperty[basicId] = petProperty[basicId] or 0
    petProperty[perId] = 0
    petProperty[extraId] = petProperty[extraId] or 0
    value = math.floor(petProperty[basicId] + petProperty[extraId])
  else
    value = petProperty[attrEnumId] and math.floor(petProperty[attrEnumId]) or 0
  end
  if petGuid ~= nil then
    local battleValue = self:getPetAttributeValueInFormation(petGuid, attrEnumId)
    if battleValue ~= nil then
      value = battleValue
    end
  end
  return value
end

function this:getPetAttributeValueInFormation(petGuid, attrId)
  local posIndexInFormation = L_FormationStore:getPetPlaceInTeam(L_FormationManager:getCurFormationType(), nil, petGuid)
  if not math.isEmpty(posIndexInFormation) then
    local petCsEntity = L_PlayerManager:getPlayerUnit():getPetEntityByPosIndex_cs(posIndexInFormation)
    if petCsEntity then
      local aliveProperty = petCsEntity.data.aliveProperty
      local current = C_MyFloatUtility.GetFloat(aliveProperty:GetBattlePropertyCurrentValue(attrId))
      return math.floor(current)
    end
  end
end

function this:getPetAttSplitValue(petProperty, attrEnumId, petGuid)
  local baseValue, addValue
  if battleInfoTpl:getHasGroup(attrEnumId) then
    local tpl_tmp = battleInfoTpl:getTplById(attrEnumId)
    local groupId = battleInfoTpl:getGroupId(tpl_tmp)
    local group = battleInfoTpl:getGroupById(attrEnumId)
    local basicId = battleInfoTpl:getAttrVal(group[1])
    local perId = battleInfoTpl:getAttrVal(group[2])
    local extraId = battleInfoTpl:getAttrVal(group[3])
    petProperty[basicId] = petProperty[basicId] or 0
    petProperty[perId] = petProperty[perId] or 0
    petProperty[extraId] = petProperty[extraId] or 0
    baseValue = petProperty[basicId] or 0
    addValue = petProperty[extraId]
  else
    baseValue = petProperty[attrEnumId] or 0
    addValue = 0
  end
  if petGuid ~= nil then
    local battleValue = self:getPetAttributeValueInFormation(petGuid, attrEnumId)
    if battleValue ~= nil then
      local diff = battleValue - (baseValue + addValue)
      addValue = addValue + diff
      if diff ~= 0 then
        errorf("\229\165\135\230\179\162\229\137\141\229\144\142\231\171\175\229\177\158\230\128\167\228\184\141\228\184\128\232\135\180,\232\175\183\229\133\179\230\179\168")
        errorf("\229\174\160\231\137\169guid" .. petGuid .. " |\229\174\160\231\137\169\229\177\158\230\128\167\230\152\175\239\188\154" .. attrEnumId .. " |\229\137\141\231\171\175\231\153\189\229\173\151\229\177\158\230\128\167\230\152\175: " .. baseValue .. " |\229\137\141\231\171\175\231\187\191\229\173\151\229\177\158\230\128\167\230\152\175\239\188\154" .. addValue)
        local battleProperty = L_PetStore:getBattleStructPropertyNew(petGuid)
        for k, v in ipairs(battleProperty) do
          if v.id == attrEnumId then
            errorf("\229\174\160\231\137\169guid" .. petGuid .. "|\229\174\160\231\137\169\229\177\158\230\128\167\230\152\175\239\188\154" .. attrEnumId .. " |\229\144\142\231\171\175\231\153\189\229\173\151\229\177\158\230\128\167\230\152\175: " .. v.baseValue .. " |\229\144\142\231\171\175\231\187\191\229\173\151\229\177\158\230\128\167\230\152\175\239\188\154" .. v.extraValue)
          end
        end
      end
    end
  end
  return baseValue, addValue
end

local SpecialExtraSpeedStatusAttrIdEnum = {
  [1039] = 1039,
  [1040] = 1040,
  [1041] = 1041,
  [1042] = 1042
}
local PlayerMountStatueToAttrIdEnum = {
  [L_Const.WorldMapPlayerMountStatusType.WMPMST_GROUND] = 1039,
  [L_Const.WorldMapPlayerMountStatusType.WMPMST_FLY] = 1040,
  [L_Const.WorldMapPlayerMountStatusType.WMPMST_WATER_SURFACE] = 1041,
  [L_Const.WorldMapPlayerMountStatusType.WMPMST_COUNT] = 1042
}

function this:getPetSkillInfo(petGuid)
  local skillInfos = {}
  local inherentSkills = self:getPetPropertyInherentSkills(petGuid)
  for _, v in ipairs(inherentSkills) do
    table.insert(skillInfos, v)
  end
  local geneSkills = L_PetStore:getPetPropertyGeneSkills(petGuid)
  for _, v in ipairs(geneSkills) do
    table.insert(skillInfos, v)
  end
  return skillInfos
end

function this:getBattleStructPropertyNew(petGuid)
  local petAtrrMap = self:getPetPropertyMap(petGuid)
  local result = {}
  for arrtId, attrValue in pairs(petAtrrMap) do
    if battleInfoTpl:getHasGroup(arrtId) then
      local battInfoCfg = battleInfoTpl:getTplById(arrtId)
      local groupId = battleInfoTpl:getGroupId(battInfoCfg)
      local groupType = battleInfoTpl:getGroupType(battInfoCfg)
      if not result[groupId] then
        result[groupId] = {
          id = groupId,
          baseValue = 0,
          percent = 0,
          extraValue = 0
        }
      end
      local value = attrValue
      if groupType == 1 then
        result[groupId].baseValue = result[groupId].baseValue + value
      elseif groupType == 2 then
        if battleInfoTpl:getIsRatio(battInfoCfg) == 1 then
          value = value / 10000
        end
        result[groupId].percent = result[groupId].percent + value
      elseif groupType == 3 then
        result[groupId].extraValue = result[groupId].extraValue + value
      end
    else
      local battInfoCfg = battleInfoTpl:getTplById(arrtId)
      if not result[arrtId] then
        result[arrtId] = {
          id = arrtId,
          baseValue = 0,
          percent = 0,
          extraValue = 0
        }
      end
      local value = attrValue
      result[arrtId].baseValue = result[arrtId].baseValue + value
      if SpecialExtraSpeedStatusAttrIdEnum[arrtId] then
        local mountStatus = L_PlayerStore:getMountStatus()
        local attrPropertId = PlayerMountStatueToAttrIdEnum[mountStatus]
        if attrPropertId and arrtId == attrPropertId then
          if battleInfoTpl:getIsRatio(battInfoCfg) == 1 then
            value = value / 10000
          end
          if not result[35] then
            result[35] = {
              id = 35,
              baseValue = 0,
              percent = 0,
              extraValue = 0
            }
          end
          result[35].percent = result[35].percent + value
          if not result[36] then
            result[36] = {
              id = 36,
              baseValue = 0,
              percent = 0,
              extraValue = 0
            }
          end
          result[36].percent = result[36].percent + value
        end
      end
    end
  end
  return table.toArray(result)
end

function this:getBattleStructProperty(baseValue, hobbyFactor, comprehension, heroInheritance, baseAttributeList, extraHeritance)
  local newValue = {}
  local index = {}
  local result = {}
  for i, v in ipairs(baseValue) do
    local attrEnumId = _petLearingEnumTpl:getEnumNum(_petLearingEnumTpl:getTplById(i))
    heroInheritance[i] = heroInheritance[i] or 0
    if battleInfoTpl:getHasGroup(attrEnumId) then
      local group = battleInfoTpl:getGroupById(attrEnumId)
      local basicId = battleInfoTpl:getAttrVal(group[1])
      local perId = battleInfoTpl:getAttrVal(group[2])
      local extraId = battleInfoTpl:getAttrVal(group[3])
      newValue[basicId] = 0
      newValue[perId] = 0
      newValue[extraId] = 0
      if battleInfoTpl:getIsRatio(battleInfoTpl:getTplById(attrEnumId)) == 0 then
        local data = v * hobbyFactor[i] * comprehension[i]
        newValue[basicId] = math.integrate(data)
        newValue[extraId] = math.floor(heroInheritance[i])
      else
        newValue[basicId] = math.floor(v + hobbyFactor[i] * 100 + comprehension[i] * 100)
        newValue[extraId] = math.floor(heroInheritance[i])
      end
      table.insert(result, {
        id = attrEnumId,
        baseValue = newValue[basicId],
        percent = newValue[perId],
        extraValue = newValue[extraId]
      })
    else
      local base, extra = 0
      if battleInfoTpl:getIsRatio(battleInfoTpl:getTplById(attrEnumId)) == 0 then
        base = v * hobbyFactor[i] * comprehension[i]
        extra = heroInheritance[i]
        newValue[attrEnumId] = math.floor(base + extra)
      else
        base = v + hobbyFactor[i] * 100 + comprehension[i] * 100
        extra = heroInheritance[i]
        newValue[attrEnumId] = math.floor(base + extra)
      end
      table.insert(result, {
        id = attrEnumId,
        baseValue = base,
        percent = 0,
        extraValue = extra
      })
    end
    index[attrEnumId] = true
  end
  for i, v in pairs(baseAttributeList) do
    if not index[i] then
      table.insert(result, {
        id = i,
        baseValue = v,
        percent = 0,
        extraValue = extraHeritance[i] == nil and 0 or extraHeritance[i]
      })
      index[i] = true
    end
  end
  return result
end

function this:getInheritanceValue(heroGuid, attrVal, extraAttrVal, adjustment_1, adjustment_2, coefficient)
  local property = L_AttributeManager:getMergeHeroAtt(heroGuid)
  local _, baseValue, addValue = L_AttributeManager:getHeroAttSplitValue(property, attrVal)
  return math.floor((baseValue + adjustment_1) * coefficient) + math.floor((addValue + adjustment_2) * coefficient)
end

function this:getHeroInheritanceAttr(heroData, favorLv)
  local inheritanceAttr = {}
  local coefficient = _petFavorabilityTpl:getLvEffect(favorLv) / 10000
  local heroGuid = L_HeroStore:getHeroGuid(heroData)
  for i = 1, #_petLearingEnumTpl:getAllEnum() do
    local attrId = _petLearingEnumTpl:getEnumNum(_petLearingEnumTpl:getTplById(i))
    local inheritance = petInheritanceTpl:getTplByAttrId(attrId)
    if inheritance ~= nil then
      if inheritance.attrVal == L_Const.battleAtt.ATK then
        inheritanceAttr[i] = self:getInheritanceValue(heroGuid, L_Const.battleAtt.ATK, L_Const.battleAtt.EXTRA_ATK, inheritance.adjustment, petInheritanceTpl:getTplByAttrId(L_Const.battleAtt.EXTRA_ATK).adjustment, coefficient)
      elseif inheritance.attrVal == L_Const.battleAtt.DEF then
        inheritanceAttr[i] = self:getInheritanceValue(heroGuid, L_Const.battleAtt.DEF, L_Const.battleAtt.EXTRA_DEF, inheritance.adjustment, petInheritanceTpl:getTplByAttrId(L_Const.battleAtt.EXTRA_DEF).adjustment, coefficient)
      elseif inheritance.attrVal == L_Const.battleAtt.MDEF then
        inheritanceAttr[i] = self:getInheritanceValue(heroGuid, L_Const.battleAtt.MDEF, L_Const.battleAtt.EXTRA_MDEF, inheritance.adjustment, petInheritanceTpl:getTplByAttrId(L_Const.battleAtt.EXTRA_MDEF).adjustment, coefficient)
      elseif inheritance.attrVal == L_Const.battleAtt.MAXHP then
        inheritanceAttr[i] = self:getInheritanceValue(heroGuid, L_Const.battleAtt.MAXHP, L_Const.battleAtt.EXTRA_MAXHP, inheritance.adjustment, petInheritanceTpl:getTplByAttrId(L_Const.battleAtt.EXTRA_MAXHP).adjustment, coefficient)
      else
        local value_1 = L_AttributeManager:getAttValueByHeroGuid(heroGuid, inheritance.attrVal)
        inheritanceAttr[i] = math.floor((value_1 + inheritance.adjustment) * coefficient)
      end
    end
  end
  return inheritanceAttr
end

function this:getExtraInheritanceAttr(heroData, finishGroup, favorLv)
  local inheritanceAttr = {}
  local coefficient = _petFavorabilityTpl:getLvEffect(favorLv) / 10000
  local heroGuid = L_HeroStore:getHeroGuid(heroData)
  for _, v in pairs(petInheritanceTpl:getAllData()) do
    local attrId = petInheritanceTpl:getAttrVal(v)
    if not finishGroup[attrId] then
      local value_1 = L_AttributeManager:getAttValueByHeroGuid(heroGuid, attrId)
      local adjustment = petInheritanceTpl:getAdjustment(v)
      inheritanceAttr[attrId] = math.floor((value_1 + adjustment) * coefficient)
    end
  end
  return inheritanceAttr
end

function this:getAttrInheritFromHero(heroInfo, favorLv)
  local attr = {}
  local coefficient = _petFavorabilityTpl:getLvEffect(favorLv) / 10000
  local heroGuid = L_HeroStore:getHeroGuid(heroInfo)
  for _, v in pairs(petInheritanceTpl:getAllData()) do
    local attrId = petInheritanceTpl:getAttrVal(v)
    if attrId ~= L_Const.battleAtt.EXTRA_ATK and attrId ~= L_Const.battleAtt.EXTRA_DEF and attrId ~= L_Const.battleAtt.EXTRA_MDEF and attrId ~= L_Const.battleAtt.EXTRA_MAXHP then
      local value = 0
      local adjustment = petInheritanceTpl:getAdjustment(v)
      if attrId == L_Const.battleAtt.ATK then
        value = self:getInheritanceValue(heroGuid, L_Const.battleAtt.ATK, L_Const.battleAtt.EXTRA_ATK, adjustment, petInheritanceTpl:getTplByAttrId(L_Const.battleAtt.EXTRA_ATK).adjustment, coefficient)
      elseif attrId == L_Const.battleAtt.DEF then
        value = self:getInheritanceValue(heroGuid, L_Const.battleAtt.DEF, L_Const.battleAtt.EXTRA_DEF, adjustment, petInheritanceTpl:getTplByAttrId(L_Const.battleAtt.EXTRA_DEF).adjustment, coefficient)
      elseif attrId == L_Const.battleAtt.MDEF then
        value = self:getInheritanceValue(heroGuid, L_Const.battleAtt.MDEF, L_Const.battleAtt.EXTRA_MDEF, adjustment, petInheritanceTpl:getTplByAttrId(L_Const.battleAtt.EXTRA_MDEF).adjustment, coefficient)
      elseif attrId == L_Const.battleAtt.MAXHP then
        value = self:getInheritanceValue(heroGuid, L_Const.battleAtt.MAXHP, L_Const.battleAtt.EXTRA_MAXHP, adjustment, petInheritanceTpl:getTplByAttrId(L_Const.battleAtt.EXTRA_MAXHP).adjustment, coefficient)
      else
        local value_1 = L_AttributeManager:getAttValueByHeroGuid(heroGuid, attrId)
        value = math.floor((value_1 + adjustment) * coefficient)
      end
      attr[attrId] = value
    end
  end
  return attr
end

function this:getPetGeneValue(petGene, lockState)
  local totalGeneValue = 0
  local gene = petGene or {}
  for i, v in pairs(gene) do
    local index = math.ceil(v.pos / 2)
    local lock = lockState < index and true or false
    if not lock then
      local petDnaTpl = petDna:getTplById(v.gene_id)
      local rarity = petDna:getRarity(petDnaTpl)
      totalGeneValue = totalGeneValue + v.gene_lv * rarity
    end
  end
  return totalGeneValue
end

function this:judgePetHasSpecialGene(petGuid)
  local petItem = self:getPetItem(petGuid)
  if not petItem then
    return false
  end
  return petItem:hasFlashGene()
end

function this:getPetGradeNew(petGuid)
  local petItem = self:getPetItem(petGuid)
  if not petItem then
    return 0, 0
  end
  local totalScore = petItem:getPetGrade()
  local gradeRank = self:calGradeRank(totalScore)
  return totalScore, gradeRank
end

function this:calGradeRank(totalScore)
  local minScore = gameConstTpl:getValue("PET_GRADE_SCORE_MIN")
  totalScore = math.max(totalScore, minScore)
  local allGradeRank = petGradeTpl:getAllData()
  local gradeRank = 1
  for i, v in ipairs(allGradeRank) do
    if totalScore >= v.grade[1] and totalScore <= v.grade[2] then
      gradeRank = v.id
      break
    end
  end
  return gradeRank
end

function this:getPetGrade(pet, baseAttributeList)
  local totalScore = 0
  local petCfg = petInfoTpl:getTplById(pet.id)
  local isSpecial = pet.isSpecialPet and pet:isSpecialPet() or pet.special
  totalScore = totalScore + petInfoTpl:getGradeScore(petCfg, isSpecial)
  local petGradeAttrScore = gameConstTpl:getValue("PET_GRADE_ATTR_SCORE")
  for attrId, v in pairs(petGradeAttrScore) do
    local battleInfoCfg = battleInfoTpl:getTplById(attrId)
    local value = baseAttributeList[attrId] or 0
    value = 0 < battleInfoTpl:getIsRatio(battleInfoCfg) and value / 10000 or value
    if attrId == 8 then
      value = 1 <= value and value - 1 or 0
    end
    totalScore = totalScore + value * (v / 10000)
  end
  local petGradeAttrEleBattleInfoScore = gameConstTpl:getValue("PET_GRADE_ATTR_ELE_BATTLEINFO_ID")
  local ratio = gameConstTpl:getValue("PET_GRADE_ATTR_ELE_SCORE")
  for _, attrId in ipairs(petGradeAttrEleBattleInfoScore) do
    local battleInfoCfg = battleInfoTpl:getTplById(attrId)
    local value = baseAttributeList[attrId] or 0
    value = 0 < battleInfoTpl:getIsRatio(battleInfoCfg) and value / 10000 or value
    totalScore = totalScore + value * (ratio / 10000)
  end
  local petGene = pet.gene_infos
  if pet.gene_infos then
    for i, v in pairs(petGene) do
      local petDnaTpl = petDna:getTplById(v.gene_id)
      totalScore = totalScore + petDna:getGradeScore(petDnaTpl)
    end
  end
  totalScore = math.floor(totalScore)
  local minScore = gameConstTpl:getValue("PET_GRADE_SCORE_MIN")
  totalScore = math.max(totalScore, minScore)
  local allGradeRank = petGradeTpl:getAllData()
  local gradeRank = 1
  for i, v in ipairs(allGradeRank) do
    if totalScore >= v.grade[1] and totalScore <= v.grade[2] then
      gradeRank = v.id
      break
    end
  end
  return totalScore, gradeRank
end

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

function this:getRangeValueComprehension(is_small, standardValue, comprehension)
  local comprehensionList = {}
  local comprehensionSortList = {}
  for i = 1, #comprehension do
    local enumNum = _petLearingEnumTpl:getEnumNum(_petLearingEnumTpl:getTplById(i))
    for n, k in pairs(comprehension) do
      if k.attr_id == enumNum then
        comprehensionSortList[i] = k
        break
      end
    end
  end
  local index = standardValue
  if 9 <= standardValue then
    index = 9
  elseif standardValue < 1 then
    index = 1
  end
  if is_small == false then
    for i = 1, #comprehensionSortList do
      local enumData = _petLearingEnumTpl:getTplByEnumId(comprehensionSortList[i].attr_id)
      local comprehensionRangeList = petLearningAblityTpl:getTplByEnumId(enumData.id)
      for k = 1, #comprehensionRangeList - (index - 1) do
        if comprehensionSortList[i].value <= comprehensionRangeList[k].range[2] and comprehensionSortList[i].value > comprehensionRangeList[k].range[1] then
          table.insert(comprehensionList, {
            value = comprehensionSortList[i].value,
            attr_id = comprehensionSortList[i].attr_id,
            rankId = comprehensionRangeList[k].id
          })
          break
        end
      end
    end
  else
    for i = 1, #comprehensionSortList do
      local enumData = _petLearingEnumTpl:getTplByEnumId(comprehensionSortList[i].attr_id)
      local comprehensionRangeList = petLearningAblityTpl:getTplByEnumId(enumData.id)
      for k = 1 + (#comprehensionRangeList - (index - 1)), #comprehensionRangeList do
        if comprehensionSortList[i].value <= comprehensionRangeList[k].range[2] and comprehensionSortList[i].value > comprehensionRangeList[k].range[1] then
          table.insert(comprehensionList, {
            value = comprehensionSortList[i].value,
            attr_id = comprehensionSortList[i].attr_id,
            rankId = comprehensionRangeList[k].id
          })
          break
        end
      end
    end
  end
  table.sort(comprehensionList, function(a, b)
    return a.value > b.value
  end)
  return comprehensionList
end

function this:getGeneComponentIcon(type, color)
  if type == 1 then
    return 0 < color and self.data.beta_bgIcon[color] or "Pages/Pet/tex_pet_frame_onebg"
  elseif type == 2 then
    return 0 < color and self.data.alpha_bgIcon[color] or "Pages/Pet/tex_pet_frame_twobg"
  elseif type == 3 then
    return 0 < color and self.data.link_bgIcon[color] or "Pages/Pet/tex_pet_dec_line"
  end
end

function this:getSaveBoxIndexKey()
  local pId = L_PlayerStore:getPlayerId()
  local key = string.format(self.saveKey.save_curBoxIndex, pId)
  local val = C_PlayerPrefsUtility.GetInt(key)
  return val
end

local petVoiceFormatStr = "Play_QVO_System_%s_%s"

function this:playPetVoiceSound(petId, type)
  local tpl = petVoiceWordsSystemTpl:getTplById(petId)
  if not tpl then
    print("\230\178\161\230\156\137\232\175\165\229\174\160\231\137\169\231\154\132\232\175\173\233\159\179\233\133\141\231\189\174 petId = " .. tostring(petId))
    return
  end
  return L_AudioUtil.playSound(string.format(petVoiceFormatStr, petId, type))
end

function this:refreshPetEntityGuidToEntityId(bAdd, guid, entityId)
  if not bAdd then
    self.data.petEntityGuidToEntityId[guid] = nil
    return
  end
  self.data.petEntityGuidToEntityId[guid] = entityId
end

function this:getPetEntityId(guid)
  return self.data.petEntityGuidToEntityId[guid]
end

function this:checkIsEggHatch(eggUid)
  local eggInfo = L_PetStore:getPetEggItem(eggUid)
  if eggInfo and eggInfo.hatch_state == 0 then
    return false
  end
  return true
end

function this:getPetGeneMutationNewSaveKey(uid)
  return string.format("%s_%s_%s", L_PlayerStore:getPlayerId(), "petGeneMutationNew", uid)
end

function this:getPetGeneMutationNewSaveKeyByPos(uid, pos)
  return string.format("%s_%s_%s_%s", L_PlayerStore:getPlayerId(), "petGeneMutationNew", uid, pos)
end

function this:checkIsNewGene(uid, pos)
  return C_PlayerPrefsUtility.GetInt(self:getPetGeneMutationNewSaveKeyByPos(uid, pos)) == pos
end

function this:getCsPetData(petGuid)
  csHomeManager = csHomeManager or AzurWorld.HomeMgr
  csPetStore = csPetStore or csHomeManager:GetPetStore()
  return csPetStore:GetPet(petGuid)
end

function this:getPetConfigId(csPetData)
  return csPetData.configId
end

function this:getPetLaborInfoList(csPetData)
  local laborInfoList = {}
  local csLaborInfoList = csPetData:GetLaborInfoList()
  for i = 0, csLaborInfoList.Count - 1 do
    local csLaborInfo = csLaborInfoList[i]
    local laborInfo = {}
    laborInfo.laborId = csLaborInfo.laborId
    laborInfo.laborGrade = csLaborInfo.laborGrade
    table.insert(laborInfoList, laborInfo)
  end
  return laborInfoList
end

function this:getPetTalentIdList(csPetData)
  local talentIdList = {}
  local csTalentIds = csPetData.talentIds
  for i = 0, csTalentIds.Count - 1 do
    table.insert(talentIdList, csTalentIds[i])
  end
  return talentIdList
end

function this:getPetIsFreeWork(csPetData)
  return csPetData:GetIsInHomeHub()
end

function this:getPetIsDesignated(csPetData)
  return csPetData:GetIsStationLock()
end

function this:getPetSatietyVal(csPetData)
  return csPetData:GetSatietyVal()
end

function this:getPetWorkPause(csPetData)
  return csPetData:GetWorkPause()
end

function this:getPetCanteenId(csPetData)
  return csPetData:GetCanteenId()
end

function this:getWorkBuildingGuid(csPetData)
  return csPetData:GetWorkBuildingGuid()
end

function this:getPetAutoWorkStatus(csPetData)
  return csPetData:GetAutoWorkState()
end

function this:getPetIsWorking(csPetData)
  return csPetData:IsWorking()
end

return this
