local this = class("cellPixelPet", G_UIModuleBase)
local petTpl = L_GameTpl:getPetTpl()
local petGradeTpl = L_GameTpl:getPetGradeTpl()
local elementTypeTpl = L_GameTpl:getElementTypeTpl()
local IsPc = L_DeviceTpl:getIsPc()
local _homeLaborTypeTpl = L_GameTpl:getHomeLaborTypeTpl()
local _homeTalentTpl = L_GameTpl:getHomeTalentTpl()

function this:ctor(...)
  this.super.ctor(self, ...)
  self.data = {
    hungerColor = {
      [L_PetConst.SatietyStatus.LESS] = "#ff7e6d",
      [L_PetConst.SatietyStatus.MIDDLE] = "#ffbf35",
      [L_PetConst.SatietyStatus.FULL] = "#27ae89"
    }
  }
end

function this.bind()
  return {
    empty = true,
    content = false,
    frameBg = "",
    gradeGroup = false,
    gradeValue = "",
    gradeIcon = "",
    lvGroup = false,
    txt_lv = "",
    elementIcon = "",
    hungerGroup = false,
    hungerValue = "",
    hungerIconColor = C_Color.white,
    masterGroup = false,
    masterIcon = "",
    selected = false,
    module_pixelIcon = {
      moduleName = "pages/pet/modulePetPixelIcon"
    },
    emptySelect = false,
    exchangeSelect = false,
    releaseTagActive = false,
    petStatusActive = false,
    module_petGameplayStatus = {
      moduleName = "pages/pet/modulePetGameplayStatus"
    },
    list_petLabors = {
      moduleName = "pages/pet/cellPixelPetLabor"
    },
    active_petLaborList = false,
    activeEdit = false
  }
end

function this.methods()
  return {
    onClick = function(self)
      if self.bind.callback then
        self.bind.callback(self)
        if not string.isEmpty(self.bind.reddotName) then
          L_ReddotManager:clearNew(L_ReddotManager.DotDef.PetNew, self.bind.guid)
        end
      end
    end,
    onPointEnter_content = function(self)
      if not IsPc then
        return
      end
      if self.bind.pointEnterCallback then
        self.bind.pointEnterCallback(self)
      end
    end,
    onPointExit_content = function(self)
      if not IsPc then
        return
      end
      if self.bind.pointExitCallback then
        self.bind.pointExitCallback(self)
      end
    end,
    onPointEnter_slot = function(self)
      if not self.parent.isDragging then
        return
      end
      if self.bind.empty ~= true then
        return
      end
      self:setEmptySelect(true)
    end,
    onPointExit_slot = function(self)
      if not self.parent.isDragging then
        return
      end
      if self.bind.empty ~= true then
        return
      end
      self:setEmptySelect(false)
    end,
    onPointEnter_exchange = function(self)
      if not self.parent.isDragging or self.isDragSelect then
        return
      end
      if self.bind.content ~= true then
        return
      end
      self:setExchangeSelect(true)
    end,
    onPointExit_exchange = function(self)
      if not self.parent.isDragging or self.isDragSelect then
        return
      end
      if self.bind.content ~= true then
        return
      end
      self:setExchangeSelect(false)
    end
  }
end

function this:open()
  this.super.open(self)
  self._pixelIconModule = self.modules.module_pixelIcon
  L_SatietyStore:listenCallFunc(L_SatietyStore.event.satiety_value_refresh, self.onRefreshSatiety, self)
  L_PetStore:listenCallFunc(L_PetStore.event.setPetReleaseMode, self.refreshPetStatus, self)
  self:refreshView()
end

function this:refreshView()
  if not self.isBind then
    return
  end
  if not math.isEmpty(self.bind.guid) then
    self:setPetDataContent(self.bind.guid, self.bind)
    self:setGifPlay(self.bind.choice)
    if L_PetReleaseManager:getIsReleaseMode() then
      self:setGifPlay(L_PetReleaseManager:isPetSelected(self.bind.guid))
    else
      self:setGifPlay(self.bind.choice)
    end
    local reddotName = ""
    if self.bind and self.bind.reddotName then
      reddotName = self.bind.reddotName
    end
    local reddotGeneName = ""
    if self.bind and self.bind.reddotGeneName then
      reddotGeneName = self.bind.reddotGeneName
    end
    if self.bindComponents.reddotNew then
      if string.isEmpty(reddotName) or not string.isEmpty(reddotGeneName) then
        self.bindComponents.reddotNew.gameObject:SetActive(false)
      else
        L_ReddotManager:registerReddot(self.bindComponents.reddotNew, reddotName)
      end
    end
    if self.bindComponents.reddotGene then
      if string.isEmpty(reddotGeneName) then
        self.bindComponents.reddotGene.gameObject:SetActive(false)
      else
        if L_ReddotManager:haveNew(L_ReddotManager.DotDef.PetNew, self.bind.guid) then
          L_ReddotManager:clearNew(L_ReddotManager.DotDef.PetNew, self.bind.guid)
        end
        L_ReddotManager:registerReddot(self.bindComponents.reddotGene, reddotGeneName)
      end
    end
  else
    self.bind.empty = true
    self.bind.content = false
  end
