local this = class("pageHomeCollectionManage", G_UIPageBase)
local columnNum = L_DeviceTpl:getIsPc() and 3 or 3
local minLineNum = L_DeviceTpl:getIsPc() and 3 or 3
local homeCollectionWorldTpl = L_GameTpl:getHomeCollectionWorldTpl()
local homeLaborCapacityTpl = L_GameTpl:getHomeLaborCapacityTpl()
local productTpl = L_GameTpl:getProductsTpl()
local domainTpl = L_GameTpl:getDomainTpl()
local worldCityTpl = L_GameTpl:getWorldCityTpl()
local homeBuildingCollectionTpl = L_GameTpl:getHomeBuildingCollectionTpl()
local homeBuildingTpl = L_GameTpl:getHomeBuildingTpl()
local homeBuildingGroupTpl = L_GameTpl:getHomeBuildingGroupTpl()
local productsTpl = L_GameTpl:getProductsCollectionTpl()
local productsCollectionTypeTpl = L_GameTpl:getProductsCollectionTypeTpl()
local _screenPosToUI = Unity.RectTransformUtility.ScreenPointToLocalPointInRectangle
local HideNodeList_PageHomeCollectionManage = {
  L_EntityManager.node.player
}
local _homeCollectionWorkLimitTpl = L_GameTpl:getHomeCollectionWorkLimitTpl()
local C_HomeManager = AzurWorld.HomeMgr

function this.bind()
  return {
    module_tabList = {
      moduleName = "modulePages/tabList/moduleCommonTabListWithWords"
    },
    listToggle = true,
    go_free = false,
    txt_time_free = nil,
    go_working = false,
    go_running = false,
    txt_time_running = nil,
    go_finish = false,
    go_collect = false,
    go_pause = true,
    txt_pause = nil,
    go_full = false,
    scrollList_collectionItem = {
      moduleName = "pages/collection/cellCollectionOutput"
    },
    collectionList = {
      moduleName = "pages/home/homeCollectionManage/cellHomeCollection"
    },
    module_top = {
      moduleName = "pages/home/moduleHomeBuildingTop"
    },
    module_managerTop = {
      moduleName = "pages/home/moduleHomeBuildingTop"
    },
    infoToggle = false,
    emptyTips = "",
    module_petInfo = {
      moduleName = "pages/product/modulePetInfo"
    },
    module_petInfoNew = {
      moduleName = "pages/product/modulePetInfoNew"
    },
    scrollList_preview = {
      moduleName = "pages/collection/cellCollectionPreview"
    },
    infoToggle_show = false,
    btn_blank = false,
    txt_workLimit = ""
  }
end

function this.methods()
  return {
    onClick_start = function(self)
      self:checkCollect()
    end,
    onClick_stop = function(self)
      local data_tip = {
        txtTitle = L_WordsTpl:getValue("notice_pageCollection_01"),
        txtContent = L_WordsTpl:getValue("notice_pageCollection_02"),
        confirmCallback = function()
          L_CollectionManager:reqCancelCollect(self._collectionGuid, function()
            self:initRightShow(true)
          end)
        end
      }
      L_GameUtil.showCommonTip(data_tip)
    end,
    onClick_collect = function(self)
      L_CollectionManager:reqCollectReward(self._collectionGuid, self._buildingGuid, function()
        self:initRightShow(true)
      end)
    end,
    onClick_collectAll = function(self)
      local canCollectAll, guidList = L_CollectionManager:judgeCanCollectReward()
      if canCollectAll then
        L_CollectionManager:reqCollectAllReward(guidList, self._buildingGuid, function()
          self:initRightShow(true)
        end)
      else
        L_FlyMsgManager:showNormalMsgByKey("notice_moduleHomeCenterCollection_01")
      end
    end,
    onClick_close = function(self)
      L_UI:close(self.pageName)
    end,
    onClick_closeBlank = function(self)
      self.bind.btn_blank = false
      self.bind.infoToggle_show = false
      self:refreshView(true)
    end,
    collectionList = {
      onClick_choose = function(self, bind, position)
        self._collectionGuid = bind.collectionGuid
        self:refreshView()
        self.bind.btn_blank = true
        self:checkBorderPos(position)
        self:req_initCollection(bind)
      end
    }
  }
end

function this:preOpen(options)
  self._buildingGuid = options and options.buildingGuid or 0
  local size = math.min(Unity.Screen.width / 1920, Unity.Screen.height / 1080)
  self.screenWidth = Unity.Screen.width / size
  self.screenPos_rect = C_CameraManager.uiCamera:WorldToScreenPoint(self.bindComponents.rect_board.position)
  self:initManagerInfo()
  L_CollectionStore:listenCallFunc(L_CollectionStore.event.updateCollection, self.onEvent_updateCollection, self)
  L_PetStore:listenCallFunc(L_PetStore.event.refreshBuildingPet, self.onEvent_refreshPet, self)
  L_PetStore:listenCallFunc(L_PetStore.event.refreshPet, self.refreshSatiety, self)
  self:registerConditionsOfUnlockMaxWorkingNumOfCollectionBuildingAtSameTime()
  self:cameraFocusOnMainUITrans()
  self:refreshCollectionBuildingWorkLimitPart()
