local this = class("productManager")
local _productsTpl = L_GameTpl:getProductsTpl()
local _foodTpl = L_GameTpl:getFoodTpl()
local _foodGroupTpl = L_GameTpl:getFoodGroupTpl()
local _homeBuildingTpl = L_GameTpl:getHomeBuildingTpl()
local _homeBuildingProductionTpl = L_GameTpl:getHomeBuildingProductionTpl()
local _productsMultiQualityTpl = L_GameTpl:getProductsMultiQualityTpl()

function this:initialize()
  self:addEventListener()
end

function this:addEventListener()
  L_UI:addListener(L_UI.pageEvent.showed, self.onEventMessageUIShowed, self)
end

function this:dispose()
  L_UI:removeListener(L_UI.pageEvent.showed, self.onEventMessageUIShowed, self)
end

function this:onEventMessageUIShowed(pageName)
  if pageName == "pageMainCity" then
    self:onShowAllFastProductRewards()
  end
end

function this:getMaxCanProductNum(productId)
  local tpl = _productsTpl:getTplById(productId)
  local limit = _productsTpl:getNumberLimit(tpl)
  local material = _productsTpl:getMaterial(tpl)
  local minCanNum = math.maxinteger
  for i, v in pairs(material) do
    local hasNum = L_ItemTplManager:getItemNum(v[1], v[2], true)
    minCanNum = math.min(minCanNum, math.floor(hasNum / v[3]))
  end
  local count, limitCnt = self:getLimitForBuildingItem(productId)
  if limitCnt ~= nil then
    minCanNum = math.min(minCanNum, limitCnt - count)
    if minCanNum == 0 then
      minCanNum = 1
    end
  end
  return math.min(minCanNum, limit)
end

function this:reqStartProduct(param, callback)
  L_ProductStore:req_CSProtoProductStart(param, function(errCode)
    if errCode == L_Const.errorCode.ErrCodeSucc and callback then
      callback()
    end
  end)
end

function this:reqStartProductImmediately(param, callback)
  L_ProductStore:req_CSProtoProductStartImmediately(param, function(rspData, errCode)
    if errCode == L_Const.errorCode.ErrCodeSucc then
      local reward
      if rspData.rewards then
        reward = rspData.rewards
      end
      if not table.isEmpty(reward) then
        L_RewardManager:ShowReward(reward)
      end
      if callback then
        callback()
      end
    end
  end)
end

function this:reqCancelProduct(buildingGuid, productGuid, callback)
  L_ProductStore:req_CSProtoProductCancel(buildingGuid, productGuid, function(errCode)
    if errCode == L_Const.errorCode.ErrCodeSucc then
      if callback then
        callback()
      end
    else
      L_FlyMsgManager:showNormalMsg(L_WordsTpl:getValue("ui_product_get_receive_first"))
    end
  end)
end

function this:reqCollectProduct(buildingGuid, callback)
  L_ProductStore:req_CSProtoProductFinish(buildingGuid, function(rspData, errCode)
    if errCode == L_Const.errorCode.ErrCodeSucc then
      local reward
      if rspData.reward then
        reward = rspData.reward.rewards
      end
      if not table.isEmpty(reward) then
        L_RewardManager:ShowReward(rspData.reward)
      end
      local specialReward
      if rspData.special_reward then
        specialReward = rspData.special_reward.rewards
      end
      if not table.isEmpty(specialReward) then
        L_RewardManager:ShowReward(rspData.special_reward)
      end
      if callback then
        callback()
      end
    end
  end)
end

function this:reqCollectProductByPet(petGuid, buildGuid, queueGuid, callback)
  L_ProductStore:req_CSProtoProductFinishOne(buildGuid, queueGuid, function(rspData, errorCode)
    if rspData.reward then
      self:showPetFinishMsg(petGuid, rspData.reward.rewards or {})
    end
    if rspData.special_reward then
      self:showPetFinishMsg(petGuid, rspData.special_reward.rewards or {})
    end
    if callback then
      callback()
    end
  end)
end

