local this = class("pageSatiety", G_UIPageBase)
local _homeBuildingTpl = L_GameTpl:getHomeBuildingTpl()
local foodTpl = L_GameTpl:getFoodTpl()
local _screenPosToUI = Unity.RectTransformUtility.ScreenPointToLocalPointInRectangle

function this.bind()
  return {
    bagCloseMaskActive = false,
    bagActive = false,
    selectCloseMaskActive = false,
    selectNodeActive = false,
    upgradeBtnActive = true,
    maxNodeAcitve = false,
    arrowAcitve = false,
    buildingNameText = "",
    buildingLevelText = "",
    active_canUpgrade = false,
    bagList = {
      moduleName = "modulePages/cellIconItemSatiety"
    },
    leftItemList = {
      moduleName = "pages/home/homeSatiety/cellSatietyItem"
    },
    rightItemList = {
      moduleName = "pages/home/homeSatiety/cellSatietyItem"
    },
    moduleSelect = {
      moduleName = "modulePages/moduleSelectNum"
    },
    currentSatiety = "",
    totalSatiety = "",
    satietyIocn = "",
    numSelectPos = C_Vector2.zero,
    arrowPos = C_Vector2.zero,
    addBtnActive = true
  }
end

function this.methods()
  return {
    onClick_closeBtn = function(self)
      L_UI:close(self.pageName)
    end,
    onClick_bagCloseMask = function(self)
      self:setBagActive(false)
    end,
    onClick_selectNodeCloseMask = function(self)
      self:setSelectNodeActive(false)
    end,
    onClick_rightBtn = function(self)
      self:dealPageIndexChange(true)
    end,
    onClick_leftBtn = function(self)
      self:dealPageIndexChange()
    end,
    onClick_autoBtn = function(self)
      self:dealAuto()
    end,
    onClick_checkBtn = function(self)
      self:dealCheckBtn()
    end,
    onClick_addBtn = function(self)
      self:setBagActive(true)
    end,
    onClick_upgrade = function(self)
      if self.isBuildingMax then
        L_FlyMsgManager:showNormalMsg(L_WordsTpl:getValue("ui_home_manage_13"))
        return
      end
      L_UI:open("pageBuildingUpgrade", {
        keepCamera = true,
        guid = self.buildingGuid
      })
    end,
    leftItemList = {
      onClick_item = function(self, item)
        self:dealClickFood(item)
      end
    },
    rightItemList = {
      onClick_item = function(self, item)
        self:dealClickFood(item)
      end
    },
    bagList = {
      onClick_item = function(self, item)
        local currentSatiety, maxSatiety = L_SatietyManager:getBuildingSatiety(self.buildingGuid)
        if maxSatiety <= currentSatiety then
          L_FlyMsgManager:showNormalMsg(L_WordsTpl:getValue("ui_home_building_foodenough"))
          return
        end
        local maxCanUse = L_SatietyManager:getMaxFoodCanUse(self.buildingGuid, item.bind.itemId)
        if maxCanUse == 0 then
          L_FlyMsgManager:showNormalMsg(L_WordsTpl:getValue("ui_home_building_foodenough"))
          return
        end
        self.selectItemId = item.bind.itemId
        self.selectNum = 1
        self.operationType = L_Const.satietyOperationType.add
        if item.bind.itemNum == 1 then
          self:dealCheckBtn()
        else
          self:setNumModulePosition(item:getCellRect())
          self:initModuleNum()
          self:setSelectNodeActive(true)
        end
      end
    }
  }
end

function this:preOpen(options)
  L_HomeStore:listenCallFunc(L_HomeStore.event.syncWorldMapHomeItem, self.refreshBuild, self)
  L_BagStore:listenCallFunc(L_BagStore.event.refreshBag, self.refreshBagList, self)
  L_HomeStore:listenCallFunc(L_HomeStore.event.refreshPetEatFinishList, self.refreshPetEatFinishList, self)
  self:setBagActive(false)
  self.bind.bagList:clear()
  self.buildingGuid = options.buildingGuid
  L_HomeUtil.focusBuild(self.buildingGuid, L_HomeConst.FocusType.CENTER)
  self.foodPageIndex = 1
  self:initPage()