end

function this:show()
  self:cameraFocusOnMainUITrans()
end

function this:close(options)
  L_TimerManager:clearTimer(self)
  L_CollectionStore:unListenCallFunc(L_CollectionStore.event.updateCollection, self.onEvent_updateCollection)
  L_PetStore:unListenCallFunc(L_PetStore.event.refreshBuildingPet, self.onEvent_refreshPet)
  L_PetStore:unListenCallFunc(L_PetStore.event.refreshPet, self.refreshSatiety)
  self:unregisterConditionsOfUnlockMaxWorkingNumOfCollectionBuildingAtSameTime()
  self:cameraExitFocusOnMainUITrans()
end

function this:initManagerInfo()
  if not math.isEmpty(self._buildingGuid) then
    local serverData = L_HomeStore:getHomeBuildingByGuid(self._buildingGuid)
    local buildingId = serverData.build_id
    local tpl = homeBuildingTpl:getTplById(buildingId)
    local groupId = homeBuildingTpl:getGroupId(tpl)
    local tpl_buildingGroup = homeBuildingGroupTpl:getTplById(groupId)
    local name = homeBuildingGroupTpl:getName(tpl_buildingGroup)
    self.petGuid = serverData and serverData.station_pet_guid or 0
  end
  self:initCollectionData()
  if math.isEmpty(self.petGuid) then
    self:setToggleActive(false)
    self.bind.emptyTips = L_WordsTpl:getValue("notice_pageHomeCollectionManage_03")
  else
    self:judgeSatiety(self.petGuid)
  end
end

function this:refreshSatiety(entity)
  if entity.guid ~= self.petGuid or math.isEmpty(self.petGuid) then
    return
  end
  self:judgeSatiety(entity.guid)
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:judgeSatiety(petGuid)
  if not math.isEmpty(petGuid) then
    local pet = L_PetStore:getPetItem(petGuid)
    if not math.isEmpty(pet.canteen_id) then
      self:setToggleActive(false)
      self.bind.emptyTips = L_WordsTpl:getValue("notice_pageHomeCollectionManage_02")
      return
    end
    local satiety = pet.satiety
    if satiety <= 0 then
      self:setToggleActive(false)
      self.bind.emptyTips = L_WordsTpl:getValue("notice_pageHomeCollectionManage_01")
    elseif self.bind.listToggle == false then
      self:setToggleActive(true)
    end
  end
end

function this:setToggleActive(bool)
  self.bind.listToggle = bool
end

function this:setRightInfoToggleActive(bool)
  self.bind.infoToggle = bool
end

function this:initMenu()
  self.allData = homeCollectionWorldTpl:getAllTplByType()
  local rawData = {}
  for i, v in pairs(self.allData) do
    table.insert(rawData, {type = i})
  end
  table.sort(rawData, function(a, b)
    return a.type < b.type
  end)
  local tabList = {}
  local selectIndex = 1
  table.insert(tabList, 201)
  for i, v in ipairs(rawData) do
    table.insert(tabList, tonumber("400" .. v.type))
  end
  self._selectType = self._selectType or rawData[1].type
  self.modules.module_tabList:setData(tabList, function(tab)
    local id = tab % 1000
    if id == self._selectType then
      return
    end
    self._selectType = id
    self:updateMenuType()
  end, selectIndex, nil, "#FFAA05")
end

function this:initAreaName(type)
  self.bind.tabName = ""
  local tpl = domainTpl:getTplById(type)
  if tpl then
    local sceneId = domainTpl:getSceneId(tpl)
    local cityTpl = worldCityTpl:getTplById(sceneId)
    if cityTpl then
      self.bind.tabName = worldCityTpl:getCity(cityTpl)
    end
  end
end

function this:initCollectionData()
  self:initData()
  self:initManagerCoolieModule()
end

function this:initData()
  self:initMenu()
  self:updateMenuType()
end

function this:updateMenuType()
  if math.isEmpty(self.petGuid) then
    self:setToggleActive(false)
    return
  end
  local data = self.allData[self._selectType] or homeCollectionWorldTpl:getAllTpl()
  self.bind.infoToggle_show = false
  self.bind.btn_blank = false
  local tmp = {}
  for i, v in ipairs(data) do
    table.insert(tmp, {
      data = v,
      index = i,
      collectionGuid = homeCollectionWorldTpl:getId(v),
      isChoose = false,
      tagName = homeCollectionWorldTpl:getName(v)
    })
  end
  if 0 < #tmp then
    self._collectionGuid = self._collectionGuid or homeCollectionWorldTpl:getId(tmp[1])
    self:setToggleActive(true)
  else
    self:setToggleActive(false)
  end
  self.bind.collectionList:clear()
  self.bind.collectionList:insert_array(tmp)