function this:showPetFinishMsg(petGuid, protoRewards)
  local petData = L_PetStore:getPetItem(petGuid)
  local items = L_DataUtil.paresRewardProto(protoRewards)
  for _, item in ipairs(items) do
    local conf = L_ItemTplManager:getItemConfig(item.itemType, item.itemId)
    local showName = L_WordsTpl:getValue("notice_productManager", {
      [0] = petData.pet_name,
      [1] = conf.name
    })
    L_FlyMsgManager:showCommonRewardMsg(item.itemType, item.itemId, item.itemNum, showName)
    local eventData = {
      pet_id = petData.id,
      pet_guid = petGuid,
      item_id = item.itemId,
      item_num = item.itemNum,
      item_type = item.itemType
    }
    L_GameUtil.logEvent(L_Const.logEventName.pet_carry, eventData)
  end
end

function this:isProductRewarded(buildingGuid)
  local building = L_HomeStore:getHomeBuildingByGuid(buildingGuid)
  if building.status ~= L_Const.WorldMapBuildStatusType.WMBST_PRODUCT then
    return
  end
  local products = L_ProductStore:getHomeProduct(buildingGuid)
  if not products or #products == 0 then
    return
  end
  local product = products[1]
  local finishNum, _, _ = self:getProductProduceInfo(buildingGuid, product)
  if 0 < finishNum then
    return true
  end
  return false
end

function this:isMutlipleQueueFinished(buildingGuid)
  local building = L_HomeStore:getHomeBuildingByGuid(buildingGuid)
  if building.status ~= L_Const.WorldMapBuildStatusType.WMBST_PRODUCT then
    return false
  end
  local products = L_ProductStore:getHomeProduct(buildingGuid)
  if not products or #products == 0 then
    return false
  end
  local finishQueue = 0
  for k, product in ipairs(products) do
    local onceTime = self:getProduceOnceTime(buildingGuid, product.product_id)
    local nowTime = L_TimeUtil.getServerTime()
    local endTime = product.start_time + product.total_count * onceTime
    if nowTime > endTime and product.start_time ~= 0 then
      finishQueue = finishQueue + 1
    end
  end
  if 1 < finishQueue then
    return true
  end
  return false
end

function this:checkProductBuildingPetSize(tpl, size)
  if not tpl then
    return false
  end
  local homeBuildingProductionTpl = L_GameTpl:getHomeBuildingProductionTpl()
  local petSizes = homeBuildingProductionTpl:getPetSize(tpl)
  for _, petSize in ipairs(petSizes) do
    if petSize == size then
      return true
    end
  end
  return false
end

function this:getMaxproduceQueueNum(buildingId)
  local homeBuildingTpl = L_GameTpl:getHomeBuildingTpl()
  local buildingCfg = homeBuildingTpl:getTplById(buildingId)
  while not math.isEmpty(homeBuildingTpl:getNextLevel(buildingCfg)) do
    buildingCfg = homeBuildingTpl:getTplById(homeBuildingTpl:getNextLevel(buildingCfg))
  end
  local maxBuildId = homeBuildingTpl:getId(buildingCfg)
  local homeBuildingProductionTpl = L_GameTpl:getHomeBuildingProductionTpl()
  local tpl = homeBuildingProductionTpl:getTplById(maxBuildId)
  local maxNum = tpl and homeBuildingProductionTpl:getProductionQueueNum(homeBuildingProductionTpl:getTplById(maxBuildId)) or 0
  return maxNum or 1
end

function this:checkQueueNumValid(buildingId, checkLevel)
  local currentQueueNum = _homeBuildingProductionTpl:getProductionQueueNum(_homeBuildingProductionTpl:getTplById(buildingId))
  if checkLevel <= currentQueueNum then
    return true
  end
  local buildingCfg = _homeBuildingTpl:getTplById(buildingId)
  local groupId = _homeBuildingTpl:getGroupId(buildingCfg)
  local groups = _homeBuildingTpl:getGroupData(groupId)
  for k, cfg in pairs(groups) do
    local id = _homeBuildingTpl:getId(cfg)
    local queueNum = _homeBuildingProductionTpl:getProductionQueueNum(_homeBuildingProductionTpl:getTplById(id))
    if checkLevel <= queueNum then
      return false, _homeBuildingTpl:getLevel(cfg)
    end
  end
  return false, L_Const.maxInt
end

