local this = class("moduleProductFormulaNormalNew", G_UIModuleBase)
local _productsTpl = L_GameTpl:getProductsTpl()
local _foodGroupTpl = L_GameTpl:getFoodGroupTpl()
local _productsMaterialGroupTpl = L_GameTpl:getProductsMaterialGroupTpl()
local _commonTabTpl = L_GameTpl:getCommonTabTpl()
local _commonItemTpl = L_GameTpl:getCommonItemTpl()
local _homeBuildingTpl = L_GameTpl:getHomeBuildingTpl()
local _homeBuildingGroupTpl = L_GameTpl:getHomeBuildingGroupTpl()
local _productsMultiQualityTpl = L_GameTpl:getProductsMultiQualityTpl()
local _foodMaterialTpl = L_GameTpl:getFoodMaterialGroupTpl()
local _foodTpl = L_GameTpl:getFoodTpl()
local _petEggTpl = L_GameTpl:getPetEggTpl()

function this.bind()
  return {
    txt_envName = "",
    txt_name = "",
    img_quality = "",
    img_icon = "",
    img_iconFilter = "",
    list_star = {},
    list_materials = {
      moduleName = "pages/product/cellProductMaterial"
    },
    active_heroIcon = false,
    img_heroIcon = "",
    active_autoSelectMaterialOfMultiQuaProduct = false,
    txt_autoSelectMaterialOfMultiQuaProduct = L_WordsTpl:getValue("ui_moduleProduct_02")
  }
end

function this.methods()
  return {
    onClick_autoSelectMaterialOfMultiQuaProduct = function(self)
      self:onClickAutoSelectMaterialOfMultiQuaProduct()
      self:refreshAutoSelectMultiQuaProductMaterialBtnText()
    end
  }
end

function this:open()
  self.moduleData = {}
  self._selectNum = 1
  self:refreshView()
  
  function self._onBagNumChange()
    self._selectGuid = 0
    self:refreshMaterial()
  end
  
  L_BagStore:listenCallFunc(L_BagStore.event.refreshBag, self._onBagNumChange)
  L_ProductStore:listenCallFunc(L_ProductStore.event.refreshHomeProduct, self.refreshView, self)
end

function this:close()
  self._selectGuid = 0
  L_BagStore:unListenCallFunc(L_BagStore.event.refreshBag, self._onBagNumChange)
  L_ProductStore:unListenCallFunc(L_ProductStore.event.refreshHomeProduct, self.refreshView, self)
end

function this:hide()
  self._selectGuid = 0
end

function this:setProduct(buildingGuid, id, buildType)
  self.moduleData.isMultiQuality = false
  self.moduleData.productInfoDescType = L_HomeConst.ProductInfoDescType.Normal
  self._buildingGuid = buildingGuid
  self._id = id
  self._selectNum = 1
  self.viewIndex2groupDataIndex = {
    1,
    1,
    1,
    1
  }
  self:refreshView()
end

function this:refreshSingleQuaProductView()
  if not self.isBind or not self._id then
    return
  end
  local id = self._id
  local tpl = _productsTpl:getTplById(id)
  local tabId = _productsTpl:getTabId(tpl)
  local reward = L_DataUtil.parseRewardConfigItem(_productsTpl:getRewardId(tpl)[1])
  local item = L_ItemTplManager:getItemConfig(reward.itemType, reward.itemId)
  self:InitItemInfo(reward.itemType, reward.itemId, tabId)
  self.bind.petIconActive = _productsTpl:getIsNeedPet(tpl)
  self:refreshMaterial()
  self.bind.active_autoSelectMaterialOfMultiQuaProduct = false
end

