-- TODO: retry multiple time if HTTP call fail

local function getTextureId(id: number): number?
	local assetInfo = MarketplaceService:GetProductInfo(id, Enum.InfoType.Asset)

	if assetInfo.AssetTypeId == Enum.AssetType.Image.Value then
		return id
	elseif assetInfo.AssetTypeId == Enum.AssetType.Decal.Value then
		return HttpService:GetAsync(`http://f3xteam.com/bt/getDecalImageID/{id}`)
	end

	return
end

Remote.OnServerEvent:Connect(function(plr, id: number | string, pos)
	if Helper.Owner ~= plr then
		return
	end

	local assetId = tonumber(tostring(id):match("%d+") or 0) :: number

	if assetId == 0 then
		return
	end

	local textureId = getTextureId(assetId)

	if not textureId then
		return
	end

	if textureId ~= 0 then
		local rayOrigin = Tool.Handle.Position
		local rayDestination = pos

		local rayDirection = rayDestination - rayOrigin

		if rayDirection.Magnitude >= 10 then
			return
		end

		local raycastParams = RaycastParams.new()
		raycastParams.FilterDescendantsInstances = {plr.Character}
		raycastParams.FilterType = Enum.RaycastFilterType.Exclude
		raycastParams.IgnoreWater = true

		local raycastResult = workspace:Raycast(rayOrigin, rayDirection*2, raycastParams)

		if (raycastResult) and raycastResult.Instance then
			if raycastResult.Instance:FindFirstAncestorWhichIsA("Model") then
				if raycastResult.Instance:FindFirstAncestorWhichIsA("Model"):FindFirstChildWhichIsA("Humanoid") then
					return
				end
			end
			if raycastResult.Instance:FindFirstAncestorWhichIsA("Tool") then
				return
			end
			
			local sprays = {}

			for _, i in ipairs(workspace.Sprays:GetChildren()) do
				if i:GetAttribute("User") then
					if i:GetAttribute("User") == plr.UserId then
						table.insert(sprays, i)
					end
				end
			end

			if #sprays >= 3 then
				if sprays[1] then
					sprays[1]:Destroy()
				end
			end
			
			Tool.Handle.Spray:Play()

			local object = game.ServerStorage.PaintedObject:Clone()
			object.Decal.Texture =`rbxassetid://{textureId}`
			object.CFrame = CFrame.lookAt(raycastResult.Position, raycastResult.Position - raycastResult.Normal)
			object:SetAttribute("User", plr.UserId)
			object.Parent = workspace.Sprays

			if raycastResult.Instance.Anchored == false then
				object.Anchored = false

				local c0 = raycastResult.Instance.CFrame:Inverse()
				local c1 = object.CFrame:Inverse()

				local weld = Instance.new("Weld")
				weld.Parent = object

				weld.Part0 = raycastResult.Instance
				weld.Part1 = object

				weld.C0 = c0
				weld.C1 = c1
			end
		end
	end
end)