function this:getProductRewardItemData(productId)
  local tpl = _productsTpl:getTplById(productId)
  local reward = _productsTpl:getRewardId(tpl)
  if reward[1] then
    return L_DataUtil.parseRewardConfigItem(reward[1])
  end
end

function this:isBuildingOnProducing(buildingGuid)
  local serverData = L_HomeStore:getHomeBuildingByGuid(buildingGuid)
  return serverData and serverData.status == L_Const.WorldMapBuildStatusType.WMBST_PRODUCT
end

function this:isBuildingHasPet(buildingGuid)
  local serverData = L_HomeStore:getHomeBuildingByGuid(buildingGuid)
  return not math.isEmpty(serverData.station_pet_guid)
end

function this:getProduceQueueForBuilding(buildingGuid)
  local serverData = L_HomeStore:getHomeBuildingByGuid(buildingGuid)
  if not serverData then
    return {}
  end
  local buildingId = serverData.build_id
  local maxQueueNum = self:getMaxproduceQueueNum(buildingId)
  local queueData = {}
  local products = serverData.product
  for i = 1, maxQueueNum do
    local isUnlock, unlockLevel = self:checkQueueNumValid(buildingId, i)
    local isEmpty = table.isEmpty(products) or table.isEmpty(products[i]) or math.isEmpty(products[i].product_id)
    local weight = i * 100000000000
    local product
    if not isEmpty then
      weight = products[i].product_guid
      product = products[i]
    end
    table.insert(queueData, {
      isUnlock = isUnlock,
      unlockLevel = unlockLevel,
      product = product,
      isEmpty = isEmpty,
      buildingGuid = buildingGuid,
      buildingId = buildingId,
      weight = weight
    })
  end
  table.sort(queueData, function(a, b)
    return a.weight < b.weight
  end)
  return queueData
end

function this:getProduceQueueForBuildingWithoutLuaData(buildingGuid)
  local csHomeBuildData = L_HomeStore:getCsHomeBuildDataByGuid(buildingGuid)
  if not csHomeBuildData then
    return {}
  end
  local buildingId = csHomeBuildData.buildId
  local maxQueueNum = self:getMaxproduceQueueNum(buildingId)
  local queueData = {}
  local csHomeBuildProductDataList = csHomeBuildData.products
  for i = 1, maxQueueNum do
    local isUnlock, unlockLevel = self:checkQueueNumValid(buildingId, i)
    local isEmpty = i > csHomeBuildProductDataList.Count or math.isEmpty(csHomeBuildProductDataList[i - 1].productId)
    local weight = i * 100000000000
    local csHomeBuildProductData
    if not isEmpty then
      weight = csHomeBuildProductDataList[i - 1].guid
      csHomeBuildProductData = csHomeBuildProductDataList[i - 1]
    end
    table.insert(queueData, {
      isUnlock = isUnlock,
      unlockLevel = unlockLevel,
      csHomeBuildProductData = csHomeBuildProductData,
      isEmpty = isEmpty,
      buildingGuid = buildingGuid,
      buildingId = buildingId,
      weight = weight
    })
  end
  table.sort(queueData, function(a, b)
    return a.weight < b.weight
  end)
  return queueData
end

function this:getProductGuidBySpecialGuid(buildGuid, specialGuid)
  local serverData = L_HomeStore:getHomeBuildingByGuid(buildGuid)
  for _, data in ipairs(serverData.specials or {}) do
    if data.extra_guid == specialGuid then
      return data.product_guid
    end
  end
end

function this:getProductSpecialParams(buildGuid, productGuid)
  local serverData = L_HomeStore:getHomeBuildingByGuid(buildGuid)
  for _, data in ipairs(serverData.specials or {}) do
    if data.product_guid == productGuid then
      return data
    end
  end
end

function this:getProductByGuid(buildGuid, productGuid)
  local serverData = L_HomeStore:getHomeBuildingByGuid(buildGuid)
  for _, product in ipairs(serverData.product or {}) do
    if product.product_guid == productGuid then
      return product
    end
  end
end

function this:getProductByGuid(buildGuid, productGuid)
  local serverData = L_HomeStore:getHomeBuildingByGuid(buildGuid)
  for _, product in ipairs(serverData.product or {}) do
    if product.product_guid == productGuid then
      return product
    end
  end
