local this = class("pageHomePlayerEdit", G_UIPageBase)
local _homeBuildingTpl = L_GameTpl:getHomeBuildingTpl()
local _homeBuildingGroupTpl = L_GameTpl:getHomeBuildingGroupTpl()
local _liftAudio = "Play_SFX_System_FB_Home_Building_Lift"
local _dropAudio = "Play_SFX_System_FB_Home_Building_Drop"
local editMode = {
  none = -1,
  create = 0,
  set = 1,
  move = 2,
  onlyMove = 3
}

function this.bind()
  return {
    goEditNode = false,
    toggleSure = true,
    toggleGarbage = true,
    active_btnContinue = false,
    active_continueOn = false,
    txt_continueNum = "",
    moduleMovementBlock = {
      moduleName = "modulePages/moduleMovementBlock"
    },
    module_belt = {
      moduleName = "pages/home/homeBag/moduleHomeBelt"
    },
    go_keepLook = false,
    go_tipSet = false,
    txt_tipSet = "",
    txt_btnCancel = L_WordsTpl:getValue("ui_home_arrange_8"),
    txt_btnGarbage = L_WordsTpl:getValue("ui_home_arrange_5"),
    txt_btnGarbageCant = L_WordsTpl:getValue("ui_home_arrange_5"),
    txt_btnRotate = L_WordsTpl:getValue("ui_home_arrange_3"),
    txt_btnSure = L_WordsTpl:getValue("ui_home_arrange_1"),
    txt_btnSureCant = L_WordsTpl:getValue("ui_home_arrange_1")
  }
end

function this.methods()
  return {
    onClick_exit = function(self)
      self:exit()
    end,
    onClick_cancel = function(self)
      self:resetSelection()
      self._curBuildPart:refreshBuildings()
    end,
    onClick_look = function(self)
      self:onClick_look()
    end,
    onClick_continue = function(self)
      self:onClick_continue()
    end,
    onClick_garbage = function(self)
      self:unLocateBuilding()
    end,
    onClick_rotate = function(self)
      self:onClick_rotate()
    end,
    onClick_sure = function(self)
      self:locateHomeBuilding()
    end
  }
end

function this:check(options, callback)
  self.mainControl = L_PlayerManager:getMainControlEntity()
  local index = L_HomeManager:getBlockIndexByPlayerPos(self.mainControl:getWorldPosition(), L_HomeConst.blockType.BUILD)
  self._curBlock = L_HomeManager:getBlockEntityByIndex(index)
  callback(index ~= nil)
end

function this:preOpen(options)
  L_CameraManager:getCameraTactics():SetCameraDis(8)
  L_CameraManager:getCameraTactics():SetFreezePinch(true)
  this.super.preOpen(self, options)
  options = options or {}
  self._curBlock:collectBarrierData()
  self._curEdit = self._curBlock.editPart
  self._curBuildPart = self._curBlock.buildPart
  if L_WorldManager:getCurProxy() then
    L_WorldManager:getCurProxy():setEditMode(L_Const.HomeEditorMode.playerEditor, self._curEdit)
  end
  self._checkTime = 0
  self._checkOut = false
  
  function self.controlMoveHandle(v2)
    self._curEdit:setMoving(v2.x ~= 0 or v2.y ~= 0)
  end
  
  C_InputManager.AddAxisListener(L_Const.axisType.emainMoveMent, self.controlMoveHandle)
  L_ShortCutManager:addShortKeyFlag(self, "Esc", L_Const.AnchorType.Middle, self.bindComponents.opShortKeys, L_Vector3.new(-402.9, 197.5))
  L_ShortCutManager:addShortKeyFlag(self, "R", L_Const.AnchorType.Middle, self.bindComponents.opShortKeys, L_Vector3.new(-326.3, 326.6))
  L_ShortCutManager:addShortKeyFlag(self, "Q", L_Const.AnchorType.Middle, self.bindComponents.opShortKeys, L_Vector3.new(-200.4, 394.9))
  if options.buildingId then
    self:doEditEntity(options.buildingId)
  elseif options.entity then
    self:doMoveEntity(options.entity)
  else
    errorf(L_WordsTpl:getValue("notice_pageHomePlayerEdit_02"))
  end
  self:initEditView()
