/*
 * Copyright (c)2009-2025 DemiVision, LLC. All Rights Reserved. The information
 * herein is the CONFIDENTIAL and PROPRIETARY information of DemiVision, LLC.
 */

using Syncfusion.Maui.DataSource;

using DXLib.UI.Container;
using DXLib.UI.Control.List.Template;

using DXLib.Data;
using DXLib.Utils;

namespace DXLib.UI.Control.List;

/*
 * Displays a scrollable vertical list of menu items in a modal popup with optional menu title. Each menu item includes
 * a text label with optional icon, image, or secondary label. Menu items can optionally be sorted and/or grouped.
 */
public class DXListMenu : DXPopup
{
	/* Constants */
	public const int TapDelay = 250;
	
	// Defines row display items
	public enum ListType
	{
		Text,
		Icon,
		Image
	};

	/* Actions */
	public Action<DXItem> ItemSelected { get; set; }
	public Action Cancelled { get; set; }

	/* Properties */

	// Text, icon, image
	public ListType Type { get; set;}

	// Default icon
	public string Icon { get; set; }

	// Display config
	public Thickness ListPadding { set { if ( listView != null ) listView.Padding = value; } }
	public double RowHeight { set { if ( listView != null ) listView.RowHeight = value; } }

	/* Fields */
	private DXListView listView;

	/* Methods */

	// Creates menu with no title
	public DXListMenu( bool modal = true ) : base( null, null )
	{
		IsModal = modal;
	}

	// Creates menu with specified title
	public DXListMenu( string header, bool modal = true ) : base( header, null )
	{
		IsModal = modal;
	}

	// Sets list of menu items
	public void SetItems( List<DXListMenuItem> items, bool sorted = false, bool grouped = false )
	{
		Padding = 0;

		Thickness padding = new( 5, 0 );
		const string roboto = DXFonts.Roboto;

		// Apply default styling
		foreach ( DXListMenuItem item in items )
		{
			item.Padding = padding;

			item.Color = DXColors.Light4;
			item.TextColor = DXColors.Dark1;

			item.Font = roboto;
			item.FontSize = 20;
		}

		// Create underlying list
		listView = new DXListView
		{
			Padding = 0,
			Mode = DXListView.SelectMode.Single,

			ItemSpacing = 1,
			ItemsSource = items,

			ItemSelected = OnItemSelected,
			
			// Text, Icon, or Image templates
			ItemTemplate = GetTemplate( false ),
			SelectedItemTemplate = GetTemplate( true )
		};

		// Optional ascending sort
		if ( sorted )
		{
			listView.DataSource?.SortDescriptors.Add( new SortDescriptor()
			{
				PropertyName = grouped ? "Alpha" : "Value",
				Direction = ListSortDirection.Ascending,
			});
		}

		// Optional grouping by first letter
		if ( grouped )
		{
			listView.GroupHeaderSize = 20;
			listView.IsStickyGroupHeader = false;

			listView.DataSource?.GroupDescriptors.Add( new GroupDescriptor()
			{
				PropertyName = "Alpha",
			});
		}

		SetContent( listView );
	}

	// Returns template for configured type
	private DataTemplate GetTemplate( bool selected )
	{
        return Type switch
        {
            ListType.Text => new DataTemplate( () => new DXListTemplate( selected ) ),
            ListType.Icon => new DataTemplate( () => new DXListIconTemplate( Icon, selected ) ),
            ListType.Image => new DataTemplate( () => new DXListImageTemplate( Icon, selected ) ),

            _ => null,
        };
    }

    /* Event Callbacks */

    // User selected item from list, callback listener
    private void OnItemSelected( object item )
	{
		// Short delay to show tap state
		DXTimer.Delay( TapDelay, () =>
		{
			ItemSelected?.Invoke( item as DXItem );
			Hide();
		});
	}

	// User dismissed menu, callback listener
	protected override void OnClosed( object sender, EventArgs args )
	{
		Cancelled?.Invoke();
	}
}

//