end

function this:getCsHomeBuildProductDataWithoutLuaData(buildingGuid, productGuid)
  local csHomeBuildData = L_HomeStore:getCsHomeBuildDataByGuid(buildingGuid)
  if not csHomeBuildData then
    return nil
  end
  local csHomeBuildProductDataList = csHomeBuildData.products
  for i = 0, csHomeBuildProductDataList.Count - 1 do
    if csHomeBuildProductDataList[i].guid == productGuid then
      return csHomeBuildProductDataList[i]
    end
  end
  return nil
end

function this:getProductState(buildGuid, productGuid)
  local product = self:getProductByGuid(buildGuid, productGuid)
  local buildData = L_HomeStore:getHomeBuildingByGuid(buildGuid)
  if not product then
    return L_HomeConst.ProductQueueState.NONE
  end
  if L_SatietyStore:isBuildingPause(buildGuid) then
    local finishNum, total, _ = L_ProductManager:getProductProduceInfo(buildGuid, product)
    if total == finishNum then
      return L_HomeConst.ProductQueueState.FINISH
    end
    return L_HomeConst.ProductQueueState.PAUSE, L_SatietyStore:isEating(buildData.station_pet_guid)
  end
  local nowTime = L_TimeUtil.getServerTimeWithFloor()
  if product.start_time == 0 or nowTime < product.start_time then
    return L_HomeConst.ProductQueueState.WAITING
  end
  local onceTime
  local buildType = L_HomeUtil.getBuildingType(buildGuid)
  if buildType == L_Const.WorldMapBuildType.WMBT_HATCH then
    local special = L_ProductManager:getProductSpecialParams(buildGuid, productGuid)
    onceTime = L_PetStore:getEggIncubationTime(L_PetStore:getPetEggItem(special.extra_guid).configId, buildGuid)
  else
    onceTime = self:getProduceOnceTime(buildGuid, product.product_id)
    local protectProcessProductTime = L_GameConstTpl:getValue("HOME_PROCESS_PRODUCT_TIME")
    if onceTime < protectProcessProductTime then
      onceTime = protectProcessProductTime
    end
  end
  if nowTime < product.start_time + onceTime * product.total_count then
    return L_HomeConst.ProductQueueState.RUNNING, onceTime
  else
    return L_HomeConst.ProductQueueState.FINISH, onceTime
  end
end

function this:getProductStateWithoutLuaData(buildingGuid, productGuid)
  local csHomeBuildProductData = self:getCsHomeBuildProductDataWithoutLuaData(buildingGuid, productGuid)
  local csHomeBuildData = L_HomeStore:getCsHomeBuildDataByGuid(buildingGuid)
  if not csHomeBuildProductData then
    return L_HomeConst.ProductQueueState.NONE
  end
  local totalCount = csHomeBuildProductData.totalCount
  if totalCount == 0 then
    return L_HomeConst.ProductQueueState.FINISH
  else
    if L_SatietyStore:isBuildingPause(buildingGuid) then
      return L_HomeConst.ProductQueueState.PAUSE, L_SatietyStore:isEating(0 < csHomeBuildData.stationedPetGuidList.Count and csHomeBuildData.stationedPetGuidList[0] or 0)
    end
    local nowTime = L_TimeUtil.getServerTimeWithFloor()
    if csHomeBuildProductData.startTime == 0 or nowTime < csHomeBuildProductData.startTime then
      return L_HomeConst.ProductQueueState.WAITING
    end
    return L_HomeConst.ProductQueueState.RUNNING
  end
end

function this:checkProduceQueueAvaliable(buildingGuid)
  local queueData = self:getProduceQueueForBuilding(buildingGuid)
  for k, queue in ipairs(queueData) do
    if queue.isEmpty and queue.isUnlock then
      return true
    end
  end
  return false
end