end

function this:show()
  self.modules.moduleMovementBlock:showOrHideBtnRoot(false)
  self.modules.moduleMovementBlock:refreshBtnPos()
  self:registerShortCut()
end

function this:doEditEntity(buildingId)
  self._buildMode = editMode.set
  local editEntity = self._curEdit:getEditEntity()
  editEntity:setBuildId(buildingId, nil)
  editEntity:setBuildPos(C_Vector2.zero)
  self._curEdit:setEditEntityFront()
  self:setCurSelectedEntity(editEntity)
end

function this:exit()
  L_UI:close(self.pageName)
end

function this:close(options)
  L_CameraManager:getCameraTactics():SetCameraDis(3.5)
  L_CameraManager:getCameraTactics():SetFreezePinch(false)
  self._buildMode = nil
  self._curSelectEntity = nil
  C_InputManager.RemoveAxisListener(L_Const.axisType.emainMoveMent, self.controlMoveHandle)
  if L_WorldManager:getCurProxy() then
    L_WorldManager:getCurProxy():setEditMode(L_Const.HomeEditorMode.free)
  end
  if not self._curEdit.disposed then
    self._curEdit:setSelectEntity(nil)
    self._curBuildPart:refreshBuildings()
    self._curEdit:hideItemGrid()
    self._curBuildPart:handlePlayerStuck()
  end
end

function this:registerShortCut()
  L_ShortCutManager:registerShortCut(self.pageName, C_InputManager_KeyType.EHomeBuildingGarbage, function()
    if self.bind.goEditNode then
      self:unLocateBuilding()
    end
  end)
  L_ShortCutManager:registerShortCut(self.pageName, C_InputManager_KeyType.EHomePlayerEditRotate, function()
    if self.bind.goEditNode then
      self:onClick_rotate()
    end
  end)
  L_ShortCutManager:registerShortCut(self.pageName, C_InputManager_KeyType.EHomePlayerContinue, function()
    if self.bind.goEditNode then
      self:onClick_continue()
    end
  end)
  L_ShortCutManager:registerShortCut(self.pageName, C_InputManager_KeyType.EHomePlayerLook, function()
  end)
  L_ShortCutManager:registerShortCut(self.pageName, C_InputManager_KeyType.EHomePlayerBuilding, function()
    self:locateHomeBuilding()
  end)
end

function this:resetSelection()
  self._buildMode = editMode.none
  self:setCurSelectedEntity(nil)
  self:setLookInfo(false)
end

function this:setCurSelectedEntity(select)
  if self._curSelectEntity == select then
    return
  end
  self._curBlock:collectBarrierData()
  self._curSelectEntity = select
  self._curEdit:setSelectEntity(select)
  if select then
    self:refreshTips()
  end
  self:updateNowHomeBuildingShow(true)
  self:refreshTips()
end

function this:initEditView()
  self.bind.goEditNode = true
  local tpl = _homeBuildingTpl:getTplById(self._curSelectEntity:getBuildingId())
  local groupId = _homeBuildingTpl:getGroupId(tpl)
  local groupTpl = _homeBuildingGroupTpl:getTplById(groupId)
  local isCanGarbage = _homeBuildingGroupTpl:getIsStorable(groupTpl)
  self.bind.toggleGarbage = self._buildMode == editMode.move and isCanGarbage
  self._isContinue = false
  self:refreshContinueInfo()
  L_AudioUtil.playSound(_liftAudio)
end

function this:getContinueInfo()
  local buildingId = self._curSelectEntity:getBuildingId()
  local buildingInfo = L_HomeStore:getBuildingInBag(buildingId)
  if buildingInfo.total_num - buildingInfo.used_num >= 1 then
    return true
  end
  return false
end

local setType2Tip = {
  [L_Const.HomeSetErrorType.inOtherSet] = "notice_home_arrange_tip_1",
  [L_Const.HomeSetErrorType.outArea] = "notice_home_arrange_tip_2",
  [L_Const.HomeSetErrorType.inBarrier] = "notice_home_arrange_tip_8"
}

