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

using System.Collections.ObjectModel;

using DXLib.UI.Gestures;
using DXLib.Data.Model;
using DXLib.Utils;

namespace DXLib.UI.Control.Selector;

/*
 * Extended version of DXSelector supporting the addition of new objects to the dropdown list. An '+ Add New Foo' footer
 * will be added to the dropdown menu. Only object lists, not items, are supported.
 */
public class DXAddSelector : DXSelector
{
    /* Constants */
    private const int TapDelay = 250;
    
    // Default colors
    private static readonly Color DefaultColor = DXColors.Light2;
    private static readonly Color TapColor = DXColors.Accent1;

    /* Properties */
    
    // Foo name for 'Add New Foo' label
    public override string ObjectLabel { set => SetLabel( value ); }
    
    /* Fields */
	private readonly DXGridGestures addLayout;
    private readonly DXLabel addLabel;

    /* Methods */
	public DXAddSelector()
	{
        // Layout
		addLayout = new DXGridGestures
		{
			BackgroundColor = DefaultColor,

			Padding = new Thickness( 10, 0 ),
            ColumnSpacing = 4
		};

		addLayout.Tapped += OnAddTapped;

		const double iconSize = 25;
		
        // + icon
        DXIcon addIcon = new()
        {
            Resource = "add_circle",
            Color = DXColors.Dark3,
            
            Size = iconSize,

            Horizontal = LayoutOptions.Start,
            Vertical = LayoutOptions.Center
        };
        
        // 'Add New Foo'
        addLabel = new DXLabel
        {
            TextColor = DXColors.Dark3,

            Font = DXFonts.Roboto,
            FontSize = 17,

            Horizontal = LayoutOptions.Start,
            Vertical = LayoutOptions.Center
        };
        
        // 1 row, 2 columns
        addLayout.AddFixedColumn( iconSize );		// 0: icon
        addLayout.AddStarColumn();					// 1: label
        
        addLayout.Add( addIcon, 0, 0 );
        addLayout.Add( addLabel, 1, 0 );

        // Using footer
        ShowDropdownFooterView = true;
        DropdownFooterViewHeight = 35;
		DropdownFooterView = addLayout;
	}

    // Loads list from specified query results
    public override void LoadObjects( IList<DXModel> list )
    {
        // Do NOT disable if empty
        if ( list != null )
        {
            // Empty list, add blank row so footer can still be used
            if ( list.Count == 0 )
            {
                DXEmptyModel model = new();
                objects = new ObservableCollection<DXModel>( [model] );
            }
            // Sort alphabetically
            else
            {
                objects = new ObservableCollection<DXModel>( list.OrderBy( m => m.ObjectName ) );
            }

            ItemsSource = objects;
            DisplayMemberPath = "ObjectName";
        }
    }

    // Creates object specific 'Add New Foo' label
    private void SetLabel( string label )
    {
        string addNew = DXString.Get( "card.new" );
        string objName = DXString.Get( $"{label}.singular" );

        addLabel.Text = $"{addNew} {objName}";
    }

    /* Event Callbacks */

    // User tapped '+ Add New Foo' footer
    private void OnAddTapped( object sender, MR.Gestures.TapEventArgs args )
	{
		addLayout.BackgroundColor = TapColor;

        // Briefly show selection
        DXTimer.Delay( TapDelay, () =>
        {
            // Reset
            addLayout.BackgroundColor = DefaultColor;
            IsDropDownOpen = false;

            // Callback listener
            AddTapped?.Invoke();
        });
	}

    /* Inner Class */

    /*
     * Dummy class allowing empty row to be added to DXAddSelector. Supports dropdown menu opening to display footer for
     * adding new objects.
     */
    private class DXEmptyModel : DXModel
    {
        /* Properties */
        public override string ObjectName => string.Empty;
    }
}

//