end

function this:close()
  L_HomeUtil.focusBuild(0, L_HomeConst.FocusType.CENTER)
  L_HomeStore:unListenCallFunc(L_HomeStore.event.syncWorldMapHomeItem, self.refreshBuild)
  L_BagStore:unListenCallFunc(L_BagStore.event.refreshBag, self.refreshBagList, self)
  L_HomeStore:unListenCallFunc(L_HomeStore.event.refreshPetEatFinishList, self.refreshPetEatFinishList, self)
end

function this:dealAuto()
  local currentSatiety, maxSatiety = L_SatietyManager:getBuildingSatiety(self.buildingGuid)
  local data = L_SatietyManager:getFoodList()
  local items = {}
  for _, food in ipairs(data) do
    local fTpl = foodTpl:getTplById(food.itemId)
    if fTpl then
      local satietyScore = foodTpl:getSatietyScore(fTpl)
      local needNum = math.floor((maxSatiety - currentSatiety) / satietyScore)
      local addNum = math.min(needNum, food.itemNum)
      if 0 < addNum then
        table.insert(items, {
          itemtype = L_Const.resType.commonItem,
          itemid = food.itemId,
          itemnum = addNum
        })
      end
      currentSatiety = currentSatiety + satietyScore * addNum
    end
  end
  if 0 < #items then
    self.operationType = L_Const.satietyOperationType.add
    self:reqAddFood(items, true)
  end
end

function this:reqAddFood(items, isAuto)
  L_SatietyStore:req_CSProtoAddPetFood(self.operationType, items, self.buildingGuid, function()
    if isAuto then
      L_FlyMsgManager:showNormalMsg(L_WordsTpl:getValue("ui_home_building_foodputfinish"))
    end
    self:setSelectNodeActive(false)
    self.changeItem = items[1].itemid
    self:initPage(true)
    self.operationType = nil
  end)
end

function this:dealClickFood(item)
  self.selectItemId = item.bind.itemid
  self.selectNum = 1
  self.operationType = L_Const.satietyOperationType.minus
  self:setNumModulePosition(item:getCellRect())
  self:initModuleNum()
  self:setSelectNodeActive(true)
end

function this:dealPageIndexChange(isAdd)
  if not self.foods then
    return
  end
  if isAdd then
    if self.foodPageIndex >= #self.foods then
      return
    end
    self.foodPageIndex = self.foodPageIndex + 1
  else
    if self.foodPageIndex <= 1 then
      return
    end
    self.foodPageIndex = self.foodPageIndex - 1
  end
  self:setFoodList()
end

function this:dealCheckBtn()
  if self.operationType == nil then
    return
  end
  local item = {
    itemtype = L_Const.resType.commonItem,
    itemid = self.selectItemId,
    itemnum = self.selectNum
  }
  self:reqAddFood({item})
end

function this:setBagActive(isActive)
  if isActive then
    local data = L_SatietyManager:getFoodList()
    if #data == 0 then
      isActive = false
      L_FlyMsgManager:showNormalMsgByKey("ui_pageSatiety")
    end
  end
  self.bind.addBtnActive = not isActive
  self.bind.bagActive = isActive
  self.bind.bagCloseMaskActive = isActive
end

function this:setSelectNodeActive(isActive)
  self.bind.selectNodeActive = isActive
  self.bind.selectCloseMaskActive = isActive
  self.bind.arrowAcitve = isActive
end

