local this = {}
local homeBuildingCollectionTpl = L_GameTpl:getHomeBuildingCollectionTpl()
local productsTpl = L_GameTpl:getProductsCollectionTpl()
local productsCollectionTypeTpl = L_GameTpl:getProductsCollectionTypeTpl()
local infoText = {
  noSetPet = "notice_pageCollection_05",
  satietyLow = "notice_pageCollection_04",
  inCanteen = "notice_pageCollection_03",
  unlockingLevel = "ui_moduleCanteenFree_03"
}

function this:onEvent_refreshPet()
  self:initRightShow()
end

function this:onEvent_updateCollection(updateList)
  if self.bind.infoToggle_show == false then
    return
  end
  self:refreshPauseInfo()
  self:initOutputList()
  self:refreshCollectionBuildingWorkLimitPart()
end

function this:initRightShow(needSort)
  L_TimerManager:clearTimer(self)
  if self.bind.infoToggle_show == false then
    return
  end
  local serverData = L_CollectionStore:getCollection(self._collectionGuid)
  if not table.isEmpty(serverData) then
    self.bind.infoToggle = true
    local isWorking = not math.isEmpty(serverData.start_time)
    self.bind.go_free = not isWorking
    self.bind.go_working = isWorking
    if isWorking then
      self:openTickTimer()
    else
      self:calculateCostTime(serverData)
    end
    self:refreshPauseInfo()
    self:initOutputList(needSort)
    self:initPreviewList()
    self:initCoolieModule()
  else
    self._collectionGuid = 0
    self.bind.infoToggle = false
  end
end

function this:calculateCostTime(serverData)
  local nowTime = L_TimeUtil.getServerTime()
  local pet = L_PetStore:getPetItem(serverData.pet_guid)
  local endTime = L_SatietyStore:calculateSatietyTimeStamp(pet)
  local leftTime = endTime - nowTime
  if 0 < leftTime then
    self.bind.txt_time_free = L_TimeUtil.secondToLangString(leftTime)
  else
    self.bind.txt_time_free = ""
  end
end

function this:initCoolieModule()
  if not math.isEmpty(self._collectionGuid) then
    self.modules.module_petInfo:setCollectionModule(self._collectionGuid, self._buildingGuid)
    self.modules.module_top:setCollectionId(self._collectionGuid, self._buildingGuid)
  end
end

function this:checkCollect()
  local serverData = L_CollectionStore:getCollection(self._collectionGuid)
  local tpl_building = homeBuildingCollectionTpl:getTplById(serverData.build_id)
  local needPet = homeBuildingCollectionTpl:getIsNeedPet(tpl_building)
  if needPet and math.isEmpty(serverData.pet_guid) then
    L_FlyMsgManager:showNormalMsgByKey(infoText.noSetPet)
    return
  end
  self:reqStartCollect()
end

function this:reqStartCollect()
  L_CollectionManager:reqStartCollect(self._collectionGuid, 1, function()
    self:initRightShow()
  end)
end

function this:openTickTimer()
  local serverData = L_CollectionStore:getCollection(self._collectionGuid)
  local pet = L_PetStore:getPetItem(serverData.pet_guid)
  if table.isEmpty(pet) then
    return
  end
  local endTime = L_SatietyStore:calculateSatietyTimeStamp(pet)
  self.bind.go_pause = false
  local func = function()
    local nowTime = L_TimeUtil.getServerTime()
    local leftTime = endTime - nowTime
    self.bind.go_running = 0 < leftTime
    if 0 < leftTime then
      self.bind.txt_time_running = L_TimeUtil.secondToLangString(leftTime)
    else
      local serverData = L_CollectionStore:getCollection(self._collectionGuid)
      local isWorkPause = L_SatietyStore:isWorkPause(serverData.pet_guid)
      if isWorkPause then
        local pet = L_PetStore:getPetItem(serverData.pet_guid)
        L_TimerManager:stopTimer(self, "timeTick")
        L_TimerManager:stopTimer(self, "reqCollect_timeTick")
        self.bind.go_running = false
        self.bind.go_finish = false
        self.bind.go_pause = true
        self.bind.txt_pause = pet:isInCanteen() and L_WordsTpl:getValue(infoText.inCanteen) or L_WordsTpl:getValue(infoText.satietyLow)
      end
      L_TimerManager:clearTimer(self)
    end
  end
  L_TimerManager:newOrResetTimer(self, "timeTick", func, 1, -1)
  func()
end

function this:refreshPauseInfo()
  local serverData = L_CollectionStore:getCollection(self._collectionGuid)
  local isWorkPause = L_SatietyStore:isWorkPause(serverData.pet_guid)
  if isWorkPause then
    local pet = L_PetStore:getPetItem(serverData.pet_guid)
    L_TimerManager:stopTimer(self, "timeTick")
    L_TimerManager:stopTimer(self, "reqCollect_timeTick")
    self.bind.go_running = false
    self.bind.go_finish = false
    self.bind.go_pause = true
    self.bind.txt_pause = pet:isInCanteen() and L_WordsTpl:getValue(infoText.inCanteen) or L_WordsTpl:getValue(infoText.satietyLow)
  else
    self:openTickTimer()
  end
end