function this:getProductProduceInfo(buildingGuid, product)
  local onceTime
  local buildType = L_HomeUtil.getBuildingType(buildingGuid)
  if buildType == L_Const.WorldMapBuildType.WMBT_HATCH then
    local special = L_ProductManager:getProductSpecialParams(buildingGuid, product.product_guid)
    onceTime = L_PetStore:getEggIncubationTime(L_PetStore:getPetEggItem(special.extra_guid).configId, buildingGuid)
  else
    onceTime = self:getProduceOnceTime(buildingGuid, product.product_id)
  end
  if product.start_time == 0 then
    return 0, product.total_count, 0
  end
  local nowTime = L_TimeUtil.getServerTimeWithFloor()
  local total = product.total_count + product.finish_count
  if onceTime <= 0 then
    onceTime = tonumber(L_Config:getConfig("game", "HOME_PROCESS_PRODUCT_TIME"))
  end
  if L_SatietyStore:isBuildingPause(buildingGuid) then
    return product.finish_count, total, product.finish_count / total
  end
  return product.finish_count, total, math.min((product.finish_count + (nowTime - product.start_time) / onceTime) / total, 1)
end

function this:getProduceOnceTime(buildingGuid, productId)
  local serverData = L_HomeStore:getHomeBuildingByGuid(buildingGuid)
  local homeBuildingProductionTpl = L_GameTpl:getHomeBuildingProductionTpl()
  local tpl = homeBuildingProductionTpl:getTplById(serverData.build_id)
  local type = homeBuildingProductionTpl:getType(tpl)
  local conditions = {
    [L_HomeConst.buffConditionType.PRODUCT_TYPE] = type
  }
  local params = {
    petGuid = serverData.station_pet_guid
  }
  return L_HomeBuffManager:getProductProduceTime(productId, conditions, params)
end

function this:getFastProduceOnceTime(productId)
  local productTpl = _productsTpl:getTplById(productId)
  if not productTpl then
    errorf("\230\151\160\230\149\136\231\154\132 product ID: " .. tostring(productId))
    return 0
  end
  local onceTime = _productsTpl:getTime(productTpl)
  return onceTime
end

function this:IsOnProducing(buildingGuid)
  local serverData = L_HomeStore:getHomeBuildingByGuid(buildingGuid)
  if L_SatietyStore:isBuildingPause(buildingGuid) then
    return false
  end
  local products = serverData.product
  if not table.isEmpty(products) then
    for _, product in pairs(products) do
      if not table.isEmpty(product) and not math.isEmpty(product.product_id) then
        local _, _, amount = self:getProductProduceInfo(serverData.guid, product)
        if amount < 1 then
          return true
        end
      end
    end
  end
  return false
end

function this:getTargetFoodForBuilding(buildingId)
  local dataList = {}
  local tpl_building = _homeBuildingTpl:getTplById(buildingId)
  local groupId = _homeBuildingTpl:getGroupId(tpl_building)
  local level = _homeBuildingTpl:getLevel(tpl_building)
  for id, tpl in pairs(_foodGroupTpl.data) do
    local needLv = _foodGroupTpl:getUnlockLevel(tpl)
    if needLv[groupId] and level + 1 >= needLv[groupId] then
      local foodGroupId = _foodGroupTpl:getId(tpl)
      table.insert(dataList, {
        isFood = true,
        id = foodGroupId,
        foodGroupId = foodGroupId,
        productIdList = _productsMultiQualityTpl:getProductIdListByFoodGroupId(foodGroupId),
        lockIconActive = level < needLv[groupId],
        unlockText = L_WordsTpl:getValue("home_product_unlock_condition", {
          [0] = needLv[groupId]
        }),
        petNeededIconActive = _productsTpl:getIsNeedPet(tpl),
        itemName = _foodGroupTpl:getName(tpl)
      })
    end
  end
  table.sort(dataList, function(a, b)
    if a.lockIconActive ~= b.lockIconActive then
      return not a.lockIconActive
    else
      return a.id < b.id
    end
  end)
  return dataList
end

