
using Editor;
using Sandbox;
using System.Numerics;
using VeloX.Audio;
using static VeloX.EngineStream;

namespace VeloX;
internal class LayerObjectWidget : ControlObjectWidget
{
	private SerializedProperty Index;

	private SerializedCollection Controllers;
	private class ControllerWidget : ControlObjectWidget
	{
		public ControllerWidget( LayerObjectWidget parent, SerializedProperty property ) : base( property, true )
		{
			PaintBackground = false;
			Layout = Layout.Row();
			HorizontalSizeMode = (SizeMode)3;
			//SetStyles( "background-color: #123; color: white; font-weight: 600;" );
			SerializedObject.TryGetProperty( nameof( Controller.InputParameter ), out var inputType );
			Layout.Add( EnumControlWidget.Create( inputType ), 1 );
			SerializedObject.TryGetProperty( nameof( Controller.InputRange ), out var inputRange );
			Layout.Add( ValueRangeWidget.Create( inputRange ), 12 );

			SerializedObject.TryGetProperty( nameof( Controller.OutputParameter ), out var outputType );
			Layout.Add( EnumControlWidget.Create( outputType ), 1 );
			SerializedObject.TryGetProperty( nameof( Controller.OutputRange ), out var outputRange );
			Layout.Add( ValueRangeWidget.Create( outputRange ), 12 );
			var removeButton = new IconButton( "clear", () => parent.RemoveEntry( property ) ) { ToolTip = "Remove", Background = Theme.ControlBackground, FixedWidth = Theme.RowHeight, FixedHeight = Theme.RowHeight };
			Layout.Add( removeButton );
		}

	}

	void RemoveEntry( SerializedProperty index )
	{
		Controllers.Remove( index );
		Rebuild();
	}
	private SerializedCollection layers;

	SimulatedEngineWidget SimulatedEngine;
	public LayerObjectWidget( SerializedProperty property, SerializedProperty index, SerializedCollection layers, SimulatedEngineWidget SimulatedEngine ) : base( property, true )
	{

		this.SimulatedEngine = SimulatedEngine;
		SetStyles( "background-color: #;" );

		this.layers = layers;
		Index = index;
		Layout = Layout.Column();
		Layout.SizeConstraint = SizeConstraint.SetMaximumSize;
		Layout.Alignment = TextFlag.Top;
		Layout.Margin = 4;
		Layout.Spacing = 4;

		Rebuild();
	}
	protected override void PaintUnder()
	{

		base.PaintUnder();

		if ( SimulatedEngine is null )
			return;
		if ( SimulatedEngine.Player is null )
			return;

		var layer = SimulatedEngine.Player.Stream.Layers[Index.GetValue<string>()];
		if ( SimulatedEngine.Player.EngineSounds.TryGetValue( layer, out var handle ) )
		{

			Paint.SetBrush( Color.Gray );
			Rect localRect = base.LocalRect;
			var newVolume = localRect.Width * handle.Volume;

			Paint.DrawRect( new( 0, 0, newVolume, localRect.Height ) );

			Update();
		}
	}

	public void Rebuild()
	{
		using var _ = SuspendUpdates.For( this );
		Layout.Clear( true );
		VerticalSizeMode = SizeMode.CanShrink;

		var layout = Layout.AddRow();
		layout.Alignment = TextFlag.Top;
		var id = layout.Add(
			StringControlWidget.Create( Index ), 1
		 ).HorizontalSizeMode = SizeMode.Flexible;

		layout.Add(
			ResourceControlWidget.Create( SerializedObject.GetProperty( nameof( Layer.AudioPath ) ) ), 3
		).HorizontalSizeMode = SizeMode.Flexible;

		var ctlrs = Layout.AddColumn();
		ctlrs.Spacing = 2;
		ctlrs.Margin = 4;

		var hints = ctlrs.AddRow();
		hints.Add( new Label( "Input Type" ), 3 );
		hints.Add( new Label( "Input Min" ), 2 );
		hints.Add( new Label( "Input Max" ), 2 );
		hints.Add( new Label( "Output Type" ), 3 );
		hints.Add( new Label( "Output Min" ), 2 );
		hints.Add( new Label( "Output Max" ), 2 );

		if ( !SerializedObject.TryGetProperty( nameof( Layer.Controllers ), out var constrollers ) )
			return;

		if ( !constrollers.TryGetAsObject( out var so ) || so is not SerializedCollection sc )
			return;

		Controllers = sc;
		Controllers.OnEntryAdded = Rebuild;
		Controllers.OnEntryRemoved = Rebuild;
		foreach ( var controller in sc )
		{
			ctlrs.Add( new ControllerWidget( this, controller ) );
		}

		var footer = ctlrs.AddRow();
		var controls = footer.AddRow();
		controls.Alignment = TextFlag.Left;
		controls.Spacing = 4;

		var useRedline = SerializedObject.GetProperty( nameof( Layer.UseRedline ) );
		controls.Add( new BoolControlWidget( useRedline ) );
		controls.Add( new Label( useRedline.Description ) );

		var isMuted = SerializedObject.GetProperty( nameof( Layer.IsMuted ) );
		controls.Add( new BoolControlWidget( isMuted ) );
		controls.Add( new Label( isMuted.DisplayName ) );

		var cont = footer.AddRow();
		cont.Spacing = 4;
		cont.Alignment = TextFlag.Right;
		cont.Add( new Button( "Add Controller" ) ).Clicked = () =>
		{
			Controllers.Add( null );
		};

		cont.Add( new Button( "Remove Layer" ) ).Clicked = () =>
		{
			layers.RemoveAt( Index.GetValue<string>() );
		};

	}
}
