local this = class("petManager")
table.merge(this, require("ui.manager.pet.petManager_scene"))
table.merge(this, require("ui.manager.pet.petManager_petGet"))
local _petTpl = L_GameTpl:getPetTpl()
local wordsTpl = L_GameTpl:getWordsTpl()
local _skillLevelTpl = L_GameTpl:getSkillLevelTpl()
local _worldCityTpl = L_GameTpl:getWorldCityTpl()
local _petDna = L_GameTpl:getDnaTpl()
local _skillTpl = L_GameTpl:getSkillTpl()

function this:ctor()
  self.petEntityBuffer = {}
  self.petBgColor = {
    [1] = {
      [1] = "#D5D5D5",
      [2] = "#8F8F8F",
      [3] = "#595959"
    },
    [2] = {
      [1] = "#D5D5D5",
      [2] = "#8F8F8F",
      [3] = "#595959"
    },
    [3] = {
      [1] = "#ACC0B4",
      [2] = "#8CAC95",
      [3] = "#1c795e"
    },
    [4] = {
      [1] = "#ACC0B4",
      [2] = "#8CAC95",
      [3] = "#1c795e"
    },
    [5] = {
      [1] = "#758097",
      [2] = "#6174B4",
      [3] = "#234edb"
    },
    [6] = {
      [1] = "#758097",
      [2] = "#6174B4",
      [3] = "#234edb"
    },
    [7] = {
      [1] = "#B37EB9",
      [2] = "#A272B3",
      [3] = "#935fd9"
    },
    [8] = {
      [1] = "#F0DC6D",
      [2] = "#B19749",
      [3] = "#b87500"
    }
  }
end

function this:petHintInfo(num)
  local switch = {
    [1] = function()
      L_FlyMsgManager:showNormalMsg(wordsTpl:getTplById("notice_common_lackGold"))
      return
    end,
    [2] = function()
      L_FlyMsgManager:showNormalMsg(wordsTpl:getTplById("notice_hero_lackLevel"))
      return
    end,
    [3] = function()
      L_FlyMsgManager:showNormalMsg(wordsTpl:getTplById("notice_common_lackItem"))
      return
    end,
    [4] = function()
      L_FlyMsgManager:showNormalMsg(wordsTpl:getTplById("notice_hero_rankMax"))
      return
    end,
    [5] = function()
      L_FlyMsgManager:showNormalMsg(wordsTpl:getTplById("notice_hero_levelMax"))
      return
    end,
    [6] = function()
      L_FlyMsgManager:showNormalMsg(wordsTpl:getTplById("notice_hero_chooseLevelItem"))
      return
    end,
    [7] = function()
      L_FlyMsgManager:showNormalMsg("notice_petManager")
      return
    end
  }
  local f = switch[num]
  if f then
    return f()
  else
  end
end

function this:getPetBgColor()
  return self.petBgColor
end

function this:checkTimelineControl()
  return self.timelineControl ~= nil
end

function this:getTimelineControl()
  if self.timelineControl == nil then
    self.timelineControl = require("ui.manager.pet.timeline.petHouseTimelineControl").new()
  end
  return self.timelineControl
end

function this:disposeTimelineControl()
  if self.timelineControl then
    self.timelineControl:dispose()
  end
  self.timelineControl = nil
end

function this:lvChange(lv)
  if lv < 10 then
    return string.format("0%d", lv)
  end
  return tostring(lv)
end

function this:autoLvUp(expBookTable, upExp)
  local sortMax = {}
  for i in pairs(expBookTable) do
    table.insert(sortMax, i)
  end
  table.sort(sortMax, function(a, b)
    return b < a
  end)
  local exp = upExp
  local tempData = {}
  for i = 1, #sortMax do
    tempData[sortMax[i]] = 0
    if exp >= sortMax[i] then
      local num = math.min(math.modf(exp / sortMax[i]), expBookTable[sortMax[i]])
      tempData[sortMax[i]] = num
      exp = exp - num * sortMax[i]
    end
  end
  if 0 < exp then
    for i = #sortMax, 1, -1 do
      local v = sortMax[i]
      if exp <= sortMax[i] and expBookTable[v] > tempData[v] then
        tempData[v] = tempData[v] + 1
        break
      end
    end
  end
  return tempData
end

function this:setPetEntitybuffer(entity)
  table.insert(self.petEntityBuffer, entity)
end

function this:clearPetEntitybuffer()
  self.petEntityBuffer = {}
