local this = class("modulePetAttributeFruit", G_UIModuleBase)
local _petLearingEnumTpl = L_GameTpl:getPetLearingEnumTpl()
local _petFeedItemTpl = L_GameTpl:getPetFeedItemTpl()
local _petTalentUpgradeTpl = L_GameTpl:getPetTalentUpgradeTpl()
local _petLevelTpl = L_GameTpl:getPetLevelTpl()
local _commonItemTpl = L_GameTpl:getCommonItemTpl()
local _wordsTpl = L_GameTpl:getWordsTpl()
local colNum = 2
local _petExpItemIdList = {
  402000,
  402001,
  402002,
  402003
}

function this.bind()
  return {
    txt_expTitle = "",
    list_cellPetExpFruitItem = {
      moduleName = "pages/pet/cellPetExpFruitItem"
    },
    txt_attributeTitle = "",
    list_cellPetAttributeFruitItem = {
      moduleName = "pages/pet/cellPetAttributeFruitItem"
    }
  }
end

function this.methods()
  return {
    onClick_cancel = function(self)
      self:resetSelectNum()
    end,
    onClick_confirmUseFruit = function(self)
      self:onBtnTrain()
    end,
    onClick_maxLevel = function(self)
      self:onBtnAutoSetUpLv()
    end
  }
end

function this:open()
  self.bind.txt_expTitle = L_Lang:get(L_WordsTpl:getValue("ui_pet_level_up"))
  self.bind.txt_attributeTitle = L_Lang:get(L_WordsTpl:getValue("ui_pet_attr_up"))
  L_PetStore:listenCallFunc(L_PetStore.event.getNewPetSkill, self.onEvent_showPetSkillInfo, self)
  L_PetStore:listenCallFunc(L_PetStore.event.updatePetSkill, self.onEvent_showPetSkillInfo, self)
  L_PetStore:listenCallFunc(L_PetStore.event.convertPetSkill, self.onEvent_showPetSkillInfo, self)
end

function this:onEvent_showPetSkillInfo(skillInfo, type)
end

function this:setInfos(params)
  self.parent = params.parent
  self.petGuid = params.petGuid
end

function this:refreshUI()
  self:refreshPetExpList()
  self:refreshPetAttributeList()
end

function this:refreshPetExpList()
  local petExpFruitItemList = {}
  for _, id in ipairs(_petExpItemIdList) do
    local itemId = id
    local itemType = L_Const.CommonItemSubType.kPetExpBook
    local itemNum = L_BagStore:getItemNum(itemId)
    local itemConfig = {
      itemId = itemId,
      itemType = itemType,
      itemNum = itemNum,
      onSelectChangeNumChangeCbk = function()
        self:onPetExpFruitSelectChange()
      end
    }
    table.insert(petExpFruitItemList, itemConfig)
  end
  self.bind.list_cellPetExpFruitItem:clear()
  self.bind.list_cellPetExpFruitItem:insert_array(petExpFruitItemList)
  self.maxLv = L_PetStore:getPetMaxLevel(true)
  local pet = L_PetStore:getPetItem(self.petGuid)
  self.lv = pet.lv
  self.configId = pet:petCfgId()
end

function this:onPetExpFruitSelectChange()
  local selectInfo = self:getSelectedExpInfo()
  local preUseFruitInfoList = self:getPreUseFruitInfoList()
  self.parent:onPetExpItemSelectNumChange(selectInfo, preUseFruitInfoList)
  self:onEvent_petExpChange()
end

function this:getSelectedExpInfo()
  local tempExp = {}
  for _, module in ipairs(self.modules.list_cellPetExpFruitItem) do
    if module:getSelectNum() > 0 then
      local data = {}
      data = {
        item_id = module:getItemId(),
        item_num = module:getSelectNum()
      }
      table.insert(tempExp, data)
    end
  end
  return tempExp
end

function this:getSelectAddExp()
  local tempExpAll = 0
  for _, module in ipairs(self.modules.list_cellPetExpFruitItem) do
    local exp = _commonItemTpl:getUseFunction(_commonItemTpl:getTplById(module:getItemId()))[1]
    tempExpAll = tempExpAll + module:getSelectNum() * exp
  end
  return tempExpAll
end

function this:onEvent_petExpChange()
  local pet = L_PetStore:getPetItem(self.petGuid)
  local tempExpAll = self:getSelectAddExp()
  local tempExp = tempExpAll + pet.exp
  local tempLv = pet.lv
  for i = tempLv, self.maxLv - 1 do
    if tempExp - _petLevelTpl:getExp(_petLevelTpl:getTplById(i)) < 0 then
      break
    end
    tempLv = i + 1
    tempExp = tempExp - _petLevelTpl:getExp(_petLevelTpl:getTplById(i))
  end
  self.lv = tempLv
end