function this:getTargetProductForBuilding(buildingId, tabTypeId)
  local tpl_building = _homeBuildingTpl:getTplById(buildingId)
  local groupId = _homeBuildingTpl:getGroupId(tpl_building)
  local level = _homeBuildingTpl:getLevel(tpl_building)
  local buildProductionTpl = _homeBuildingProductionTpl:getTplById(buildingId)
  local products = _productsTpl:getTplsByGroup(_homeBuildingProductionTpl:getGroupId(buildProductionTpl))
  local maxLevelTpl = _homeBuildingTpl:getMaxLevelTpl(groupId)
  local maxLevel = _homeBuildingTpl:getLevel(maxLevelTpl)
  local tmp = {}
  for i, v in pairs(products) do
    local tpl_pro = v
    local reward = _productsTpl:getRewardId(tpl_pro)
    local tabId = _productsTpl:getTabId(tpl_pro)
    local itemData = L_DataUtil.parseRewardConfigItem(reward[1])
    local itemParse = L_ItemTplManager:getItemConfig(itemData.itemType, itemData.itemId)
    local detectLevel = math.min(level + 1, maxLevel)
    local condition = _productsTpl:getUnlockCondition(tpl_pro)
    local isCompleted, _ = L_ConditionManager:isComplete(condition)
    local overLimit = false
    if itemData.itemType == L_Const.resType.homeBuilding then
      local tplBuilding = _homeBuildingTpl:getTplById(itemData.itemId)
      local itemGroupId = _homeBuildingTpl:getGroupId(tplBuilding)
      local limitCnt = L_HomeStore:getBuildingLimitCount(itemGroupId)
      local count = L_HomeStore:getCurNumByBuildingGroupId(itemGroupId)
      if not limitCnt or count then
        overLimit = false
      else
        overLimit = limitCnt <= count
      end
    end
    local needLv = _productsTpl:unlockBuildingLevel(tpl_pro)
    if detectLevel >= needLv and (not tabTypeId or tabId == tabTypeId) and isCompleted then
      local productId = _productsTpl:getId(tpl_pro)
      table.insert(tmp, {
        id = productId,
        productId = productId,
        lockIconActive = level < needLv,
        unlockText = L_WordsTpl:getValue("home_product_unlock_condition", {
          [0] = needLv
        }),
        petNeededIconActive = _productsTpl:getIsNeedPet(tpl_pro),
        itemData = itemData,
        itemName = itemParse.name,
        overLimit = overLimit
      })
    end
  end
  table.sort(tmp, function(a, b)
    if a.overLimit ~= b.overLimit then
      return not a.overLimit
    elseif a.lockIconActive ~= b.lockIconActive then
      return not a.lockIconActive
    else
      return a.id < b.id
    end
  end)
  return tmp
end