function this:InitItemInfo(itemType, itemId, tabId)
  self._itemType = itemType
  self._itemId = itemId
  local conf = L_ItemTplManager:getItemConfig(itemType, itemId)
  local tabTpl = _commonTabTpl:getTplById(tabId)
  if not math.isEmpty(self._buildingGuid) then
    if tabTpl then
      local buildTag = _commonTabTpl:getProductBuild(tabTpl)
      self.bind.txt_envName = string.format("~%s~", buildTag)
    else
      local buildingData = L_HomeStore:getHomeBuildingByGuid(self._buildingGuid)
      local buildingTpl = _homeBuildingTpl:getTplById(buildingData.build_id)
      local buildingGroupTpl = _homeBuildingGroupTpl:getTplById(_homeBuildingTpl:getGroupId(buildingTpl))
      self.bind.txt_envName = string.format("~%s~", _homeBuildingGroupTpl:getProduceTypeTitle(buildingGroupTpl))
    end
  else
    self.bind.txt_envName = L_WordsTpl:getValue("ui_moduleProductFormulaCookNew")
  end
  local pattern1 = string.match(conf.name, " %a+.%d+")
  local pattern2 = string.match(conf.name, "%a+.%d+")
  if pattern1 then
    self.bind.txt_name = string.gsub(conf.name, pattern1, "")
  elseif pattern2 then
    self.bind.txt_name = string.gsub(conf.name, pattern2, "")
  else
    self.bind.txt_name = conf.name
  end
  local commonItemTpl = _commonItemTpl:getTplById(itemId)
  self.bind.img_iconFilter = commonItemTpl and _commonItemTpl:getFilterIcon(commonItemTpl) or ""
  self.bind.img_icon = conf.icon
  self.bind.img_quality = string.format("UI/Atlas/Home/tex_homecommontip_bg_quality_%s.png", tostring(conf.quality))
  self:_setStars(conf.quality + 1)
end

function this:refreshSingleQuaProductMaterial()
  if self._id == nil then
    return
  end
  local tpl = _productsTpl:getTplById(self._id)
  if not tpl then
    return
  end
  local fixedMaterialList = _productsTpl:getMaterial(tpl)
  local materialSelectList = _productsTpl:getMaterialSelectList(tpl)
  local groupDataList = {}
  for _, materialGroupId in ipairs(materialSelectList) do
    local groupData = table.clone(_productsMaterialGroupTpl:getGroupDataByMaterialGroupId(materialGroupId))
    table.insert(groupDataList, groupData)
  end
  local tmp = L_DataUtil.getEmptyModuleDatas(4)
  local index = 0
  for _, groupData in ipairs(groupDataList) do
    index = index + 1
    if 4 < index then
      break
    end
    local itemData = groupData[self.viewIndex2groupDataIndex[index]]
    local viewIndex = index
    tmp[viewIndex] = {
      singleNum = itemData.itemNum,
      needNum = itemData.itemNum * self._selectNum,
      hadNum = L_BagStore:getItemNum(itemData.itemId),
      itemType = itemData.itemType,
      itemId = itemData.itemId,
      changeCallback = function()
        L_UI:open("pageHomeProductSelectMaterial", {
          groupData = groupData,
          selectNum = self._selectNum,
          callback = function(selectIndex)
            self.viewIndex2groupDataIndex[viewIndex] = selectIndex
            self:refreshMaterial()
            self.parent:initSelectNum()
          end,
          select = self.viewIndex2groupDataIndex[viewIndex]
        })
      end
    }
  end
  for i, v in ipairs(fixedMaterialList) do
    index = index + 1
    if 4 < index then
      break
    end
    local reward = L_DataUtil.parseRewardConfigItem(v)
    if reward.itemType == L_Const.resType.commonItem then
      tmp[index] = {
        singleNum = reward.itemNum,
        needNum = reward.itemNum * self._selectNum,
        hadNum = L_BagStore:getItemNum(reward.itemId),
        itemType = reward.itemType,
        itemId = reward.itemId
      }
    end
  end
  for _, v in ipairs(fixedMaterialList) do
    local reward = L_DataUtil.parseRewardConfigItem(v)
    if reward.itemType == L_Const.resType.accessory then
      tmp[4] = {
        singleNum = 1,
        needNum = 1,
        hadNum = math.isEmpty(self._selectGuid) and 0 or 1,
        itemType = reward.itemType,
        itemId = reward.itemId,
        changeCallback = function()
          local guids = L_AccessoryManager:getAccessoryGuidsById(reward.itemId)
          if 0 < #guids then
            L_UI:open("pageAccessorySelect", {
              id = reward.itemId,
              callback = function(guid)
                self._selectGuid = guid
                self:refreshMaterial()
              end,
              select = self._selectGuid
            })
          else
            L_FlyMsgManager:showNormalMsgByKey("notice_moduleProductFormulaNormalNew")
          end
        end
      }
    end
  end
  if not math.isEmpty(self._selectGuid) then
    local acc = L_AccessoryStore:getAccessory(self._selectGuid)
    self._heroId = acc.wearHero
  else
    self._heroId = nil
  end
  self.bind.active_heroIcon = not math.isEmpty(self._heroId)
  if self.bind.active_heroIcon then
    local heroData = L_HeroStore:getHero(self._heroId)
    local heroConf = L_ItemTplManager:getHeroItem(L_HeroStore:getHeroConfigId(heroData))
    self.bind.img_heroIcon = heroConf.icon
    if self._heroId == L_HeroStore:getDefaultHeroGuid() then
      L_PhotoManager:newOrBindPhotoEntity(self, self.bindComponents.img_heroIcon, L_PlayerStore:getPlayerModHeadImgName())
    else
      L_PhotoManager:clearPhotoEntity(self)
    end
  end
  self.bind.list_materials:clear()
  self.bind.list_materials:insert_array(tmp)