function this:checkCanAddExpItem()
  local petItem = L_PetStore:getPetItem(self.petGuid)
  if petItem.lv >= L_PetStore:getPetMaxLevel() then
    L_PetManager:petHintInfo(5)
    return false
  end
  if petItem.lv >= L_PetStore:getPetMaxLevel(true) then
    local tpl = _petLevelTpl:getTplById(petItem.lv + 1)
    local condition = _petLevelTpl:getCondition(tpl)
    local bCompelte = true
    if not table.isEmpty(condition) then
      bCompelte = L_ConditionManager:singleIsComplete(condition)
    end
    if not bCompelte then
      L_FlyMsgManager:showNormalMsg(L_ConditionManager:getSingleDesc(condition))
    end
    return false
  end
  if self.lv >= L_PetStore:getPetMaxLevel(true) then
    L_FlyMsgManager:showNormalMsg(L_Lang:get(L_WordsTpl:getValue("ui_spirit_exp_limit")))
    return false
  end
  return self.lv < self.maxLv
end

function this:getPetExpAll(targetLv)
  local maxLv = self.maxLv
  if not math.isEmpty(targetLv) then
    maxLv = targetLv
  end
  local pet = L_PetStore:getPetItem(self.petGuid)
  local petExpAll = 0 - pet.exp
  for i = pet.lv, maxLv - 1 do
    petExpAll = petExpAll + _petLevelTpl:getExp(_petLevelTpl:getTplById(i))
  end
  return petExpAll
end

function this:onBtnAutoSetUpLv()
  local petItem = L_PetStore:getPetItem(self.petGuid)
  if petItem.lv >= L_PetStore:getPetMaxLevel() then
    L_PetManager:petHintInfo(5)
    return
  end
  if petItem.lv >= L_PetStore:getPetMaxLevel(true) then
    local tpl = _petLevelTpl:getTplById(petItem.lv + 1)
    local condition = _petLevelTpl:getCondition(tpl)
    local bCompelte = true
    if not table.isEmpty(condition) then
      bCompelte = L_ConditionManager:singleIsComplete(condition)
    end
    if not bCompelte then
      L_FlyMsgManager:showNormalMsg(L_ConditionManager:getSingleDesc(condition))
    end
    return
  end
  if self.lv >= L_PetStore:getPetMaxLevel(true) then
    L_FlyMsgManager:showNormalMsg(L_Lang:get(L_WordsTpl:getValue("ui_spirit_exp_limit")))
    return
  end
  local tempExpAll = 0
  local data = {}
  for _, module in ipairs(self.modules.list_cellPetExpFruitItem) do
    local itemId = module:getItemId()
    local exp = _commonItemTpl:getUseFunction(_commonItemTpl:getTplById(itemId))[1]
    tempExpAll = tempExpAll + L_BagStore:getItemNum(itemId) * exp
    data[exp] = L_BagStore:getItemNum(itemId)
  end
  if tempExpAll == 0 then
    L_PetManager:petHintInfo(3)
    return
  end
  local petExpAll = self:getPetExpAll()
  local exp = 0
  if tempExpAll >= petExpAll then
    exp = petExpAll
  else
    exp = tempExpAll
  end
  for _, module in ipairs(self.modules.list_cellPetExpFruitItem) do
    module:setSelectNum(0)
  end
  for k, v in pairs(L_PetManager:autoLvUp(data, exp)) do
    for _, module in ipairs(self.modules.list_cellPetExpFruitItem) do
      local itemId = module:getItemId()
      local exp = _commonItemTpl:getUseFunction(_commonItemTpl:getTplById(itemId))[1]
      if exp == k and v ~= 0 then
        module:setSelectNum(v)
        module:setSelectState(true)
      end
    end
  end
  self:onPetExpFruitSelectChange()
end