function this:initOutputList(needSort)
  if needSort then
    self.bind.scrollList_collectionItem:clear()
  end
  local rewardList = L_CollectionManager:getCollectCommonItemRewardList(self._collectionGuid, needSort)
  local is_full = #rewardList >= L_CollectionManager:getMaxCollectionLimit()
  if self.bind.go_full ~= is_full then
    L_CollectionStore:call(L_CollectionStore.event.updateCollection, {
      [self._collectionGuid] = self._collectionGuid
    })
  end
  self.bind.go_full = is_full
  local lineNum = math.ceil(#rewardList / 3)
  lineNum = math.max(3, lineNum)
  self.bindComponents.gridView.disableScroll = lineNum <= 3
  local oldRewardCount = #self.modules.scrollList_collectionItem
  local newRewardCount = math.min(L_CollectionManager:getMaxCollectionLimit(), lineNum * 3)
  local rewardCache = {}
  local rewardDic = {}
  local rewardTable = {}
  for i, v in ipairs(self.modules.scrollList_collectionItem) do
    if not table.isEmpty(v.bind.reward) then
      rewardCache[v.bind.product_id] = 1
      table.insert(rewardTable, v.bind.product_id)
    end
  end
  for i, v in ipairs(rewardList) do
    if rewardDic[v.product_id] == nil then
      rewardDic[v.product_id] = L_Struct.getQueue()
    end
    rewardDic[v.product_id]:enQueue(v)
  end
  local isSame = oldRewardCount == newRewardCount
  if isSame then
    local id_map = {}
    for i, v in ipairs(self.modules.scrollList_collectionItem) do
      local reward, findIndex
      local needShowAni = false
      if rewardDic[v.bind.product_id] and rewardDic[v.bind.product_id]:getLength() > 0 then
        local length = rewardDic[v.bind.product_id]:getLength()
        id_map[v.bind.product_id] = 1
        for n = 1, length do
          reward = rewardDic[v.bind.product_id]:deQueue()
          self.modules.scrollList_collectionItem[i + n - 1]:setItem(reward, needShowAni, i + n - 1)
        end
      elseif not rewardCache[v.bind.product_id] then
        for _, k in ipairs(rewardList) do
          if id_map[k.product_id] ~= 1 then
            reward = k
            findIndex = i
            v:setItem(reward, true, findIndex)
            id_map[k.product_id] = 1
            break
          end
        end
      end
    end
  else
    local tmp = {}
    local max = math.min(lineNum * 3, L_CollectionManager:getMaxCollectionLimit())
    if 1 < #rewardTable then
      local index = 0
      for i, v in ipairs(rewardTable) do
        if rewardCache[v] and rewardDic[v]:getLength() > 0 then
          local length = rewardDic[v]:getLength()
          for i = 1, length do
            index = index + 1
            table.insert(tmp, {
              index = index,
              product_id = v,
              reward = rewardDic[v]:deQueue()
            })
          end
        end
      end
      for i, v in ipairs(rewardList) do
        if rewardCache[v.product_id] == nil then
          index = index + 1
          table.insert(tmp, {
            index = index,
            product_id = v.product_id,
            reward = v
          })
        end
      end
      for i = index + 1, max do
        local reward
        table.insert(tmp, {
          index = i,
          product_id = 0,
          reward = reward
        })
      end
    else
      for i = 1, max do
        local reward
        if i <= #rewardList then
          reward = rewardList[i]
        end
        table.insert(tmp, {
          index = i,
          product_id = reward and reward.product_id or 0,
          reward = reward
        })
      end
    end
    self.bind.scrollList_collectionItem:clear()
    self.bind.scrollList_collectionItem:insert_array(tmp)
  end
  local hasReward = not table.isEmpty(rewardList)
  self.bind.go_collect = hasReward
end

function this:initPreviewList()
  local serverData = L_CollectionStore:getCollection(self._collectionGuid)
  local tpl_building = homeBuildingCollectionTpl:getTplById(serverData.build_id)
  local level = homeBuildingCollectionTpl:getLevel(tpl_building)
  local products = homeBuildingCollectionTpl:getMaxLevelProducts(self._collectionGuid)
  local tmp = {}
  for i, productId in ipairs(products) do
    local tpl_pro = productsTpl:getTplById(productId)
    local dropUnlockLevel = productsTpl:getDropUnlockLevel(tpl_pro)
    local dropType = productsTpl:getDropType(tpl_pro)
    local reward = L_DataUtil.parseRewardConfigItem(productsTpl:getDropShow(tpl_pro)[1])
    local configData = L_ItemTplManager:getItemConfig(reward.itemType, reward.itemId)
    local tpl_dropType = productsCollectionTypeTpl:getTplById(dropType)
    local isLock = level < dropUnlockLevel
    local isShowRare = productsCollectionTypeTpl:getIsShowInOutPut(tpl_dropType)
    local name = configData.name
    table.insert(tmp, {
      itemType = reward.itemType,
      itemId = reward.itemId,
      img_icon = configData.icon,
      quality = configData.quality,
      name = name,
      txt_desc = isLock and L_WordsTpl:getValue(infoText.unlockingLevel, {
        [0] = dropUnlockLevel
      }) or string.format(L_WordsTpl:getValue("notice_homeProduction_23"), productsCollectionTypeTpl:getTypeName(tpl_dropType)),
      go_lock = isLock,
      unLockLevel = dropUnlockLevel,
      sortId = productId,
      lockStatus = isLock and 1 or 0,
      go_rare = isShowRare,
      img_rare = productsCollectionTypeTpl:getIcon(tpl_dropType),
      alpha_content = isLock and 0.5 or 1,
      go_mask = isLock and isShowRare
    })
  end
  table.sort(tmp, function(a, b)
    if a.lockStatus == b.lockStatus then
      if a.unLockLevel == b.unLockLevel then
        return a.sortId < b.sortId
      else
        return a.unLockLevel < b.unLockLevel
      end
    else
      return a.lockStatus < b.lockStatus
    end
  end)
  self.bind.scrollList_preview:clear()
  self.bind.scrollList_preview:insert_array(tmp)
end

return this
