local this = class("moduleSnackBag", G_UIModuleBase)
local _commonItemTpl = L_GameTpl:getCommonItemTpl()
local _foodTpl = L_GameTpl:getFoodTpl()
local SlotCount = 4
local NumSelectModulePosY = L_DeviceTpl:getIsPc() and 61 or 100
local slotPositions = {
  C_Vector2(-227.5, -13),
  C_Vector2(-76.9, -5),
  C_Vector2(72.6, 3),
  C_Vector2(215.5, 6)
}

function this.bind()
  return {
    list_PetSlot = {
      moduleName = "pages/bag/cellSnackBagSlot"
    },
    list_HeroSlot = {
      moduleName = "pages/bag/cellSnackBagSlot"
    },
    go_selectNumModule = false,
    module_selectNum = L_Const.ModuleInfo.SelectNum,
    localPosition_selectNum = nil,
    go_mask = false,
    go_heroListDisable = false,
    go_petListDisable = false,
    alpha_heroList = 1,
    alpha_petList = 1,
    fill_heroSatiety = 0,
    color_heroFill = C_Color(1, 1, 1),
    fill_petSatiety = 0,
    color_petFill = C_Color(1, 1, 1)
  }
end

function this.methods()
  return {
    onClick_confirmDragIn = function(self)
      local reqData = {}
      reqData.source_bag = self._bagType
      reqData.operate_type = 1
      reqData.source_slot = self._dragInSlotId - 1
      reqData.item_id = self._dragInId
      reqData.item_num = self._dragInNum
      L_BagManager:reqSetSnackBag(reqData)
    end,
    onClick_mask = function(self)
      self:resetEdit()
      self:emit("onClick_mask")
    end,
    onClick_showConfigPage = function(self)
      L_UI:open("pageSnackBagConfigTip")
    end
  }
end

function this:open()
  self:initSlotList(self.bind.list_HeroSlot, L_Const.roleType.hero)
  self:initSlotList(self.bind.list_PetSlot, L_Const.roleType.pet)
  self:initSatietyProcess("hero", L_Const.roleType.hero)
  self:initSatietyProcess("pet", L_Const.roleType.pet)
  L_SnackBagStore:listenCallFunc(L_SnackBagStore.event.refreshSnackBag, self.onEvent_refreshMountSnackBag, self)
  self._isSelecting = false
end

function this:close()
  L_SnackBagStore:unListenCallFunc(L_SnackBagStore.event.refreshSnackBag, self.onEvent_refreshMountSnackBag, self)
  L_TimerManager:clearTimer(self)
end

function this:initSlotList(list, roleType)
  local tmp = {}
  local bagType = L_Const.snackBagType.mount
  if roleType == L_Const.roleType.hero then
    bagType = L_Const.snackBagType.hero
  end
  for i = 1, SlotCount do
    local slotPos
    if roleType == L_Const.roleType.hero then
      slotPos = C_Vector2(slotPositions[i].x, slotPositions[i].y)
    else
      slotPos = C_Vector2(slotPositions[SlotCount + 1 - i].x * -1, slotPositions[SlotCount + 1 - i].y)
    end
    table.insert(tmp, {
      slotId = i,
      roleType = roleType,
      slotPosition = slotPos,
      bagType = bagType
    })
  end
  list:clear()
  list:insert_array(tmp)
end

function this:initSelectNumModule()
  local max = self._dragInNum
  local func = function(num)
    self._dragInNum = num
    self._dragInSlotCell:refreshCell(self._dragInId, self._dragInNum)
  end
  self.modules.module_selectNum:initModule(func, max, 1, self._dragInNum)
end

function this:initSatietyProcess(typeName, roleType)
  local color = ""
  local fillPercent = 0
  if roleType == L_Const.roleType.hero then
    fillPercent = L_StarHealingStore:getCharge().cur_value / L_StarHealingStore:getMaxCharge()
    color = L_Const.satietyColor[L_StarHealingStore:getSatietyStatus()]
  elseif roleType == L_Const.roleType.pet then
    local petId = L_MountStore:getEquipMountId()
    if not petId then
      return
    end
    fillPercent = L_SatietyStore:getPetSatietyPercent(petId)
    color = L_Const.satietyColor[L_SatietyStore:getPetSatietyStatus(petId)]
  else
    return
  end
  self.bind[string.format("fill_%sSatiety", typeName)] = fillPercent
  local _, c_color = C_ColorUtility.TryParseHtmlString(color)
  self.bind[string.format("color_%sFill", typeName)] = c_color
end

function this:checkRaycastGo(go)
  for i, v in pairs(self.modules.list_PetSlot) do
    local cell = v
    if go == cell:getRaycastGo() then
      return cell.bind.slotId, cell.bind.roleType
    end
  end
  for i, v in pairs(self.modules.list_HeroSlot) do
    local cell = v
    if go == cell:getRaycastGo() then
      return cell.bind.slotId, cell.bind.roleType
    end
  end
end

