local this = class("modulePropertyPanel", G_UIModuleBase)
local battleInfoTpl = L_GameTpl:getBattleInfoTpl()
local petLearingEnumTpl = L_GameTpl:getPetLearingEnumTpl()
local detailsTpl = L_GameTpl:getDetailsTpl()
local spiritronTpl = L_GameTpl:getSpiritronTpl()
local _accessoryTpl = L_GameTpl:getAccessoryTpl()
local _accessorySetTpl = L_GameTpl:getAccessorySetTpl()
local _heroTpl = L_GameTpl:getHeroTpl()

function this.bind()
  return {
    battleTagList = {
      moduleName = "pages/propertyPanel/cellBattleType"
    },
    groupList = {
      moduleName = "pages/propertyPanel/cellPropertyGroup"
    },
    spiritList = {
      moduleName = "pages/propertyPanel/cellHeroSpirit"
    },
    accessorySpecialityList = {
      moduleName = "pages/propertyPanel/cellAccessorySpeciality"
    },
    accessoryEffectList = {
      moduleName = "pages/propertyPanel/cellAccessoryEffect"
    },
    active_battleTagList = false,
    groupListActive = true,
    spiritListAcitive = false,
    accessorySpecialityListActive = false,
    accessoryEffectListActive = false,
    contentAlpha = 0,
    groupListY = 1,
    contentActive = false,
    maskActive = false,
    arrowActive = false,
    active_guideArrow = false
  }
end

function this.methods()
  return {
    onClick_closeBg = function(self)
      self:setPanelActive(false)
    end,
    onValueChanged = function(self, data)
      if not self.contentHeightOver then
        return
      end
      if data.y < 0.001 then
        if self.bind.active_guideArrow then
          self.bind.active_guideArrow = false
        end
      elseif not self.bind.active_guideArrow then
        self.bind.active_guideArrow = true
      end
    end
  }
end

function this:setPanelActive(isShow)
  if self.gameObject then
    if isShow then
      self.bind.contentAlpha = 1
    else
      self.bind.contentAlpha = 0
    end
    self.bind.maskActive = isShow
    self.bind.contentActive = isShow
    self.bind.arrowActive = isShow
  end
end

function this:initModule(options)
  if not self.isBind then
    self:setPanelActive(false)
    return
  end
  self.options = options
  local tpl = detailsTpl:getTplById(options.detailId)
  self.showType = detailsTpl:getPage(tpl)
  self:refreshList()
  Timer.once(0, function()
    Unity.UI.LayoutRebuilder.ForceRebuildLayoutImmediate(self.bindComponents.rectContent)
    self:checkGuideArrowShowByContentHeight()
  end, self)
end

function this:refreshList()
  self:resetView()
  self:refreshHeroBattleTagView()
  self:refreshDetailView()
  self:refreshSpiritView()
  self:refreshEquipmentView()
end

function this:checkGuideArrowShowByContentHeight()
  local height = self.bindComponents.verticalLayoutGroupContent.preferredHeight
  self.contentHeightOver = height > self.bindComponents.rectBackground.rect.height - 80
  self.bind.active_guideArrow = self.contentHeightOver
end

function this:resetView()
  self.bind.groupListY = 1
  self.bind.active_battleTagList = false
  self.bind.groupListActive = false
  self.bind.spiritListAcitive = false
  self.bind.accessorySpecialityListActive = false
  self.bind.accessoryEffectListActive = false
end

function this:refreshHeroBattleTagView()
  if self.showType == L_Const.propertyPageType.equipment or self.showType == L_Const.propertyPageType.kiBo then
    return
  end
  local heroItem
  if self.showType == L_Const.propertyPageType.heroPreview then
    heroItem = self.options.heroData
  else
    heroItem = L_HeroStore:getHero(L_HeroStore:getHeroGuid(self.options.heroData))
  end
  local heroCfgId = L_HeroStore:getHeroConfigId(heroItem)
  local heroCfg = _heroTpl:getTplById(heroCfgId)
  local heroTagInfo = _heroTpl:getBattleTag(heroCfg)
  local tagInfoList = {}
  if heroTagInfo and 0 < #heroTagInfo then
    self.bind.active_battleTagList = true
    for _, v in ipairs(heroTagInfo) do
      table.insert(tagInfoList, {tagId = v})
    end
  end
  self.bind.battleTagList:clear()
  self.bind.battleTagList:insert_array(tagInfoList)
end

function this:refreshDetailView()
  self.bind.groupListActive = true
  local attDic, groups
  if self.showType ~= L_Const.propertyPageType.kiBo then
    if self.options.isPreview then
      attDic = L_AttributeManager:parseHeroConfigAttByHero(self.options.heroData, self.options.heroData.heroId)
    else
      local heroId = L_HeroStore:getHeroGuid(self.options.heroData)
      self.guid = heroId
      if self.showType == L_Const.propertyPageType.equipment then
        attDic = L_AttributeManager:getMergeHeroAtt(self.guid, {2, 3})
      else
        attDic = L_HeroStore:getHeroPropertyMap(heroId)
      end
    end
    groups = L_AttributeManager:getPropertiesForDisplay(L_Const.roleType.hero, attDic, self.guid)
  end
  if self.showType == L_Const.propertyPageType.kiBo and self.options.petData ~= nil then
    attDic = L_PetStore:getPetProperty(self.options.petData)
    local guid = self.options.petData.guid
    groups = L_AttributeManager:getPropertiesForDisplay(L_Const.roleType.pet, attDic, guid)
  end
  self.bind.groupList:clear()
  self.bind.groupList:insert_array(groups)
end

