using Sandbox;
using Sandbox.Audio;
using System;
using System.Text.Json.Serialization;
using VeloX.Audio;
using static Sandbox.Utility.Noise;
using static VeloX.EngineStream;

namespace VeloX;


public abstract partial class VeloXBase : Component, Component.ICollisionListener
{

	[Property, Feature( "Effects" ), Group( "Sound" )]
	public SoundEvent SuspensionHeavySound { get; protected set; } = ResourceLibrary.Get<SoundEvent>( "sounds/suspension/compress_heavy.sound" );

	[Property, Feature( "Effects" ), Group( "Sound" )]
	public SoundEvent SuspensionDownSound { get; protected set; } = ResourceLibrary.Get<SoundEvent>( "sounds/suspension/pneumatic_down.sound" );

	[Property, Feature( "Effects" ), Group( "Sound" )]
	public SoundEvent SuspensionUpSound { get; protected set; } = ResourceLibrary.Get<SoundEvent>( "sounds/suspension/pneumatic_up.sound" );

	[Property, Feature( "Effects" ), Group( "Sound" )]
	public SoundEvent SoftCollisionSound { get; protected set; } = ResourceLibrary.Get<SoundEvent>( "sounds/collisions/car_light.sound" );

	[Property, Feature( "Effects" ), Group( "Sound" )]
	public SoundEvent HardCollisionSound { get; protected set; } = ResourceLibrary.Get<SoundEvent>( "sounds/collisions/car_heavy.sound" );

	[Property, Feature( "Effects" ), Group( "Sound" )]
	public SoundEvent VehicleScrapeSound { get; protected set; } = ResourceLibrary.Get<SoundEvent>( "sounds/collisions/metal_scrape.sound" );

	[Property, Feature( "Effects" ), Group( "Particle" )]
	public GameObject MetalImpactEffect { get; protected set; } = GameObject.GetPrefab( "effects/metal_impact.prefab" );
	void ICollisionListener.OnCollisionStart( Collision collision )
	{

		var speed = MathF.Abs( collision.Contact.NormalSpeed );
		var surfaceNormal = collision.Contact.Normal;
		if ( speed < 100 )
			return;

		var isHardHit = speed > 300;
		var volume = Math.Clamp( speed / 400f, 0, 1 );
		var sound = Sound.Play( SoftCollisionSound, WorldPosition );
		sound.Volume = volume;

		var a = MetalImpactEffect.Clone( new CloneConfig() { StartEnabled = true, Transform = new( collision.Contact.Point, surfaceNormal.Cross( surfaceNormal ).EulerAngles ) } );
		a.Components.Get<ParticleConeEmitter>().Burst = speed / 2;

		if ( isHardHit )
		{
			var hardSound = Sound.Play( HardCollisionSound, WorldPosition );
			hardSound.Volume = volume;
			TriggerHaptics( HapticEffect.HardImpact );
		}
		else if ( surfaceNormal.Dot( -collision.Contact.Speed.Normal ) < 0.5f )
		{
			var scrapSound = Sound.Play( VehicleScrapeSound, WorldPosition );
			scrapSound.Volume = 0.4f;
			TriggerHaptics( HapticEffect.SoftImpact );
		}
	}
}