function this:refreshPetAttributeList()
  local allPetFeedItemTpl = _petFeedItemTpl:getAllTpl()
  local petAttributeFruitItemList = {}
  for id, _ in pairs(allPetFeedItemTpl) do
    local itemId = id
    local itemType = L_Const.CommonItemSubType.kPetTalentFeed
    local itemNum = L_BagStore:getItemNum(itemId)
    local itemConfig = {
      itemId = itemId,
      itemType = itemType,
      itemNum = itemNum,
      onSelectChangeNumChangeCbk = function()
        self:onPetAttrFruitSelectNumChange()
      end
    }
    table.insert(petAttributeFruitItemList, itemConfig)
  end
  if #petAttributeFruitItemList % colNum ~= 0 then
    local num = colNum - #petAttributeFruitItemList % colNum
    for i = 1, num do
      table.insert(petAttributeFruitItemList, {})
    end
  end
  self.bind.list_cellPetAttributeFruitItem:clear()
  self.bind.list_cellPetAttributeFruitItem:insert_array(petAttributeFruitItemList)
  local count = math.ceil(#petAttributeFruitItemList / 2)
  local height1 = count * 188 + (count - 1) * -4 + 100 + 440
  self.bindComponents.Content:SetSizeWithCurrentAnchors(1, height1)
end

function this:onPetAttrFruitSelectNumChange()
  local preUseFruitInfoList = self:getPreUseFruitInfoList()
  self.parent:onPetAttrFruitSelectNumChange(preUseFruitInfoList)
end

function this:resetSelectNum()
  for i = 1, #self.bind.list_cellPetAttributeFruitItem do
    local cellPetAttributeFruitItem = self.bind.list_cellPetAttributeFruitItem:getItemCls(i)
    cellPetAttributeFruitItem:resetSelectNum()
  end
  self:onPetAttrFruitSelectNumChange()
  for i = 1, #self.bind.list_cellPetExpFruitItem do
    local cellPetExpFruitItem = self.bind.list_cellPetExpFruitItem:getItemCls(i)
    cellPetExpFruitItem:resetSelectNum()
  end
  self:onPetExpFruitSelectChange()
  self.parent:resetBtnCultivateClickHistory()
  self.parent:refreshUI()
end

function this:checkIfCanAddSelectNumOfTargetFruitItem(itemId)
  local ifCanAdd = false
  local addResultComprehensionExpList = self:getAddResultComprehensionExpList()
  local allComprehensionMaxNeedExpList = _petTalentUpgradeTpl:getAllComprehensionMaxNeedExpList()
  local targetFruitItemAddComprehensionAttrEnumNumList = self:getTargetFruitItemAddComprehensionAttrEnumNumList(itemId)
  for _, attrEnumNum in pairs(targetFruitItemAddComprehensionAttrEnumNumList) do
    local addResultComprehensionExp = addResultComprehensionExpList[attrEnumNum]
    local oneComprehensionMaxNeedExp = allComprehensionMaxNeedExpList[attrEnumNum]
    if addResultComprehensionExp < oneComprehensionMaxNeedExp then
      ifCanAdd = true
    end
  end
  return ifCanAdd
end

function this:getAddResultComprehensionExpList()
  local preUseFruitInfoList = self:getPreUseFruitInfoList()
  local addComprehensionExpList = self:getAddComprehensionExpListByPreUseFruitInfoList(preUseFruitInfoList)
  local petCurComprehensionExpList = self:getPetCurComprehensionExpList()
  local addResultComprehensionExpList = {}
  for attrEnumNum, _ in pairs(addComprehensionExpList) do
    local curComprehensionExp = petCurComprehensionExpList[attrEnumNum]
    local addComprehensionExp = addComprehensionExpList[attrEnumNum]
    local resultComprehensionExp = curComprehensionExp + addComprehensionExp
    addResultComprehensionExpList[attrEnumNum] = resultComprehensionExp
  end
  return addResultComprehensionExpList
end

function this:getPreUseFruitInfoList()
  local preUseFruitInfoList = {}
  for i = 1, #self.bind.list_cellPetAttributeFruitItem do
    local cellPetAttributeFruitItem = self.bind.list_cellPetAttributeFruitItem:getItemCls(i)
    local itemNum = cellPetAttributeFruitItem:getSelectNum()
    if 0 < itemNum then
      local itemId = cellPetAttributeFruitItem:getItemId()
      table.insert(preUseFruitInfoList, {itemId = itemId, itemNum = itemNum})
    end
  end
  return preUseFruitInfoList
end

function this:getAddComprehensionExpListByPreUseFruitInfoList(preUseFruitInfoList)
  local addComprehensionExpList = {}
  local petLearingEnumTplData = _petLearingEnumTpl:getAllEnum(true)
  for _, petLearingEnumTpl in pairs(petLearingEnumTplData) do
    local attrEnumNum = _petLearingEnumTpl:getEnumNum(petLearingEnumTpl)
    addComprehensionExpList[attrEnumNum] = 0
  end
  for _, preUseFruitInfo in pairs(preUseFruitInfoList) do
    local itemId = preUseFruitInfo.itemId
    local itemNum = preUseFruitInfo.itemNum
    local petFeedItemTpl = _petFeedItemTpl:getTplById(itemId)
    local effectParamList = _petFeedItemTpl:getEffectParamList(petFeedItemTpl)
    for _, effectParam in pairs(effectParamList) do
      local attrEnumNum = effectParam[1]
      local expAddNum = effectParam[2] * itemNum
      addComprehensionExpList[attrEnumNum] = addComprehensionExpList[attrEnumNum] + expAddNum
    end
  end
  return addComprehensionExpList
end

function this:getPetCurComprehensionExpList()
  local petCurComprehensionExpList = {}
  local petItem = L_PetStore:getPetItem(self.petGuid)
  local petLearingEnumTplData = _petLearingEnumTpl:getAllEnum(true)
  for _, petLearingEnumTpl in pairs(petLearingEnumTplData) do
    local attrEnumNum = _petLearingEnumTpl:getEnumNum(petLearingEnumTpl)
    local attrComprehension = petItem:getTargetAttributeComprehension(attrEnumNum)
    local attrComprehensionCurExp = attrComprehension.cur_exp + _petTalentUpgradeTpl:getNeedExpOfTargetComprehensionTargetLevel(attrEnumNum, attrComprehension.level)
    petCurComprehensionExpList[attrEnumNum] = attrComprehensionCurExp
  end
  return petCurComprehensionExpList
end

function this:getTargetFruitItemAddComprehensionAttrEnumNumList(itemId)
  return _petFeedItemTpl:getTargetFruitItemAddComprehensionAttrEnumNumList(itemId)
end

function this:onBtnTrain()
  if L_BattleDataManager:checkPlayerBattle() then
    L_FlyMsgManager:showNormalMsg(L_BattleDataManager:getBattleBlockTips(L_Const.BattleBlockType.PetUpgrade))
    return
  end
  local petItem = L_PetStore:getPetItem(self.petGuid)
  local curProperty = L_PetStore:getPetProperty(petItem)
  local selectedInfo = self:getSelectedExpInfo()
  local preUseFruitInfoList = self:getPreUseFruitInfoList()
  local bLevelUp = self.lv > petItem.lv
  local params = {isPetLevelUp = bLevelUp}
  self:reqEatAttributeFruit(preUseFruitInfoList, bLevelUp, curProperty, params)
  self:reqLevelUp(selectedInfo, curProperty, params)
end

function this:reqEatAttributeFruit(preUseFruitInfoList, bLevelUp, curProperty, params)
  if table.isEmpty(preUseFruitInfoList) then
    return
  end
  L_PetStore:req_CSProtoPetEatAttrFruit(preUseFruitInfoList, self.petGuid, function()
    if bLevelUp then
      return
    end
    local data = self:checkShowLevelUpPage(curProperty)
    if #data < 1 then
      return
    end
    L_PetStore:playPetVoiceSound(self.configId, L_PetConst.PetSystemVoiceType.Upgrade)
    local effectParams = {
      isPetLevelUp = params.isPetLevelUp,
      attrIdList = {}
    }
    for _, singleData in pairs(data) do
      local attrId = singleData.enumId
      table.insert(effectParams.attrIdList, attrId)
    end
    self:playPetFeedItemEffect(effectParams)
  end)
end

function this:checkShowLevelUpPage(oldProperty)
  local petItem = L_PetStore:getPetItem(self.petGuid)
  local newPetProperty = L_PetStore:getPetProperty(petItem)
  local all_Attribute = _petLearingEnumTpl:getAllEnum(true)
  local tmp = {}
  for i, v in pairs(all_Attribute) do
    local enumId = _petLearingEnumTpl:getEnumNum(v)
    local curValue = newPetProperty[enumId] or 0
    local oldValue = oldProperty[enumId] or 0
    if curValue ~= oldValue then
      table.insert(tmp, {
        oldValue = oldValue,
        newValue = curValue,
        enumId = enumId
      })
    end
  end
  return tmp
end

function this:reqLevelUp(selectedInfo, curProperty, params)
  if not selectedInfo[1] then
    return
  end
  L_PetStore:req_changeLvUpPet(self.petGuid, selectedInfo, function()
    local data = self:checkShowLevelUpPage(curProperty)
    if #data < 1 then
      return
    end
    L_PetStore:playPetVoiceSound(self.configId, L_PetConst.PetSystemVoiceType.Upgrade)
    local effectParams = {
      isPetLevelUp = params.isPetLevelUp,
      attrIdList = {}
    }
    for _, singleData in pairs(data) do
      local attrId = singleData.enumId
      table.insert(effectParams.attrIdList, attrId)
    end
    self:playPetFeedItemEffect(effectParams)
  end)
end

function this:playPetFeedItemEffect(effectParams)
  local isPetLevelUp = effectParams.isPetLevelUp
  local attrIdList = effectParams.attrIdList or {}
  if table.isEmpty(attrIdList) and isPetLevelUp == false then
    return
  end
  self.parent:playPetFeedItemEffect(effectParams)
end

function this:close()
  L_PetStore:unListenCallFunc(L_PetStore.event.getNewPetSkill, self.onEvent_showPetSkillInfo)
  L_PetStore:unListenCallFunc(L_PetStore.event.updatePetSkill, self.onEvent_showPetSkillInfo)
  L_PetStore:unListenCallFunc(L_PetStore.event.convertPetSkill, self.onEvent_showPetSkillInfo)
end

return this
