using Sandbox;
using System;
using VeloX.Utils;

namespace VeloX;

public partial class VeloXCar
{
	public static float ExpDecay( float a, float b, float decay, float dt ) => b + (a - b) * MathF.Exp( -decay * dt );
	[Property, Feature( "Steer" )] public float MaxSteerAngle { get; set; } = 40f;

	[ConVar( "steer_return_speed" )]
	[Property] public static float SteerReturnSpeed { get; set; } = 6f;

	[ConVar( "steer_speed" )]
	public static float SteerInputResponse { get; set; } = 3f;


	[ConVar( "assist_mult" )]
	public static float MaxSteerAngleMultiplier { get; set; } = 1f;
	public int CarDirection { get { return ForwardSpeed < 1 ? 0 : (VelocityAngle < 90 && VelocityAngle > -90 ? 1 : -1); } }
	public float VelocityAngle { get; private set; }

	[Sync] public float Steering { get; private set; }

	private float currentSteerAngle;
	private float inputSteer;
	private void UpdateSteering( float dt )
	{
		inputSteer = Input.AnalogMove.y;


		float targetSteerAngle = inputSteer * MaxSteerAngle;

		if ( !Input.Down( "Jump" ) )
			targetSteerAngle *= Math.Clamp( 1 - Math.Clamp( TotalSpeed / 3000, 0f, 0.85f ), -1, 1 );

		VelocityAngle = -Body.Velocity.SignedAngle( WorldRotation.Forward, WorldRotation.Up );

		float targetAngle = 0;

		if ( TotalSpeed > 150 && CarDirection > 0 && IsOnGround )
			targetAngle = VelocityAngle * MaxSteerAngleMultiplier;

		float lerpSpeed = Math.Abs( inputSteer ) < 0.1f ? SteerReturnSpeed : SteerInputResponse;

		currentSteerAngle = ExpDecay( currentSteerAngle, targetSteerAngle, lerpSpeed, Time.Delta );
		Steering = currentSteerAngle + targetAngle;
		SteerAngle = new( 0, Math.Clamp( Steering, -MaxSteerAngle, MaxSteerAngle ), 0 );
	}
}