function this:getAllProductForBuilding(buildingId, tabId)
  local tpl_building = _homeBuildingTpl:getTplById(buildingId)
  local homeBuildGroupId = _homeBuildingTpl:getGroupId(tpl_building)
  local level = _homeBuildingTpl:getLevel(tpl_building)
  local homeBuildingProductionTpl = _homeBuildingProductionTpl:getTplById(buildingId)
  local buildingProductionGroup = _homeBuildingProductionTpl:getGroupId(homeBuildingProductionTpl)
  local products = _productsTpl:getTplsByGroup(buildingProductionGroup)
  local maxLevelHomeBuildingTpl = _homeBuildingTpl:getMaxLevelTpl(homeBuildGroupId)
  local homeBuildingMaxLevel = _homeBuildingTpl:getLevel(maxLevelHomeBuildingTpl)
  local tmp = {}
  for _, v in pairs(products) do
    local productsTpl = v
    local material = _productsTpl:getMaterial(productsTpl)
    if material ~= nil and not table.isEmpty(material) then
      local reward = _productsTpl:getRewardId(productsTpl)
      local productTabId = _productsTpl:getTabId(productsTpl)
      local itemData = L_DataUtil.parseRewardConfigItem(reward[1])
      local itemParse = L_ItemTplManager:getItemConfig(itemData.itemType, itemData.itemId)
      local detectLevel = math.min(level + 1, homeBuildingMaxLevel)
      local condition = _productsTpl:getUnlockCondition(productsTpl)
      local isCompleted, _ = L_ConditionManager:isComplete(condition)
      local overLimit = false
      if itemData.itemType == L_Const.resType.homeBuilding then
        local tplBuilding = _homeBuildingTpl:getTplById(itemData.itemId)
        local itemGroupId = _homeBuildingTpl:getGroupId(tplBuilding)
        local limitCnt = L_HomeStore:getBuildingLimitCount(itemGroupId)
        local count = L_HomeStore:getCurNumByBuildingGroupId(itemGroupId)
        if not limitCnt or count then
          overLimit = false
        else
          overLimit = limitCnt <= count
        end
      end
      local needLv = _productsTpl:unlockBuildingLevel(productsTpl)
      if detectLevel >= needLv and (not tabId or tabId == productTabId) and isCompleted then
        local productId = _productsTpl:getId(productsTpl)
        table.insert(tmp, {
          id = productId,
          productId = productId,
          lockIconActive = level < needLv,
          unlockText = L_WordsTpl:getValue("home_product_unlock_condition", {
            [0] = needLv
          }),
          petNeededIconActive = _productsTpl:getIsNeedPet(productsTpl),
          itemData = itemData,
          itemName = itemParse.name,
          overLimit = overLimit
        })
      end
    end
  end
  for foodGroupId, foodGroupTpl in pairs(_foodGroupTpl.data) do
    local needLv = _foodGroupTpl:getUnlockLevel(foodGroupTpl)
    if needLv[homeBuildGroupId] and level + 1 >= needLv[homeBuildGroupId] then
      table.insert(tmp, {
        isFood = true,
        id = foodGroupId,
        foodGroupId = foodGroupId,
        productIdList = _productsMultiQualityTpl:getProductIdListByFoodGroupId(foodGroupId),
        lockIconActive = level < needLv[homeBuildGroupId],
        unlockText = L_WordsTpl:getValue("home_product_unlock_condition", {
          [0] = needLv[homeBuildGroupId]
        }),
        petNeededIconActive = _productsTpl:getIsNeedPet(foodGroupTpl),
        itemName = _foodGroupTpl:getName(foodGroupTpl)
      })
    end
  end
  table.sort(tmp, function(a, b)
    if not a.isFood and not b.isFood then
      if a.overLimit ~= b.overLimit then
        return not a.overLimit
      elseif a.lockIconActive ~= b.lockIconActive then
        return not a.lockIconActive
      else
        return a.id < b.id
      end
    elseif not a.isFood and b.isFood then
      return true
    elseif a.isFood and b.isFood then
      if a.lockIconActive ~= b.lockIconActive then
        return not a.lockIconActive
      else
        return a.id < b.id
      end
    end
  end)
  return tmp
end

function this:getLimitForBuildingItem(productId)
  local tpl_pro = _productsTpl:getTplById(productId)
  local reward = _productsTpl:getRewardId(tpl_pro)
  if table.isEmpty(reward) then
    return
  end
  local itemData = L_DataUtil.parseRewardConfigItem(reward[1])
  if itemData.itemType ~= L_Const.resType.homeBuilding then
    return 0
  end
  local tplBuilding = _homeBuildingTpl:getTplById(itemData.itemId)
  local itemGroupId = _homeBuildingTpl:getGroupId(tplBuilding)
  local limitCnt = L_HomeStore:getBuildingLimitCount(itemGroupId)
  local count = L_HomeStore:getCurNumByBuildingGroupId(itemGroupId)
  return count, limitCnt
end

function this:getIsHomeWorkBuildingNeedPet(buildingGuid)
  if math.isEmpty(buildingGuid) then
    return false
  end
  local serverData = L_HomeStore:getHomeBuildingByGuid(buildingGuid)
  local tpl_proBuilding = _homeBuildingProductionTpl:getTplById(serverData.building_id)
  if not tpl_proBuilding then
    return false
  end
  local products = serverData.product
  for i, v in pairs(products) do
    local tpl_pro = _productsTpl:getTplById(v.product_id)
    if _productsTpl:getIsNeedPet(tpl_pro) then
      return true
    end
  end
  return false
end

function this:getAllCanProductList()
  local configList = _productsTpl:getConfig()
  local dataList = {}
  for _, value in pairs(configList) do
    if value.isQuickProduct and L_ConditionManager:isComplete(value.unlockCondition) then
      local productId = value.id
      local rewardInfo = value.rewardId[1]
      local rewardItemType = rewardInfo[1]
      local rewardItemId = rewardInfo[2]
      local maxProductCount = self:onGetMaxCountFastProduct(productId)
      local item = {
        productId = productId,
        itemId = rewardItemId,
        itemType = rewardItemType,
        groupType = value.group,
        maxCount = maxProductCount
      }
      table.insert(dataList, item)
    end
  end
  return dataList