function this:setNumModulePosition(cellRect)
  if not cellRect then
    return
  end
  local worldPosition = cellRect.transform.position
  local screenPos = C_CameraManager.uiCamera:WorldToScreenPoint(worldPosition)
  local _, arrowUiPos = _screenPosToUI(self.bindComponents.board, C_Vector2(screenPos.x, screenPos.y), C_CameraManager.uiCamera)
  arrowUiPos.y = arrowUiPos.y + 30
  local diff = screenPos.x + self.bindComponents.numSelectRect.sizeDelta.x * 0.45 - C_Screen.width
  if 0 < diff then
    screenPos.x = C_Screen.width - self.bindComponents.numSelectRect.sizeDelta.x * 0.45
  end
  local _, uiPos = _screenPosToUI(self.bindComponents.board, C_Vector2(screenPos.x, screenPos.y), C_CameraManager.uiCamera)
  uiPos.y = uiPos.y + 10 + cellRect.sizeDelta.y / 2
  arrowUiPos.y = arrowUiPos.y + 10 + cellRect.sizeDelta.y / 2
  self.bind.numSelectPos = uiPos
  self.bind.arrowPos = arrowUiPos
end

function this:initModuleNum()
  local max = 0
  if self.operationType == L_Const.satietyOperationType.add and self.selectItemId ~= nil then
    max = L_SatietyManager:getMaxFoodCanUse(self.buildingGuid, self.selectItemId)
  end
  if self.operationType == L_Const.satietyOperationType.minus and self.selectItemId ~= nil then
    max = L_SatietyManager:getMaxFoodCanDelete(self.buildingGuid, self.selectItemId)
  end
  local func = function(num)
    self.selectNum = num
  end
  local min = 1
  if max < min then
    min = max
  end
  self.modules.moduleSelect:initModule(func, max, min, min)
end

function this:refreshBuildingInfo()
  if not self.buildingGuid then
    return
  end
  local serverData = L_HomeStore:getHomeBuildingByGuid(self.buildingGuid)
  local tpl = _homeBuildingTpl:getTplById(serverData.build_id)
  local groupId = _homeBuildingTpl:getGroupId(tpl)
  local homeBuildingGroupTpl = L_GameTpl:getHomeBuildingGroupTpl()
  local tpl_buildingGroup = homeBuildingGroupTpl:getTplById(groupId)
  self.bind.buildingNameText = homeBuildingGroupTpl:getName(tpl_buildingGroup)
  local isMax = math.isEmpty(_homeBuildingTpl:getNextLevel(tpl))
  local levelStr = string.concat("Lv.", _homeBuildingTpl:getLevel(tpl))
  self.bind.upgradeBtnActive = not isMax
  self.bind.maxNodeAcitve = isMax
  self.bind.buildingLevelText = levelStr
  self.bind.active_canUpgrade = L_HomeUtil.canBuildUpgrade(self.buildingGuid)
  self.isBuildingMax = isMax
end

function this:refreshBuild()
  self.selectNum = 1
  self:initPage()
  self:initModuleNum()
end

function this:initPage(changeIndex)
  self:refreshBuildingInfo()
  self:refreshBuildSatiety()
  self:refreshBagList()
  self:refreshFoodListData(changeIndex)
end

function this:refreshBuildSatiety()
  local currentSatiety, maxSatiety = L_SatietyManager:getBuildingSatiety(self.buildingGuid)
  local icon, color
  if currentSatiety / maxSatiety <= 0.2 then
    icon = string.format("Atlas/Satiety/tex_homecanteen_dec_guo0%d.png", 3)
    color = L_Const.colorHtml.red001
  elseif currentSatiety / maxSatiety <= 0.5 then
    icon = string.format("Atlas/Satiety/tex_homecanteen_dec_guo0%d.png", 2)
    color = L_Const.colorHtml.yellow017
  else
    icon = string.format("Atlas/Satiety/tex_homecanteen_dec_guo0%d.png", 1)
    color = L_Const.colorHtml.green002
  end
  self.bind.currentSatiety = L_GameUtil.fillColor(tostring(currentSatiety), color)
  self.bind.totalSatiety = string.format("/%d", maxSatiety)
  self.bind.satietyIocn = icon