end

function this:getSelectedGuid()
  return self._selectGuid
end

function this:getSelectedHeroId()
  return self._heroId
end

function this:getSelectMaterialTableIdList()
  local tpl = _productsTpl:getTplById(self._id)
  local materialSelectList = _productsTpl:getMaterialSelectList(tpl)
  if materialSelectList == nil or table.isEmpty(materialSelectList) then
    return {}
  end
  local result = {}
  for i, materialGroupId in pairs(materialSelectList) do
    local groupDataIndex = self.viewIndex2groupDataIndex[i]
    local groupData = table.clone(_productsMaterialGroupTpl:getGroupDataByMaterialGroupId(materialGroupId))
    local itemData = groupData[groupDataIndex]
    local tableId = itemData.tableId
    table.insert(result, tableId)
  end
  return result
end

function this:getSingleQualityProductMaxCanDo()
  local canNum = L_Const.maxInt
  for _, cellProductMaterial in ipairs(self.modules.list_materials) do
    if cellProductMaterial.bind.itemId then
      local oneNum = cellProductMaterial.bind.singleNum
      local haveNum = cellProductMaterial.bind.hadNum
      canNum = math.min(canNum, math.floor(haveNum / oneNum))
    end
  end
  if self._itemType == L_Const.resType.homeBuilding then
    local tpl_building = _homeBuildingTpl:getTplById(self._itemId)
    local groupId = _homeBuildingTpl:getGroupId(tpl_building)
    local limitCnt = L_HomeStore:getBuildingLimitCount(groupId)
    local count = L_HomeStore:getCurNumByBuildingGroupId(groupId)
    local restCount = limitCnt - count
    return math.min(canNum, restCount)
  end
  return canNum
end

function this:setFoodGroup(groupId)
  self.moduleData.isMultiQuality = true
  self.moduleData.productInfoDescType = L_HomeConst.ProductInfoDescType.Normal
  self.multiQuaProductData = self.multiQuaProductData or {}
  if self.multiQuaProductData.foodGroupId == groupId then
    return
  end
  printf("\232\174\190\231\189\174\233\163\159\231\137\169\231\187\132" .. groupId)
  local oldFoodGroupId = self.multiQuaProductData.foodGroupId
  self.multiQuaProductData.foodGroupId = groupId
  self.multiQuaProductData.isFoodAutoReverse = oldFoodGroupId == self.multiQuaProductData.foodGroupId and self.multiQuaProductData.isFoodAutoReverse or nil
  self.multiQuaProductData.selectNum = oldFoodGroupId == self.multiQuaProductData.foodGroupId and self.multiQuaProductData.selectNum or 1
  self:refreshAutoSelectMaterialOfMultiQualityProduct()
end