end

function this:refreshView(isSetFalse)
  if isSetFalse then
    for i, v in pairs(self.bind.collectionList) do
      self.bind.collectionList:change(i, {isChoose = false})
    end
  else
    for i, v in pairs(self.bind.collectionList) do
      if self._collectionGuid == v.collectionGuid then
        self.bind.collectionList:change(i, {isChoose = true})
      else
        self.bind.collectionList:change(i, {isChoose = false})
      end
    end
  end
end

function this:req_initCollection(info)
  if table.isEmpty(info.serverData) then
    self.bind.infoToggle_show = true
    self.bind.emptyTips = L_WordsTpl:getValue("notice_moduleHomeCenterCollection_02", {
      [0] = info.tagName
    })
    self:initRightShow(true)
    return
  end
  self.bind.infoToggle_show = true
  self:initRightShow(true)
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:setRightInfoToggleActive(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:initTopModule()
    self:initPreviewList()
    self:initCoolieModule()
  else
    self._collectionGuid = 0
    self:setRightInfoToggleActive(false)
  end
end

function this:initTopModule()
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:initManagerCoolieModule()
  if not math.isEmpty(self._buildingGuid) then
    self.modules.module_petInfoNew:setCollectionManageModule(self._buildingGuid)
  end
end

function this:initManageTopModule()
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: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("notice_pageCollection_05")
    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("notice_pageCollection_03") or L_WordsTpl:getValue("notice_pageCollection_04")
      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("notice_pageCollection_03") or L_WordsTpl:getValue("notice_pageCollection_04")
  else
    self:openTickTimer()
  end
end

function this:onEvent_refreshPet()
  local petGuid = 0
  if not math.isEmpty(self._buildingGuid) then
    local serverData = L_HomeStore:getHomeBuildingByGuid(self._buildingGuid)
    petGuid = serverData and serverData.station_pet_guid or 0
  end
  self:initRightShow()
  if petGuid ~= self.petGuid then
    self:initManagerInfo()
  end
end

function this:onEvent_updateCollection(updateList)
  if self.bind.infoToggle_show == false then
    return
  end
  self:refreshPauseInfo()
  self:initOutputList()
  self:refreshCollectionBuildingWorkLimitPart()
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("ui_moduleCanteenFree_03", {
        [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

function this:checkBorderPos(position)
  local cellPos = position
  local rect = self.bindComponents.infoTrans
  local screenPos_cell = C_CameraManager.uiCamera:WorldToScreenPoint(cellPos)
  local v2 = L_Vector3.new(screenPos_cell.x, self.screenPos_rect.y)
  local parent = self.bindComponents.rect_board
  local _, uiPos = _screenPosToUI(parent, v2, C_CameraManager.uiCamera)
  local edgePos = uiPos.x + 500
  if edgePos >= self.screenWidth / 2 then
    uiPos.x = uiPos.x - 475
  else
    uiPos.x = uiPos.x + 475
  end
  L_Vector3.setAnchored(rect, uiPos)
end

function this:cameraFocusOnMainUITrans()
  L_HomeUtil.focusBuildWithCustomHideList(self._buildingGuid, L_HomeConst.FocusType.MAINUI, HideNodeList_PageHomeCollectionManage, "pageHomeCollectionManage")
end

function this:cameraExitFocusOnMainUITrans()
  L_HomeUtil.exitFocusBuildAndRevertCustomHideNodeList(HideNodeList_PageHomeCollectionManage, "pageHomeCollectionManage")
end

function this:registerConditionsOfUnlockMaxWorkingNumOfCollectionBuildingAtSameTime()
  local allConditionGroup = _homeCollectionWorkLimitTpl:getAllConditionGroup()
  self.conditionNodeList = {}
  for _, conditionGroup in pairs(allConditionGroup) do
    local conditionNode = L_ConditionManager:registGroup("pageCollection", conditionGroup, self.onConditionNodeStateChanged, self)
    table.insert(self.conditionNodeList, conditionNode)
  end
end

function this:unregisterConditionsOfUnlockMaxWorkingNumOfCollectionBuildingAtSameTime()
  for _, conditionNode in pairs(self.conditionNodeList) do
    L_ConditionManager:unRegist(conditionNode, "pageCollection")
  end
end

function this:onConditionNodeStateChanged()
  self:refreshCollectionBuildingWorkLimitPart()
end

function this:refreshCollectionBuildingWorkLimitPart()
  local curWorkingNum = C_HomeManager:GetCurWorkingNumOfCollectionBuilding()
  local maxWorkingNum = _homeCollectionWorkLimitTpl:getCurMaxWorkingNum()
  self.bind.txt_workLimit = L_Lang:get(L_WordsTpl:getValue("notice_home_collectionbuilding_limit"), {
    [0] = curWorkingNum,
    [1] = maxWorkingNum
  })
end

return this