end

function this:close()
  L_SatietyStore:unListenCallFunc(L_SatietyStore.event.satiety_value_refresh, self.onRefreshSatiety, self)
  L_PetStore:unListenCallFunc(L_PetStore.event.setPetReleaseMode, self.refreshPetStatus, self)
  L_PhotoManager:clearPhotoEntity(self)
end

function this:setPetDataContent(guid, params)
  self.bind.guid = guid
  table.merge(self.bind, params or {})
  local isEmpty = math.isEmpty(guid)
  self.bind.empty = isEmpty
  self.bind.content = not isEmpty
  if not math.isEmpty(params.filterType) then
    self.bind.gradeGroup = params.filterType == L_PetConst.filterPetBox.grade
    self.bind.lvGroup = params.filterType == L_PetConst.filterPetBox.level
    self.bind.hungerGroup = params.filterType == L_PetConst.filterPetBox.satiety
    self.bind.active_petLaborList = params.filterType == L_PetConst.filterPetBox.labor
  end
  local serverData = L_PetStore:getPetItem(guid)
  if not serverData and params.petInfo then
    self.petInfo = params.petInfo
    serverData = {
      lv = self.petInfo.lv,
      satiety = self.petInfo.satiety,
      id = self.petInfo.id
    }
    self.petInfo.gradeRank = L_PetStore:calGradeRank(self.petInfo.grade)
    self._pixelIconModule:setPetInfo(self.petInfo)
  end
  if serverData then
    self._pixelIconModule:setGuid(guid)
    self._pixelIconModule:outLineShow(params.outlineShow)
    self.bind.txt_lv = string.format("Lv.%d", serverData.lv)
    self:refreshSatiety(serverData.satiety, guid)
    local tpl = petTpl:getTplById(serverData.id)
    local element = petTpl:getElement(tpl)
    if element[1] and elementTypeTpl:getTplById(element[1]) then
      self.bind.elementIcon = elementTypeTpl:getPetElem(elementTypeTpl:getTplById(element[1]))
    end
    local haveGeneMutation = L_ReddotManager:haveNew(L_ReddotManager.DotDef.PetGeneMutation, self.bind.guid)
    if not math.isEmpty(serverData.hero_id) and not haveGeneMutation then
      self.bind.masterGroup = true
      local heroData = L_HeroStore:getHero(serverData.hero_id)
      self.bind.masterIcon = L_GameUtil.getAvatarTexturePath(L_HeroStore:getHeroConfigId(heroData), L_Const.resourceIndexOfAvatarTextureInHeroTpl.small)
      local modName = L_PlayerStore:getPlayerModHeadImgName()
      if L_HeroStore:getHeroGuid(heroData) == L_HeroStore:getDefaultHeroGuid() and not string.isEmpty(modName) then
        L_PhotoManager:newOrBindPhotoEntity(self, self.bindComponents.ImageHead, modName)
      else
        L_PhotoManager:clearPhotoEntity(self)
      end
      if L_ReddotManager:haveNew(L_ReddotManager.DotDef.PetNew, self.bind.guid) then
        L_ReddotManager:clearNew(L_ReddotManager.DotDef.PetNew, self.bind.guid)
      end
    else
      self.bind.masterGroup = false
    end
    local grade, gradeRank = L_PetStore:getPetGradeNew(guid)
    if self.petInfo ~= nil and self.petInfo.gradeRank ~= nil then
      grade = self.petInfo.grade
      gradeRank = self.petInfo.gradeRank
    end
    local gradeTpl = petGradeTpl:getTplById(gradeRank)
    self.bind.gradeIcon = petGradeTpl:getIcon(gradeTpl)
    self.bind.gradeValue = tostring(grade)
    self.bind.frameBg = petGradeTpl:getPetGradeFrame(gradeTpl)
    if self.bind.active_petLaborList then
      self.bind.frameBg = ""
    end
  end
  if self.bind.active_petLaborList then
    local csPetData = L_PetStore:getCsPetData(guid)
    if L_CommonUtil.isValid(csPetData) then
      local talentIdList = L_PetStore:getPetTalentIdList(csPetData)
      local laborInfoList = L_PetStore:getPetLaborInfoList(csPetData)
      table.sort(laborInfoList, function(a, b)
        return a.laborGrade > b.laborGrade
      end)
      local data = {}
      for _, laborInfo in pairs(laborInfoList) do
        local laborId = laborInfo.laborId
        local talentId
        for _, id in pairs(talentIdList) do
          local talentTpl = _homeTalentTpl:getTplById(id)
          local talentLaborId = _homeTalentTpl:getLaborTypeIdOfTalent(talentTpl)
          if talentLaborId == laborId then
            talentId = id
            break
          end
        end
        table.insert(data, {
          laborId = laborId,
          talentId = talentId,
          laborGrade = tostring(laborInfo.laborGrade)
        })
      end
      self.bind.list_petLabors:clear()
      self.bind.list_petLabors:insert_array(data)
    end
  end
  self:refreshPetStatus()