function this:refreshAutoSelectMaterialOfMultiQualityProduct()
  self.multiQuaProductData.curSelectRars = {
    0,
    0,
    0,
    0
  }
  if not math.isEmpty(self.multiQuaProductData.foodGroupId) then
    local foodIdList = _productsMultiQualityTpl:getItemIdListByFoodGroupId(self.multiQuaProductData.foodGroupId)
    local foodId = foodIdList[1]
    local materials = _productsMultiQualityTpl:getNeedMaterialByConfigId(foodId)
    for x = 1, 4 do
      local material = materials[x]
      if material then
        local materialGroupId = material[1]
        local needNum = material[2]
        local needRarity = material[3]
        local itemIds = _foodMaterialTpl:getGroupItemIds(materialGroupId)
        self.multiQuaProductData.curSelectRars[x] = material[3]
        if self.multiQuaProductData.isFoodAutoReverse then
          for i = 5, 1, -1 do
            if i >= needRarity and itemIds[i] and needNum < L_BagStore:getItemNum(itemIds[i]) then
              self.multiQuaProductData.curSelectRars[x] = i
              break
            end
          end
        else
          for i = 1, 5 do
            if i >= needRarity and itemIds[i] and needNum < L_BagStore:getItemNum(itemIds[i]) then
              self.multiQuaProductData.curSelectRars[x] = i
              break
            end
          end
        end
      end
    end
  end
  printf("\233\128\137\230\139\169\231\187\147\230\158\156", self.multiQuaProductData.curSelectRars)
  self:initMultiQuaProduct()
end

function this:initMultiQuaProduct()
  self.multiQuaProductData.productsMultiQualityTpl = _productsMultiQualityTpl:getCanDoTpl(self.multiQuaProductData.foodGroupId, self.multiQuaProductData.curSelectRars)
  self.multiQuaProductData.productId = _productsMultiQualityTpl:getProductIdByConfigId(self.multiQuaProductData.productsMultiQualityTpl.id)
  self.parent:changeMultiQuaProductId(self.multiQuaProductData.productId)
end

function this:getSelectFoodInfo()
  return self.multiQuaProductData.productsMultiQualityTpl, self.multiQuaProductData.curSelectRars
end

function this:refreshMultiQuaProductView()
  if not self.isBind or not self.multiQuaProductData.productId then
    return
  end
  local id = self.multiQuaProductData.productId
  local tpl = _productsTpl:getTplById(id)
  local reward = L_DataUtil.parseRewardConfigItem(_productsTpl:getRewardId(tpl)[1])
  local item = L_ItemTplManager:getItemConfig(reward.itemType, reward.itemId)
  self:refreshMultiQuaProductInfo(reward.itemType, reward.itemId, {
    itemNumTxt = item.name
  })
  self:refreshMaterial()
  self:refreshAutoSelectMultiQuaProductMaterialBtnText()
end

function this:refreshMultiQuaProductMaterial()
  if not self.multiQuaProductData.productsMultiQualityTpl then
    return
  end
  local tmp = L_DataUtil.getEmptyModuleDatas(4)
  local materials = _foodTpl:getNeedMaterial(self.multiQuaProductData.productsMultiQualityTpl)
  for i, material in ipairs(materials) do
    local itemId = _foodMaterialTpl:getItemId(material[1], self.multiQuaProductData.curSelectRars[i])
    local item_tmp = L_ItemTplManager:getCommonItem(itemId)
    local itemIds = _foodMaterialTpl:getGroupItemIds(material[1])
    tmp[i] = {
      hadNum = L_BagStore:getItemNum(itemId),
      needNum = material[2] * self.multiQuaProductData.selectNum,
      color = item_tmp.quality,
      itemType = L_Const.resType.commonItem,
      itemId = itemId,
      changeCallback = 1 < #itemIds and function()
        L_UI:open("pageCookSelectMaterial", {
          groupId = material[1],
          callback = function(selectIndex)
            self.multiQuaProductData.curSelectRars[i] = selectIndex
            self:initMultiQuaProduct()
          end,
          select = self.multiQuaProductData.curSelectRars[i]
        })
      end or nil
    }
  end
  self.bind.list_materials:clear()
  self.bind.list_materials:insert_array(tmp)
end