function this:refreshTips()
  self.bind.go_tipSet = false
  if self._checkOut then
    self.bind.go_tipSet = true
    self.bind.txt_tipSet = L_WordsTpl:getValue("notice_home_arrange_tip_6", {
      [0] = tostring(math.floor(5 - self._checkTime))
    })
  elseif self._curSelectEntity then
    local setType = self._curBuildPart:getEntityErrorSetType(self._curSelectEntity)
    self.bind.toggleSure = setType == L_Const.HomeSetErrorType.success
    if setType ~= L_Const.HomeSetErrorType.success then
      self.bind.go_tipSet = true
      self.bind.txt_tipSet = L_WordsTpl:getValue(setType2Tip[setType])
    end
  end
end

function this:locateHomeBuilding()
  if self._curSelectEntity == nil then
    return
  end
  if self._curBuildPart:getEntityErrorSetType(self._curSelectEntity) ~= L_Const.HomeSetErrorType.success then
    return
  end
  if self._buildMode == editMode.set then
    local buildingId = self._curSelectEntity:getBuildingId()
    L_HomeStore:req_locateBuilding(nil, self._curSelectEntity:getBuildingId(), self._curBlock:getBlockIndex(), self._curSelectEntity:getAnchorPosId(), self._curSelectEntity:getDirection(), function()
      L_HomeUtil.checkStartBuildingGuide(buildingId)
      self:afterOperate()
    end)
  elseif self._buildMode == editMode.move or self._buildMode == editMode.onlyMove then
    local targetEntity = self._curSelectEntity
    L_HomeStore:req_locateBuilding(self._curSelectEntity:getGUID(), nil, self._curBlock:getBlockIndex(), self._curSelectEntity:getAnchorPosId(), self._curSelectEntity:getDirection(), function()
      targetEntity:getBuildingAnimator():SetTrigger("create")
      targetEntity:playSmoke()
      targetEntity:checkIsIn()
      self:afterOperate()
      L_AudioUtil.playSound(_dropAudio)
    end)
  elseif self._buildMode == editMode.create then
    L_HomeStore:req_buildCreate(nil, self._curSelectEntity:getBuildingId(), self._curBlock:getBlockIndex(), self._curSelectEntity:getAnchorPosId(), self._curSelectEntity:getDirection(), function()
      self:afterOperate()
    end)
  end
end

function this:afterOperate()
  self:exit()
end

function this:unLocateBuilding()
  if self._curSelectEntity == nil then
    return
  end
  local serverData = L_HomeStore:getHomeBuildingByGuid(self._curSelectEntity:getGUID())
  if not serverData then
    return
  end
  if serverData.status == L_Const.WorldMapBuildStatusType.WMBST_BUILDING then
    L_FlyMsgManager:showNormalMsg(L_WordsTpl:getValue("notice_home_arrange_tip_5"))
    return
  elseif serverData.status == L_Const.WorldMapBuildStatusType.WMBST_UPGRADING then
    L_FlyMsgManager:showNormalMsg(L_WordsTpl:getValue("notice_home_arrange_tip_5"))
    return
  elseif serverData.status == L_Const.WorldMapBuildStatusType.WMBST_PRODUCT then
    L_FlyMsgManager:showNormalMsg(L_WordsTpl:getValue("notice_pageHomePlayerEdit_03"))
    return
  else
    local buildType = L_HomeManager:getBuildTypeById(serverData.build_id)
    if buildType == L_Const.WorldMapBuildType.WMBT_PET_CANTEEN and (L_SatietyManager:getBuildingSatiety(serverData.guid) > 0 or L_SatietyManager:isBuildingHasPetEating(serverData.guid)) then
      L_FlyMsgManager:showNormalMsg(L_WordsTpl:getValue("notice_moduleHomeBagCropInfo_01"))
      return
    end
  end
  local tpl = _homeBuildingTpl:getTplById(self._curSelectEntity:getBuildingId())
  local groupId = _homeBuildingTpl:getGroupId(tpl)
  local groupTpl = _homeBuildingGroupTpl:getTplById(groupId)
  local isCanGarbage = _homeBuildingGroupTpl:getIsStorable(groupTpl)
  if not isCanGarbage then
    return
  end
  L_HomeStore:req_BuildUnlocate(self._curSelectEntity:getGUID(), function()
    self:exit()
  end)
