local this = class("mapNode")
local _worldFilterTpl = L_GameTpl:getWorldFilterTpl()
local _typeImg = typeof(C_LImage)
local _typeBtn = typeof(C_LButton)
local _typeTxt = typeof(C_LTextMeshProUGUI)
local _typeRect = typeof(C_RectTransform)
local _filterMarkTpl = L_GameTpl:getWorldFilterMarkTpl()
local _screenPosToUI = Unity.RectTransformUtility.ScreenPointToLocalPointInRectangle
local PATH_MAPNODE = "UI/Pages/Map/BigMap/cellMapNode.prefab"

function this:ctor(type)
  self.type = type
  self.id = nil
  self.entityId = nil
  self.configPos = nil
  self.iconPath = nil
  self.iconBg = nil
  self.filterMarkId = nil
  self.isShow = true
end

function this:getType()
  return self.type
end

function this:setShow(isShow)
  if self.isShow == isShow then
    return
  end
  self.isShow = isShow
  if self.go then
    self.go:ActiveTrans(isShow)
  end
  if self.animation then
    if isShow == true then
      self.animation:Stop()
      self.animation:Play("anim_tipnode_show")
    else
      self.animation:Stop()
      self.animation:Play("anim_tipnode_hide")
    end
  end
end

function this:setIsUnlock(isUnLock)
  self.isUnLock = isUnLock
  if self.imgNode then
    self.imgNode.color = isUnLock == true and C_Color(1, 1, 1, 1) or C_Color(0.627, 0.627, 0.627, 0.7)
  end
end

function this:generate(parent, pool)
  self:_generate(parent, pool or L_ResPool)
  if parent then
    self.trans:Reset(parent)
  else
    L_Vector3.setScale(self.trans, L_Vector3.getTemp(1, 1, 1))
    L_Vector3.setLocalPos(self.trans, L_Vector3.getTemp())
  end
  self.go.name = self.id
  self.isShow = true
  if self.iconPath then
    self.imgNode:LoadSprite(self.iconPath)
    self.imgNode.enabled = true
  end
  if self.imgNodeGo then
    if self.iconBg then
      if self.iconBgResize then
        self.trans:Find("nodeIconBg").offsetMin = C_Vector2(0, 0)
        self.trans:Find("nodeIconBg").offsetMax = C_Vector2(0, 0)
      end
      self.imgNodeGo:ActiveTrans(true)
      self.imgNodeBg:LoadSprite(self.iconBg)
    else
      self.imgNodeGo:ActiveTrans(false)
    end
  end
  if self.areaGuideGo then
    self.areaGuideGo:SetActive(false)
  end
end

function this:_generate(parent, pool)
  local go = pool:syncGameObject(PATH_MAPNODE)
  self.go = go
  self.trans = self.go:GetComponent(_typeRect)
  self.imgNode = self.trans:Find("nodeIcon").gameObject:GetComponent(_typeImg)
  self.imgNodeBg = self.trans:Find("nodeIconBg").gameObject:GetComponent(_typeImg)
  self.imgNodeGo = self.trans:Find("nodeIconBg").gameObject
  self.btnNode = self.go:GetComponent(_typeBtn)
  self.choose = self.trans:Find("IsChoose").gameObject
  self.animation = self.go:GetComponent(typeof(C_Animation))
  self.traceEffect = self.go:GetComponent(typeof(C_UIEffectControl))
  self.location = self.trans:Find("nodeIcon/location").gameObject
  self.locationTrans = self.location:GetComponent(typeof(C_RectTransform))
  self.areaGuideTrans = self.trans:Find("areaGuide")
  self.areaGuideGo = self.areaGuideTrans.gameObject
end

function this:addClick(clickHandle)
  if not self.btnNode then
    return
  end
  self.btnNode.onClick:RemoveAllListeners()
  self.btnNode.onClick:AddListener(clickHandle)
end

function this:refreshPosByMapData(mapData)
  local l2w = mapData:worldToLocal(self.configPos)
  L_Vector3.setAnchored(self.trans, l2w)
  L_Vector3.setSize(self.trans, 1 / mapData.imgScale)
end

function this:checkShow(mapData)
  local isShow = true
  if not math.isEmpty(self.filterMarkId) then
    local tpl = _filterMarkTpl:getTplById(self.filterMarkId)
    local unlockCondition = _filterMarkTpl:getUnlockCondition(tpl)
    if not L_ConditionManager:isComplete(unlockCondition) then
      return false
    end
  end
  if mapData.isBigMap then
    local tpl = _worldFilterTpl:getTplById(self.type)
    if tpl then
      local resizeRange = _worldFilterTpl:getResizingShow(tpl)
      local min = resizeRange[1] / 100
      local max = resizeRange[2] / 100
      local percent = mapData:getPercent()
      isShow = min <= percent and max >= percent
    end
  end
  if self.hideNode then
    return false
  end
  return isShow
end

function this:refreshState(mapData)
  local isShow = self:checkShow(mapData)
  self:setShow(isShow)
end

function this:refreshNodeTraceState()
  local curTracedNode = L_MapStore:getCurNodeTargetTracing()
  if table.isEmpty(curTracedNode) then
    self:stopTraceEffect()
  elseif curTracedNode.nodeType == self.type and curTracedNode.id == self.id then
    self:playTraceEffect()
  else
    self:stopTraceEffect()
  end
end

function this:playTraceEffect()
  if self.effectTimer == nil then
    self.effectTimer = Timer.repeated(1.1, function()
      self.traceEffect:Play()
    end, self, self.go)
  end
end

function this:stopTraceEffect()
  if self.effectTimer ~= nil then
    Timer.remove(self.effectTimer)
    self.effectTimer = nil
  end
end

function this:refreshLockState()
end

function this:refreshRelativeHeightPos(canShowLocation, index)
  if self.showLocation ~= canShowLocation then
    self.showLocation = canShowLocation
    if L_CommonUtil.isValid(self.location) then
      self.location:ActiveTrans(self.showLocation)
    end
  end
  if self.localtionIndex ~= index and L_CommonUtil.isValid(self.locationTrans) then
    self.localtionIndex = index
    local angle = index == 1 and 0 or 180
    self.locationTrans:SetLocalEulerAngles(0, 0, angle)
  end
end

function this:setSize(size)
  self.trans.sizeDelta = L_Vector3.new(size.x, size.y)
end

function this:getNodeScreenPos(parent)
  if not self.isShow then
    return nil
  end
  local cellPos = self.trans.position
  local screenPos_cell = C_CameraManager.uiCamera:WorldToScreenPoint(cellPos)
  local v2 = L_Vector3.new(screenPos_cell.x, screenPos_cell.y)
  local parent = parent
  local _, uiPos = _screenPosToUI(parent, v2, C_CameraManager.uiCamera)
  return uiPos
end

function this:onDestroy()
  self:stopTraceEffect()
  if self.go then
    C_GameObject.Destroy(self.go)
  end
end

return this