end

function this:refreshBagList()
  local data = L_SatietyManager:getFoodList()
  self.bindComponents.bagList.disableScroll = #data <= 20
  while #data < 20 do
    table.insert(data, {empty = true})
  end
  local lineNum = math.ceil(#data / 5)
  local needAddEmptyNum = lineNum * 5 - #data
  for _ = 1, needAddEmptyNum do
    table.insert(data, {empty = true})
  end
  self.bind.bagList:clear()
  self.bind.bagList:insert_array(data)
  if #data == 0 then
    self.bind.bagActive = false
    self.bind.bagCloseMaskActive = false
  end
end

function this:refreshFoodListData(changeIndex)
  local serverData = L_HomeStore:getHomeBuildingByGuid(self.buildingGuid)
  self.bind.leftItemList:clear()
  self.bind.rightItemList:clear()
  if not (serverData and serverData.pet_canteen) or not serverData.pet_canteen.foods then
    return
  end
  local foods = {}
  for _, food in pairs(serverData.pet_canteen.foods) do
    table.insert(foods, {
      itemid = food.itemid,
      itemnum = food.itemnum,
      itemtype = food.itemtype,
      guid = food.guid
    })
  end
  table.sort(foods, function(a, b)
    local aTpl, bTpl = foodTpl:getTplById(a.itemid), foodTpl:getTplById(b.itemid)
    if foodTpl:getSatietyScore(aTpl) == foodTpl:getSatietyScore(bTpl) then
      return a.itemid < b.itemid
    end
    return foodTpl:getSatietyScore(aTpl) < foodTpl:getSatietyScore(bTpl)
  end)
  self.foods = self:splitFoods(foods)
  if changeIndex then
    self.foodPageIndex = self:findSelectedFoodPage(self.foods, self.changeItem)
  end
  self:setFoodList()
end

function this:findSelectedFoodPage(foods, selectItemId)
  for i, group in ipairs(foods) do
    for _, food in pairs(group) do
      if food.itemid == selectItemId then
        return i
      end
    end
  end
  return 1
end

function this:setFoodList()
  if not self.foods then
    return
  end
  if not self.foods[self.foodPageIndex] then
    return
  end
  self.bind.leftItemList:clear()
  self.bind.rightItemList:clear()
  local leftData = self.foods[self.foodPageIndex][1]
  local rightData = self.foods[self.foodPageIndex][2]
  if leftData then
    self.bind.leftItemList:insert_array(leftData)
  end
  if rightData then
    self.bind.rightItemList:insert_array(rightData)
  end
end

function this:splitFoods(foods)
  local subListSize = 4
  local topListSubLists = 2
  local splitList = function(list, subListSize, topListSubLists)
    local result = {}
    local sublistGroupIndex = 1
    local currentSublistGroup = {}
    local currentSubList = {}
    local subListCount = 0
    local subListElementCount = 0
    for _, value in ipairs(list) do
      currentSubList[#currentSubList + 1] = value
      subListElementCount = subListElementCount + 1
      if subListElementCount == subListSize then
        currentSublistGroup[#currentSublistGroup + 1] = currentSubList
        currentSubList = {}
        subListElementCount = 0
        subListCount = subListCount + 1
        if subListCount == topListSubLists then
          result[sublistGroupIndex] = currentSublistGroup
          currentSublistGroup = {}
          subListCount = 0
          sublistGroupIndex = sublistGroupIndex + 1
        end
      end
    end
    if 0 < #currentSubList then
      currentSublistGroup[#currentSublistGroup + 1] = currentSubList
    end
    if 0 < #currentSublistGroup then
      result[sublistGroupIndex] = currentSublistGroup
    end
    return result
  end
  local chunks = splitList(foods, subListSize, topListSubLists)
  return chunks
end

function this:refreshPetEatFinishList(eventData)
  L_FlyMsgManager:showPetEatFinishMsg(eventData.petGuid, eventData.foodId)
end

return this