end

function this:onClick_look()
  if self._curSelectEntity == nil then
    return
  end
  self:setLookInfo(not self._isLook)
end

function this:setLookInfo(flag)
  if self._isLook == flag then
    return
  end
  if self._curSelectEntity == nil and flag then
    return
  end
  local fixFollow = L_CameraManager:getFixedFollow()
  if self._isLook == false then
    self.oldCameraInfo = {}
    self.oldCameraInfo.canScaleView = fixFollow.canScaleView
    self.oldCameraInfo.distance = fixFollow:GetDistance()
  end
  self._isLook = flag
  self.bind.go_keepLook = self._isLook
  if self.oldCameraInfo then
    if self._isLook then
      fixFollow.canScaleView = false
      fixFollow:SetDistance(60)
    else
      fixFollow.canScaleView = self.oldCameraInfo.canScaleView
      fixFollow:SetDistance(self.oldCameraInfo.distance)
    end
  end
end

function this:onClick_continue()
  self._isContinue = not self._isContinue
  self:refreshContinueInfo()
end

function this:refreshContinueInfo()
  if self._buildMode == editMode.set or self._buildMode == editMode.create then
    local restNum = 0
    if self._buildMode == editMode.set then
      local data = L_HomeStore:getBuildingInBag(self._curSelectEntity:getBuildingId())
      restNum = data.total_num - data.used_num
    elseif self._buildMode == editMode.create then
      local tpl = _homeBuildingTpl:getTplById(self._curSelectEntity:getBuildingId())
      local result, setNum, limitSet = L_HomeStore:checkSetLimit(_homeBuildingTpl:getGroupId(tpl))
      restNum = (limitSet or L_Const.maxInt) - setNum
      local costList = L_DataUtil.parseRewardConfig(_homeBuildingTpl:getMaterial(tpl))
      for i, v in ipairs(costList) do
        local haveNum = L_BagStore:getItemNum(v.itemId)
        restNum = math.min(restNum, math.floor(haveNum / v.itemNum))
      end
    end
    self.bind.txt_continueNum = restNum - 1 < 100 and tostring(restNum - 1) or ""
    self.bind.active_btnContinue = 1 < restNum
    self._isContinue = self._isContinue and 0 < restNum
  else
    self.bind.active_btnContinue = false
    self._isContinue = false
  end
  self.bind.active_continueOn = self._isContinue
end

function this:doMoveEntity(entity)
  if L_HomeStore:getStatusByGuid(entity:getGUID()) == L_Const.WorldMapBuildStatusType.WMBST_NORMAL then
    self._buildMode = editMode.move
  else
    self._buildMode = editMode.onlyMove
  end
  self:setCurSelectedEntity(entity)
  self._curBuildPart:refreshHomeItemsGrid()
end

function this:onClick_rotate()
  local entity = self._curSelectEntity
  local direction = entity:getDirection()
  direction = (direction + 1) % 4
  entity:rotateTransform(direction)
  self:updateNowHomeBuildingShow(true)
end

function this:update()
  self:updateNowHomeBuildingShow()
  self:outCheck()
end

function this:outCheck()
  local oldSate = self._checkOut
  if self._checkPos ~= self.mainControl:getWorldPosition() then
    self._checkPos = self.mainControl:getWorldPosition()
    local index = L_HomeManager:getBlockIndexByPlayerPos(self.mainControl:getWorldPosition(), L_HomeConst.blockType.BUILD)
    self._checkOut = index ~= self._curBlock.blockId
    if not self._checkOut then
      self._checkTime = 0
    end
  end
  if self._checkOut then
    self._checkTime = self._checkTime + Unity.Time.deltaTime
  end
  if self._checkTime > 0 then
    if self._checkTime >= 5 then
      self:exit()
    else
      self:refreshTips()
    end
  end
  if oldSate ~= self._checkOut then
    self:refreshTips()
  end
end

function this:updateNowHomeBuildingShow(force)
  self._curEdit:updateEditBuildPos(force)
  self:refreshTips()
end

return this