end

function this:onGetHomeBuildFunctionType(buildGroupType)
  local type = L_HomeConst.HomeBuildFunctionType.PRODUCT
  if buildGroupType == L_HomeConst.HomeBuildGroupType.TABLE_CUISINE or buildGroupType == L_HomeConst.HomeBuildGroupType.SHOP_CUISINE then
    type = L_HomeConst.HomeBuildFunctionType.CUISINE
  elseif buildGroupType == L_HomeConst.HomeBuildGroupType.TABLE_WEAPON_STATION or buildGroupType == L_HomeConst.HomeBuildGroupType.TABLE_ARMOR or buildGroupType == L_HomeConst.HomeBuildGroupType.TABLE_JEWELRY or buildGroupType == L_HomeConst.HomeBuildGroupType.SHOP_FORGE or buildGroupType == L_HomeConst.HomeBuildGroupType.SHOP_ARMOR or buildGroupType == L_HomeConst.HomeBuildGroupType.SHOP_JEWELRY then
    type = L_HomeConst.HomeBuildFunctionType.EQUIP
  end
  return type
end

function this:onIsHadIdleQueueWithFastProduct()
  local productList = L_ProductStore:getFastProductList()
  if table.isEmpty(productList) or table.count(productList) < 4 then
    return true
  end
  for _, value in pairs(productList) do
    if table.isEmpty(value) then
      return true
    end
  end
  return false
end

function this:onShowAllFastProductRewards(isForce)
  local curPageName = L_UI:currentPage(L_UI.groupKeys.stack)
  if not isForce and curPageName ~= "pageMainCity" then
    return
  end
  local rewardList = L_ProductStore:getFastProductRewards()
  if table.isEmpty(rewardList) then
    return
  end
  for _, reward in ipairs(rewardList) do
    L_RewardManager:ShowReward(reward)
  end
  L_ProductStore:setClearFastProductRewards()
end

function this:onHadInFastProduct(productId)
  local productList = L_ProductStore:getFastProductList()
  if table.isEmpty(productList) then
    return false
  end
  for _, value in pairs(productList) do
    if value.product_id == productId then
      return true
    end
  end
  return false
end

function this:onGetMaxCountFastProduct(productId)
  local tpl = _productsTpl:getTplById(productId)
  local maxCount = 0
  local reward = _productsTpl:getRewardId(tpl)
  if not table.isEmpty(reward) then
    local itemData = L_DataUtil.parseRewardConfigItem(reward[1])
    if itemData.itemType == L_Const.resType.homeBuilding then
      local tplBuilding = _homeBuildingTpl:getTplById(itemData.itemId)
      local itemGroupId = _homeBuildingTpl:getGroupId(tplBuilding)
      maxCount = L_HomeStore:getBuildingLimitCount(itemGroupId)
    end
  end
  return maxCount
end

function this:onGetInFastProductCount(productId)
  local productList = L_ProductStore:getFastProductList()
  if table.isEmpty(productList) then
    return 0
  end
  local count = 0
  for _, value in pairs(productList) do
    if value.product_id == productId then
      count = count + value.total_count
    end
  end
  return count
end

function this:onGetAllFastProductCount(productId, inProduct)
  local tpl = _productsTpl:getTplById(productId)
  local reward = _productsTpl:getRewardId(tpl)
  if table.isEmpty(reward) then
    return 0
  end
  local itemData = L_DataUtil.parseRewardConfigItem(reward[1])
  local hadCount = 0
  if itemData.itemType == L_Const.resType.homeBuilding then
    local tplBuilding = _homeBuildingTpl:getTplById(itemData.itemId)
    local itemGroupId = _homeBuildingTpl:getGroupId(tplBuilding)
    hadCount = L_HomeStore:getCurNumByBuildingGroupId(itemGroupId)
  else
    hadCount = L_ItemTplManager:getItemNum(itemData.itemType, itemData.itemId)
  end
  if inProduct then
    local inProductNum = self:onGetInFastProductCount(productId)
    hadCount = hadCount + inProductNum
  end
  return hadCount
end

return this
