using Sandbox;
using System;
using System.Collections.Generic;

namespace VeloX;

public partial class VeloXCar
{

	private class DownforcePoint
	{
		[KeyProperty] public float MaxForce { get; set; }
		[KeyProperty] public Vector3 Position { get; set; }
	}
	public const float RHO = 1.225f;
	[Property, Feature( "Aerodinamics" )] public Vector3 Dimensions = new( 2f, 4.5f, 1.5f );
	[Property, Feature( "Aerodinamics" )] public float FrontalCd { get; set; } = 0.35f;
	[Property, Feature( "Aerodinamics" )] public float SideCd { get; set; } = 1.05f;
	[Property, Feature( "Aerodinamics" )] public float MaxDownforceSpeed { get; set; } = 80f;
	[Property, Feature( "Aerodinamics" )] private List<DownforcePoint> DownforcePoints { get; set; } = [];

	private float _forwardSpeed;
	private float _frontalArea;

	private float _sideArea;
	private float _sideSpeed;
	private float lateralDragForce;
	private float longitudinalDragForce;

	private void SimulateAerodinamics( float dt )
	{
		if ( TotalSpeed < 1f )
		{
			longitudinalDragForce = 0;
			lateralDragForce = 0;
			return;
		}

		_frontalArea = Dimensions.x * Dimensions.z * 0.85f;
		_sideArea = Dimensions.y * Dimensions.z * 0.8f;
		_forwardSpeed = LocalVelocity.x.InchToMeter();
		_sideSpeed = LocalVelocity.y.InchToMeter();
		longitudinalDragForce = 0.5f * RHO * _frontalArea * FrontalCd * (_forwardSpeed * _forwardSpeed) * (_forwardSpeed > 0 ? -1f : 1f);
		lateralDragForce = 0.5f * RHO * _sideArea * SideCd * (_sideSpeed * _sideSpeed) * (_sideSpeed > 0 ? -1f : 1f);
		var force = new Vector3( longitudinalDragForce.MeterToInch(), lateralDragForce.MeterToInch(), 0 ).RotateAround( Vector3.Zero, WorldRotation );
		Body.ApplyForce( force );
		//DebugOverlay.Normal( WorldPosition, force );

		float speedPercent = TotalSpeed / MaxDownforceSpeed;
		float forceCoeff = 1f - (1f - MathF.Pow( speedPercent, 2f ));

		foreach ( DownforcePoint dp in DownforcePoints )
			Body.ApplyForceAt( Transform.World.PointToWorld( dp.Position ), forceCoeff.MeterToInch() * dp.MaxForce.MeterToInch() * -WorldRotation.Up );
	}

	//protected override void DrawGizmos()
	//{
	//	Gizmo.Draw.LineBBox( new BBox( -Dimensions / 2 * 39.37f, Dimensions / 2 * 39.37f ) );
	//}
}