function this:dragInFromBag(itemId, itemNum, toSlotId)
  self._dragInId = itemId
  self._dragInNum = itemNum
  self._dragInSlotId = toSlotId
  local targetList = self.modules.list_PetSlot
  if self._bagType == L_Const.snackBagType.hero then
    targetList = self.modules.list_HeroSlot
  end
  for i, v in pairs(targetList) do
    if v.bind.slotId == self._dragInSlotId then
      self._dragInSlotCell = v
      self._dragInSlotCell:refreshCell(self._dragInId, self._dragInNum)
      self._dragInSlotCell:setSelect(true)
      self._isSelecting = true
      self.bind.go_selectNumModule = self._isSelecting
      local targetPosX = self.bindComponents.rect_board.transform:InverseTransformPoint(self._dragInSlotCell.uiBinding.gameObject.transform.position).x
      self.bind.localPosition_selectNum = L_Vector3.new(targetPosX, NumSelectModulePosY, 0)
      self:initSelectNumModule()
      break
    end
  end
  self.bind.go_mask = true
  local curSlot = L_SnackBagStore:getSnackBagSlot(self._bagType, self._dragInSlotId)
  if not math.isEmpty(curSlot.item_num) and curSlot.item_id ~= itemId then
    self:emit("recordBackToBagId", curSlot.item_id)
  end
  self:recordNeedShowStopDragFXId(toSlotId)
end

function this:setParentDragging(dragging)
  for i, v in pairs(self.modules.list_PetSlot) do
    local cell = v
    cell:setParentDragging(dragging)
  end
end

function this:dragInFromBagWithoutSelectNum(itemId, itemNum, toSlotId, fromBag)
  local reqData = {}
  reqData.source_bag = fromBag or self._bagType
  reqData.operate_type = 1
  reqData.source_slot = toSlotId - 1
  reqData.item_id = itemId
  reqData.item_num = itemNum
  L_BagManager:reqSetSnackBag(reqData)
  local curSlot = L_SnackBagStore:getSnackBagSlot(self._bagType, toSlotId)
  if not math.isEmpty(curSlot.item_num) and curSlot.item_id ~= itemId then
    self:emit("recordBackToBagId", curSlot.item_id)
  end
  self:recordNeedShowStopDragFXId(toSlotId)
end

function this:dragInFromSelf(fromSlotId, toSlotId, fromBag)
  local reqData = {}
  reqData.source_bag = fromBag or self._bagType
  reqData.target_bag = self._bagType
  reqData.operate_type = 2
  reqData.source_slot = fromSlotId - 1
  reqData.target_slot = toSlotId - 1
  L_BagManager:reqSetSnackBag(reqData)
  local toSlot = L_SnackBagStore:getSnackBagSlot(self._bagType, toSlotId)
  if not math.isEmpty(toSlot.item_num) then
    self._needShowStopDragFXId2 = fromSlotId
  end
  self:recordNeedShowStopDragFXId(toSlotId)
end

function this:dragOut(fromSlotId)
  local reqData = {}
  reqData.source_bag = self._bagType
  reqData.operate_type = 0
  reqData.source_slot = fromSlotId - 1
  L_BagManager:reqSetSnackBag(reqData)
  local curSlot = L_SnackBagStore:getSnackBagSlot(self._bagType, fromSlotId)
  if not math.isEmpty(curSlot.item_num) then
    self:emit("recordBackToBagId", curSlot.item_id)
  end
end

function this:checkIsSelectingNum()
  return self._isSelecting
end

function this:resetEdit()
  self:initSlotList(self.bind.list_PetSlot, L_Const.roleType.pet)
  self:initSlotList(self.bind.list_HeroSlot, L_Const.roleType.hero)
  self.bind.go_mask = false
  if self._isSelecting then
    self.bindComponents.ani_selectNum:Stop()
    self.bindComponents.ani_selectNum:Play("anim_bag_numSelect_hide")
    L_TimerManager:newOrResetTimer(self, "hideNumSelectModule", function()
      self.bind.go_selectNumModule = false
    end, 0.7)
  end
  self._isSelecting = false
end

function this:onEvent_refreshMountSnackBag()
  self:resetEdit()
  self:playCancelDragFX()
end

function this:playFX(name, slotId)
  for i, v in pairs(self.modules.list_PetSlot) do
    local slot = v
    if slot.bind.slotId == slotId then
      slot:playFX(name)
      return
    end
  end
end

function this:playCancelDragFX()
  if self._needShowStopDragFXId then
    self:playFX("anim_cellicon_stopDrag", self._needShowStopDragFXId)
    self._needShowStopDragFXId = nil
  end
  if self._needShowStopDragFXId2 then
    self:playFX("anim_cellicon_stopDrag", self._needShowStopDragFXId2)
    self._needShowStopDragFXId2 = nil
  end
end

function this:recordNeedShowStopDragFXId(id)
  self._needShowStopDragFXId = id
end

function this:setListDisable(dragShow, commonItemId)
  if math.isEmpty(commonItemId) then
    dragShow = false
  end
  if dragShow then
    local tpl_food = _foodTpl:getTplById(commonItemId)
    local satiety = _foodTpl:getSatietyScore(tpl_food)
    local isPetFood = not math.isEmpty(satiety)
    self.bind.go_petListDisable = not isPetFood
    self.bind.alpha_petList = isPetFood and 1 or 0.6
    local tpl_commonItem = _commonItemTpl:getTplById(commonItemId)
    local useType = _commonItemTpl:getUseType(tpl_commonItem)
    local isHeroFood = L_BagConst.bagUseType.starHealing == useType or useType == L_BagConst.bagUseType.starHealingAndHp
    self.bind.go_heroListDisable = not isHeroFood
    self.bind.alpha_heroList = isHeroFood and 1 or 0.6
  else
    self.bind.go_petListDisable = false
    self.bind.alpha_petList = 1
    self.bind.go_heroListDisable = false
    self.bind.alpha_heroList = 1
  end
end

function this:setBagType(bagType)
  self._bagType = bagType
end

return this
