Grid system mapping incorrectly on the bottom side

I’ve been making this system [PLEASE SOMEONE RESPOND THIS TIME] and the issue is that it’s working on all sides EXCEPT for the bottom side.

How to fix?

mouse.Move:Connect(function()
	local target = mouse.Hit
	if script.Parent.Properties.DoNotApply.Mode.Value == 0 and target then

		if connection then
			connection:Disconnect()
		end
		for _, obj in pairs(game.Workspace.Client:GetChildren()) do
			if obj.Name == "PreviewBlock" then
				obj:Destroy()
			end
		end

		local block = game.ReplicatedStorage.Files.BlockTypes:FindFirstChild(script.Parent.Properties.Shape.Value):Clone()
		block.Size = script.Parent.Properties.Size.Value
		block.Anchored = true
		block.CanCollide = false
		block.Color = script.Parent.Properties.Color.Value
		block.Material = Enum.Material[script.Parent.Properties.Material.Value]
		block.Transparency = script.Parent.Properties.Transparency.Value
		block.Reflectance = script.Parent.Properties.Reflectance.Value
		block.Name = "PreviewBlock"

		local raycastParams = RaycastParams.new()
		raycastParams.FilterDescendantsInstances = {game.Players.LocalPlayer.Character, block}
		raycastParams.FilterType = Enum.RaycastFilterType.Exclude
		local result = workspace:Raycast(workspace.CurrentCamera.CFrame.Position, (mouse.Hit.Position - workspace.CurrentCamera.CFrame.Position).Unit * 1000, raycastParams)

		local finalPos
		if result then
			local hitPos = result.Position
			local surfaceNormal = result.Normal

			finalPos = Vector3.new(
				math.floor(hitPos.X / block.Size.X) * block.Size.X + block.Size.X / 2,
				math.floor(hitPos.Y / block.Size.Y) * block.Size.Y + block.Size.Y / 2,
				math.floor(hitPos.Z / block.Size.Z) * block.Size.Z + block.Size.Z / 2
			)

			if math.abs(surfaceNormal.X) == 1 then
				finalPos = finalPos + Vector3.new((surfaceNormal.X * block.Size.X), 0, 0)
			elseif math.abs(surfaceNormal.Y) == 1 then
				if surfaceNormal.Y == -1 then
					finalPos = finalPos - Vector3.new(0, block.Size.Y, 0) 
				end
			elseif math.abs(surfaceNormal.Z) == 1 then
				finalPos = finalPos + Vector3.new(0, 0, (surfaceNormal.Z * block.Size.Z))
			end
		else
			finalPos = Vector3.new(
				math.floor(target.Position.X / block.Size.X) * block.Size.X + block.Size.X / 2,
				math.floor(target.Position.Y / block.Size.Y) * block.Size.Y + block.Size.Y / 2,
				math.floor(target.Position.Z / block.Size.Z) * block.Size.Z + block.Size.Z / 2
			)
		end
		
		block.Position = finalPos
		block.Parent = game.Workspace.Client
		connection = mouse.Button1Down:Connect(function()
			local tables = {
				Transparency = script.Parent.Properties.Transparency.Value,
				Reflectance = script.Parent.Properties.Reflectance.Value,
				Collision = script.Parent.Properties.Collision.Value,
				LightRadius = script.Parent.Properties.Light.Radius.Value,
				LightType = script.Parent.Properties.Light.Type.Value,
				LightBrightness = script.Parent.Properties.Light.Brightness.Value,
				LightColor = script.Parent.Properties.Light.Color.Value,
				Shape = script.Parent.Properties.Shape.Value,
				Color = script.Parent.Properties.Color.Value,
				Material = script.Parent.Properties.Material.Value,
				Size = script.Parent.Properties.Size.Value,
				Position = block.CFrame
			}
			local event = game.ReplicatedStorage.Files.Events.NonNative.Place
			event:FireServer(tables)
		end)
	end
end)