end

function this:getPetEntitybuffer()
  return self.petEntityBuffer
end

function this:getGeneUnlockConditions()
  local conditionMap = L_Config:getConfig("game", "PET_DNAUNLOCK_NEW")
  local conditions = {}
  for k, v in pairs(conditionMap) do
    conditions[v[1]] = v[2]
  end
  return conditions
end

function this:judgeCanScanPet()
  if not L_SystemUnlockStore:getSystemIsOpen(L_SystemConst.enum.catchPet) then
    return false
  end
  local playModule = L_WorldManager:getCurModule()
  if playModule == L_Const.worldModule.home then
    return false
  end
  local sceneId = AzurWorldInstance.CurWorldId
  local tpl = _worldCityTpl:getTplById(sceneId)
  local isCatchPetDisable = _worldCityTpl:getIsSystemDisable(tpl, L_SystemConst.enum.catchPet)
  return not isCatchPetDisable
end

function this:judgeCanCatchPet()
  local canCatch = true
  if CS.Lens.Gameplay.Modules.BigWorld.Macro.IsBattleSimulator then
    return true
  end
  if not L_SystemUnlockStore:getSystemIsOpen(L_SystemConst.enum.catchPet) then
    return false
  end
  local playModule = L_WorldManager:getCurModule()
  if playModule == L_Const.worldModule.home then
    return false
  end
  local sceneId = AzurWorldInstance.CurWorldId
  local tpl = _worldCityTpl:getTplById(sceneId)
  local isCatchPetDisable = _worldCityTpl:getIsSystemDisable(tpl, L_SystemConst.enum.catchPet)
  if isCatchPetDisable then
    L_FlyMsgManager:showNormalMsg(L_WordsTpl:getValue("notice_cannot_catch_scene"))
    return false
  end
  if L_PlayerStore:playerInMountStatus() then
    L_FlyMsgManager:showNormalMsg(L_WordsTpl:getValue("notice_cannot_catch_ride"))
    return false
  end
  local data = L_BagManager:getAllCapturePetBall()
  local haveItem = false
  for i = 1, #data do
    if data[i].num > 0 then
      haveItem = true
      break
    end
  end
  if not haveItem then
    L_FlyMsgManager:showNormalMsg(L_WordsTpl:getValue("notice_noPetcatchitem"))
    return false
  end
  local isFull, _ = L_PetStore:getAllPetBoxIsFull()
  if isFull then
    L_FlyMsgManager:showNormalMsg(L_WordsTpl:getValue("ui_petQuantity"))
    return false
  end
  return canCatch
end

function this:getPetConfigFeatureSkill(petConfigId)
  local randomFeature = {}
  local fixedFeature = {}
  local tpl = _petTpl:getTplById(petConfigId)
  if tpl then
    local randomSkillPool = _petTpl:getRandomSkillList(tpl)
    if not table.isEmpty(randomSkillPool) then
      for i, v in pairs(randomSkillPool) do
        local skill = self:parseSkillInfo(v[2])
        if not table.isEmpty(skill) then
          table.insert(randomFeature, skill)
        end
      end
    end
    local fixedSkillPool = _petTpl:getFeatureSkillList(tpl)
    if not table.isEmpty(fixedSkillPool) then
      for i, v in pairs(fixedSkillPool) do
        local skill = self:parseSkillInfo(v)
        if not table.isEmpty(skill) then
          table.insert(fixedFeature, skill)
        end
      end
    end
  end
  return randomFeature, fixedFeature
end

function this:getFPropertySkillList(petConfigId)
  local kiboFeature = {}
  local tpl = _petTpl:getTplById(petConfigId)
  if tpl then
    local kiboSkill = _petTpl:getFeatureSkillList(tpl)
    if not table.isEmpty(kiboSkill) then
      for i, v in pairs(kiboSkill) do
        local skill = self:parseSkillInfo(v)
        if not table.isEmpty(skill) then
          table.insert(kiboFeature, skill)
        end
      end
    end
  end
  return kiboFeature
end

function this:getKiboFPropertySkillList(petConfigId)
  local kiboDuelFeature = {}
  local tpl = _petTpl:getTplById(petConfigId)
  if tpl then
    local kiboSkill = _petTpl:getKiboFPropertySkillList(tpl)
    if not table.isEmpty(kiboSkill) then
      for i, v in pairs(kiboSkill) do
        local skill = self:parseSkillInfo(v)
        if not table.isEmpty(skill) then
          table.insert(kiboDuelFeature, skill)
        end
      end
    end
  end
  return kiboDuelFeature