function this:refreshSpiritView()
  if self.showType ~= L_Const.propertyPageType.hero and self.showType ~= L_Const.propertyPageType.equipment then
    return
  end
  local heroId = L_HeroStore:getHeroGuid(self.options.heroData)
  local hero = L_HeroStore:getHero(heroId)
  local spiritGuid = L_HeroStore:getHeroSpiritronGuid(hero)
  local spirit = L_SpiritronStore:getSpiritronItem(spiritGuid)
  self.bind.spiritListAcitive = spirit ~= nil
  if not spirit then
    return
  end
  self:refreshSpiritList(spirit)
end

function this:refreshSpiritList(spirit)
  local skills = {}
  local spiritId = L_SpiritronStore:getSpiritronConfigId(spirit, spirit.star)
  local tpl = spiritronTpl:getTplById(spiritId)
  local reishiSkill = spiritronTpl:getReishiSkill(tpl)
  table.insert(skills, {
    star = spirit.star,
    skillId = reishiSkill,
    guid = spirit.guid,
    spiritId = spiritId
  })
  self.bind.spiritList:clear()
  self.bind.spiritList:insert_array(skills)
end

function this:refreshEquipmentView()
  if self.showType ~= L_Const.propertyPageType.hero and self.showType ~= L_Const.propertyPageType.equipment then
    return
  end
  local heroId = L_HeroStore:getHeroGuid(self.options.heroData)
  local hero = L_HeroStore:getHero(heroId)
  local accessories = L_HeroStore:getHeroAccessoryGuidList(hero)
  if self:checkAccessoriesEmpty(accessories) then
    return
  end
  self:refreshAccessoryEffectList(accessories)
end

function this:checkAccessoriesEmpty(accessories)
  for k, v in ipairs(accessories) do
    if not math.isEmpty(v) then
      return false
    end
  end
  return true
end

function this:refreshAccessoryEffectList(accessories)
  local res = self:getSuitEffect(accessories)
  local data = {}
  for _, v in pairs(res) do
    table.insert(data, v)
  end
  table.sort(data, function(a, b)
    return a.suitId < b.suitId
  end)
  self.bind.accessoryEffectListActive = 0 < #data
  if 0 < #data then
    self.bind.accessoryEffectList:clear()
    self.bind.accessoryEffectList:insert_array({
      {suites = data}
    })
  end
end

function this:getSuitEffect(accessories)
  local res = {}
  for _, guid in ipairs(accessories) do
    if not math.isEmpty(guid) then
      local serverData = L_AccessoryStore:getAccessory(guid)
      local accessoryId = serverData.accessoryId
      local wearHero = serverData.wearHero
      local tpl_accessory = _accessoryTpl:getTplById(accessoryId)
      local suitId = _accessoryTpl:getSetId(tpl_accessory)
      if 0 < suitId and not res[suitId] then
        local suitTxtData = L_AccessoryManager:getSuitDesc(accessoryId)
        local heroAccessoryGuidList = accessories
        local suitNum = 1
        local tplCur = _accessoryTpl:getTplById(accessoryId)
        local posCur = _accessoryTpl:getType(tplCur)
        local setCur = _accessoryTpl:getSetId(tplCur)
        for _, guidTmp in pairs(heroAccessoryGuidList) do
          if not math.isEmpty(guidTmp) and guidTmp ~= guid and not math.isEmpty(setCur) then
            local serverDataTmp = L_AccessoryStore:getAccessory(guidTmp)
            local tplTmp = _accessoryTpl:getTplById(serverDataTmp.accessoryId)
            local posTmp = _accessoryTpl:getType(tplTmp)
            local setTmp = _accessoryTpl:getSetId(tplTmp)
            if setTmp == setCur then
              if self.options.isPreview and posCur ~= posTmp then
                suitNum = suitNum + 1
              elseif not self.options.isPreview and serverDataTmp.wearHero == wearHero then
                suitNum = suitNum + 1
              end
            end
          end
        end
        for i, v in ipairs(suitTxtData.suit) do
          if suitNum >= v.index then
            suitTxtData.suit[i].active = true
          end
        end
        local tpl_set = _accessorySetTpl:getTplById(_accessoryTpl:getSetId(tplCur))
        local suitSkillList = _accessorySetTpl:getSkill(tpl_set)
        local maxSuitNum = suitSkillList[#suitSkillList][1]
        local txt_suitName = string.format("%s(%s/%s)", suitTxtData.name, suitNum, maxSuitNum)
        for i, v in ipairs(suitTxtData.suit) do
          if v.active then
            if not res[suitId] then
              res[suitId] = {
                suitId = suitId,
                des = {},
                suitName = txt_suitName
              }
            end
            table.insert(res[suitId].des, v.desc)
          end
        end
      end
    end
  end
  return res
end

function this:refreshAccessorySpecialityList(accessories)
  local res = {}
  for _, guid in ipairs(accessories) do
    if not math.isEmpty(guid) then
      local serverData = L_AccessoryStore:getAccessory(guid)
      local att = L_AccessoryManager:getPackAtt(serverData)
      for _, subAtt in ipairs(att.subAtt) do
        if subAtt.isSkill and not subAtt.lock then
          res[subAtt.skillId] = subAtt
        end
      end
    end
  end
  local skillAtt = {}
  for _, v in pairs(res) do
    table.insert(skillAtt, v)
  end
  table.sort(skillAtt, function(a, b)
    return a.skillId < b.skillId
  end)
  for i, skills in ipairs(skillAtt) do
    skills.isShowBg = i % 2 == 0
  end
  self.bind.accessorySpecialityListActive = 0 < #skillAtt
  if 0 < #skillAtt then
    self.bind.accessorySpecialityList:clear()
    self.bind.accessorySpecialityList:insert_array({
      {skills = skillAtt}
    })
  end
end

return this