function this:refreshMultiQuaProductInfo(itemType, itemId, params)
  local conf = L_ItemTplManager:getItemConfig(itemType, itemId)
  self.bind.txt_envName = L_WordsTpl:getValue("ui_moduleProductFormulaCookNew")
  local pattern = string.match(conf.name, " %a+.%d+")
  if pattern then
    self.bind.txt_name = string.gsub(conf.name, pattern, "")
  else
    self.bind.txt_name = conf.name
  end
  local commonItemTpl = _commonItemTpl:getTplById(itemId)
  self.bind.img_iconFilter = commonItemTpl and _commonItemTpl:getFilterIcon(commonItemTpl) or ""
  self.bind.img_icon = conf.icon
  self.bind.img_quality = string.format("UI/Atlas/Home/tex_homecommontip_bg_quality_%s.png", tostring(conf.quality))
  self:_setStars(conf.quality + 1)
end

function this:onClickAutoSelectMaterialOfMultiQuaProduct()
  self.multiQuaProductData.isFoodAutoReverse = not self.multiQuaProductData.isFoodAutoReverse
  self:refreshAutoSelectMaterialOfMultiQualityProduct()
end

function this:refreshAutoSelectMultiQuaProductMaterialBtnText()
  self.bind.active_autoSelectMaterialOfMultiQuaProduct = true
  self.bind.txt_autoSelectMaterialOfMultiQuaProduct = self:isFoodAutoReverse() and L_WordsTpl:getValue("ui_moduleProduct_02") or L_WordsTpl:getValue("ui_moduleProduct_01")
end

function this:isFoodAutoReverse()
  return self.multiQuaProductData.isFoodAutoReverse
end

function this:getMultiQualityProductMaxCanDo()
  return _productsMultiQualityTpl:getCanDoMaxNum(self.multiQuaProductData.productsMultiQualityTpl.id, self.multiQuaProductData.curSelectRars)
end

function this:setEggGuid(eggGuid)
  self.moduleData.isMultiQuality = false
  self.moduleData.productInfoDescType = L_HomeConst.ProductInfoDescType.Egg
  self.eggData = self.eggData or {}
  self.eggData.eggGuid = eggGuid
  self.eggData.petEggData = L_PetStore:getPetEggItem(self.eggData.eggGuid)
  self:refreshEggInfoView()
end

function this:refreshEggInfoView()
  if self.eggData == nil or self.eggData.eggGuid == nil then
    return
  end
  self.bind.active_autoSelectMaterialOfMultiQuaProduct = false
  self.bind.txt_envName = L_WordsTpl:getValue("ui_modulePetHatchEggInfoNew_01")
  self.bind.txt_name = self.eggData.petEggData.type
  self.bind.img_quality = string.format("UI/Atlas/Home/tex_homecommontip_bg_quality_%s.png", tostring(0))
  local petEggTpl = _petEggTpl:getTplById(self.eggData.petEggData.configId)
  self.bind.img_icon = _petEggTpl:getEggImgIcon(petEggTpl)
  self:_setStars(1)
end

function this:refreshView()
  if self.moduleData.productInfoDescType == L_HomeConst.ProductInfoDescType.Normal then
    if self.moduleData.isMultiQuality then
      self:refreshMultiQuaProductView()
    else
      self:refreshSingleQuaProductView()
    end
  else
    self:refreshEggInfoView()
  end
end

function this:refreshMaterial()
  if self.moduleData.isMultiQuality then
    self:refreshMultiQuaProductMaterial()
  else
    self:refreshSingleQuaProductMaterial()
  end
end

function this:checkItemSatisfy()
  for _, module in ipairs(self.modules.list_materials) do
    if not module:isSatisfy() then
      L_FlyMsgManager:showNormalMsg(L_WordsTpl:getValue("ui_product_lack_material"))
      return false
    end
  end
  return true
end

function this:setSelectNum(num)
  if self.moduleData.isMultiQuality then
    self.multiQuaProductData.selectNum = num
  else
    self._selectNum = num
  end
  self:refreshView()
end

function this:_setStars(num)
  if not self.isBind then
    return
  end
  local stars = {}
  for i = 1, num do
    table.insert(stars, {})
  end
  self.bind.list_star:clear()
  self.bind.list_star:insert_array(stars)
end

function this:getMaxCanDo()
  if self.moduleData.isMultiQuality then
    return self:getMultiQualityProductMaxCanDo()
  else
    return self:getSingleQualityProductMaxCanDo()
  end
end

return this
