Editor/Widgets/SuiDetailsSectionHeader.cs
using System;
using Editor;
using Sandbox;

namespace SboxUiDesigner.EditorUi.Widgets;

/// <summary>
/// Collapsible section header in the Details panel. Chevron on the left,
/// uppercase label centered, subtle dark fill so it reads as a band but
/// doesn't compete with the panel chrome.
/// </summary>
public sealed class SuiDetailsSectionHeader : Widget
{
	public string Title { get; }
	public bool IsExpanded = true;
	public event Action ToggledExpanded;

	private bool _hover;

	public SuiDetailsSectionHeader( string title, Widget parent = null ) : base( parent )
	{
		Title = title ?? "";
		FixedHeight = 24;
		Cursor = CursorShape.Finger;
		SetStyles( "background-color: transparent; border: none;" );
	}

	protected override void OnPaint()
	{
		var rect = LocalRect;

		// Subtle band background (#272726 — slightly lighter than the dock body
		// #212120 to read as a header). Hover bumps it a touch.
		var bg = _hover
			? new Color( 50 / 255f, 50 / 255f, 49 / 255f )
			: new Color( 39 / 255f, 39 / 255f, 38 / 255f );
		Paint.SetBrushAndPen( bg );
		Paint.DrawRect( rect, 3f );

		// Chevron at left — same shape used in Palette / Hierarchy headers.
		Paint.SetPen( new Color( 165 / 255f, 172 / 255f, 182 / 255f ), 2f );
		float cy = Height / 2f;
		if ( IsExpanded )
		{
			// ▾ down
			Paint.DrawLine( new Vector2( 6, cy - 2 ), new Vector2( 10, cy + 2 ) );
			Paint.DrawLine( new Vector2( 10, cy + 2 ), new Vector2( 14, cy - 2 ) );
		}
		else
		{
			// ▸ right
			Paint.DrawLine( new Vector2( 7, cy - 4 ), new Vector2( 11, cy ) );
			Paint.DrawLine( new Vector2( 11, cy ), new Vector2( 7, cy + 4 ) );
		}

		// Title — left-aligned just past the chevron, small caps + bold.
		Paint.SetFont( null, 9, 700 );
		Paint.SetPen( new Color( 200 / 255f, 204 / 255f, 210 / 255f ) );
		Paint.DrawText( new Rect( 22, 0, Width - 24, Height ), Title, TextFlag.LeftCenter );
	}

	protected override void OnMouseEnter() { _hover = true; Update(); }
	protected override void OnMouseLeave() { _hover = false; Update(); }
	protected override void OnMousePress( MouseEvent e )
	{
		if ( e.LeftMouseButton ) ToggledExpanded?.Invoke();
	}
}

/// <summary>
/// Sub-header inside an open section (e.g. "Notes" or a per-prop subgroup).
/// Visually quieter than a full section header — small uppercase tracking,
/// no background, just a row of text.
/// </summary>
public sealed class SuiDetailsSubHeader : Widget
{
	public string Title { get; }

	public SuiDetailsSubHeader( string title, Widget parent = null ) : base( parent )
	{
		Title = title?.ToUpperInvariant() ?? "";
		FixedHeight = 22;
		SetStyles( "background-color: transparent; border: none;" );
	}

	protected override void OnPaint()
	{
		Paint.SetDefaultFont( 10 );
		Paint.SetPen( new Color( 140 / 255f, 145 / 255f, 153 / 255f ) );
		// Small horizontal padding so it lines up with section header text.
		Paint.DrawText( new Rect( 4, 6, Width - 8, Height - 6 ), Title, TextFlag.LeftCenter );
	}
}

/// <summary>
/// A complete collapsible section: header + a content container that toggles
/// visibility when the header is clicked. Add rows to <see cref="Body"/>.
/// </summary>
public sealed class SuiDetailsSection : Widget
{
	public SuiDetailsSectionHeader Header { get; }
	public Widget Body { get; }

	public SuiDetailsSection( string title, Widget parent = null, bool expanded = true ) : base( parent )
	{
		SetStyles( "background-color: transparent; border: none;" );
		Layout = Layout.Column();
		Layout.Margin = new Sandbox.UI.Margin( 0, 2, 0, 2 );
		Layout.Spacing = 0;

		Header = new SuiDetailsSectionHeader( title, this );
		Header.IsExpanded = expanded;
		Header.ToggledExpanded += () =>
		{
			Header.IsExpanded = !Header.IsExpanded;
			Header.Update();
			if ( Body.IsValid() ) Body.Visible = Header.IsExpanded;
		};
		Layout.Add( Header );

		Body = new Widget( this );
		Body.SetStyles( "background-color: transparent; border: none;" );
		Body.Layout = Layout.Column();
		// Pure Layout.Margin path — eliminate ContentMargins (was conflicting).
		// Right=16 = gap from scrollbar; vertical=4 = breathing room above/below
		// the rows.
		Body.Layout.Margin = new Sandbox.UI.Margin( 0, 4, 16, 4 );
		Body.Layout.Spacing = 0;
		Body.Visible = expanded;
		Layout.Add( Body );
	}
}