end

function this:getPetConfigActiveSkill(petConfigId)
  local tpl = _petTpl:getTplById(petConfigId)
  local commonSkill = {}
  local breakSkill = {}
  local signatureSkill = {}
  if tpl then
    local signatureSkillPool = _petTpl:getSignatureSkillList(tpl)
    if not table.isEmpty(signatureSkillPool) then
      for i, v in pairs(signatureSkillPool) do
        if not math.isEmpty(v[3]) then
          local skill = self:parseSkillInfo(v[2])
          if not table.isEmpty(skill) then
            table.insert(signatureSkill, skill)
          end
        end
      end
    end
    local breakSkillPool = _petTpl:getBreakSkillList(tpl)
    if not table.isEmpty(breakSkillPool) then
      for i, v in pairs(breakSkillPool) do
        local skill = self:parseSkillInfo(v)
        if not table.isEmpty(skill) then
          table.insert(breakSkill, skill)
        end
      end
    end
    local commonSkillPool = _petTpl:getCommonSkillList(tpl)
    if not table.isEmpty(commonSkillPool) then
      for i, v in pairs(commonSkillPool) do
        if not math.isEmpty(v[3]) then
          local skill = self:parseSkillInfo(v[2])
          if not table.isEmpty(skill) then
            table.insert(commonSkill, skill)
          end
        end
      end
    end
  end
  return signatureSkill, breakSkill, commonSkill
end

function this:parseSkillInfo(petSkillId)
  local tpl = _skillLevelTpl:getTplByIdAndLevel(petSkillId, 1)
  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)
    local skillInfo = {
      index = 0,
      skillLv = "Lv.1",
      skillId = petSkillId,
      skillLevelShow = false,
      levelLabel = true,
      itemIcon = skillIcon,
      describe = skillDescribe,
      skillName = skillName,
      skillElement = _skillTpl:getSkillElement(nameTpl)
    }
    return skillInfo
  end
  return nil
end

function this:parseGeneInfo(petGeneId)
  local tpl = _skillLevelTpl:getTplByIdAndLevel(petGeneId, 1)
  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 skillName = _skillTpl:getName(nameTpl)
    local skillDescribe = _skillLevelTpl:getSkillDescribe(tpl)
    local skillIcon = _skillTpl:getIcon(nameTpl)
    local geneInfo = {
      geneId = petGeneId,
      skillLv = "Lv." .. 1,
      skillLevelShow = false,
      levelLabel = false,
      itemIcon = skillIcon,
      describe = skillDescribe,
      skillName = skillName,
      starLv = 0,
      rarity = dnaRarity
    }
    return geneInfo
  end
  return nil
end

function this:commonGetPet(options, forceShow, callback, ignoreQueueCheck)
  local pet = options.pet
  local map = L_CatalogStore:getPetCatalog()
  if forceShow then
    if map[pet.id] then
      map[pet.id] = map[pet.id] + 1
    end
    options.showType = L_Const.getPetShowType.long
    self:getTempRenderTexture(function(tempTex)
      options.texture = tempTex
      L_UI:open("pageGetPet", options, callback, ignoreQueueCheck)
    end)
    return
  end
  if map[pet.id] and map[pet.id] > 1 then
    L_CatalogStore:_triggerCommonGetPet(pet)
    if options.closeCallback then
      options.closeCallback(true)
    end
    if options.voiceCallBack then
      options.voiceCallBack()
    end
  else
    L_CatalogStore:_triggerCommonGetPet(pet, true)
    if map[pet.id] then
      map[pet.id] = map[pet.id] + 1
    end
    options.isNew = true
    options.showType = L_Const.getPetShowType.long
    self:getTempRenderTexture(function(tempTex)
      options.texture = tempTex
      L_UI:open("pageGetPet", options, callback, ignoreQueueCheck)
    end)
  end
end

function this:getTempRenderTexture(callback)
  local width = Unity.Screen.width
  local height = Unity.Screen.height
  local tempTex = C_RenderTexture.GetTemporary(width, height)
  C_UniversalRenderPipeline.CaptureFrame(C_CameraManager.uiCamera, tempTex, true, false, function()
    if callback then
      callback(tempTex)
    end
  end)
end

function this:judgeShowScanPet()
  local canCatch = false
  return canCatch
end

return this