end

function this:onRefreshSatiety(petGuids)
  if not self.isBind then
    return
  end
  for i, v in pairs(petGuids) do
    if self.bind.guid == v then
      local currentSatiety = L_SatietyStore:getPetSatiety(v)
      self:refreshSatiety(currentSatiety, v)
      break
    end
  end
end

function this:refreshSatiety(satiety, petGuid)
  if not self.isBind then
    return
  end
  if self.bind.filterType == L_PetConst.filterPetBox.satiety then
    local satietyStatus = L_SatietyStore:getPetSatietyStatus(petGuid)
    local maxSatiety = L_SatietyStore:getPetMaxSatiety(petGuid)
    local str = L_GameUtil.fillColor(satiety, L_PetConst.NewSatietyTextColor[satietyStatus])
    local colorStr = string.format("%s<color=#C1C1C1>/%d</color>", str, maxSatiety)
    self.bind.hungerValue = colorStr
    self.bind.hungerIconColor = C_LuaUtility.ParseHtmlStringColor(L_PetConst.SatietyStatusIconColor[satietyStatus])
  end
end

function this:setGifPlay(isPlay)
  if not self.isBind then
    return
  end
  self.bind.selected = isPlay
  if isPlay then
    self._pixelIconModule:playPixelGif()
  else
    self._pixelIconModule:stopPixelGif()
  end
  self:refreshPetStatus()
  self.bind.releaseTagActive = isPlay and L_PetReleaseManager:getIsReleaseMode()
end

function this:refreshSel(sel)
  self._pixelIconModule:outLineShow(sel)
end

function this:setOutLineShow(isShow)
  if not self.isBind then
    return
  end
  self._pixelIconModule:outLineShow(isShow)
end

function this:getRaycastGo()
  if self.isBind then
    if math.isEmpty(self.bind.guid) then
      return self.bindComponents.img_empty.gameObject
    else
      return self.bindComponents.btn_img_content.gameObject
    end
  end
end

function this:setIconAlpha(alpha)
  if not self.isBind then
    return
  end
  self._pixelIconModule:setIconAlpha(alpha)
  self.isDragSelect = alpha < 1 and true or false
end

function this:setEmptySelect(bool)
  self.bind.emptySelect = bool
end

function this:setExchangeSelect(bool)
  self.bind.exchangeSelect = bool
  self.bind.emptySelect = bool
  if bool then
    self._petExchangeWrap = L_AudioUtil.playSound("Play_SFX_System_UI_QiboHouse_PickUp_Hold")
    self.exchangeAudioTimer = Timer.repeated(1, function(self)
      self._petExchangeWrap = L_AudioUtil.playSound("Play_SFX_System_UI_QiboHouse_PickUp_Hold")
    end, self)
  else
    L_AudioUtil.stopSound(self._petExchangeWrap)
    Timer.remove(self.exchangeAudioTimer)
  end
end

function this:refreshPetStatus()
  self.bind.petStatusActive = L_PetReleaseManager:getIsReleaseMode()
  if self.bind.petStatusActive then
    local moduleStatus = self.modules.module_petGameplayStatus
    moduleStatus:setPetReleaseData(self.bind.guid)
  end
end

return this
