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

using Syncfusion.Maui.ListView;

using DXLib.UI;
using DXLib.UI.Form;
using DXLib.UI.Container;

namespace iStatVball3;

/*
 * Implements a list for displaying and selecting custom reports. Reports are edited via tapping an item in the list.
 * The list can be reordered using drag 'n drop. Items can be deleted by swiping left.
 */
public class CustomList : DXContent
{
	/* Constants */
	private const double ItemHt = 60;
	private const double Pad = 1;

	/* Events */
	public Action Reordered { get; set; }
	public Action Cancelled { get; set; }

	public Action<CustomReport,bool> Completed { get; set; }
	public Action<CustomReport> Deleted { get; set; }

	/* Properties */
	public CustomConfig Config { get; set; }

	// Current selection
	public CustomReport Selected { get => list.SelectedItem as CustomReport;
								   set => list.SelectedItem = value; }
	// Visual state
	public bool IsDisabled { set => SetDisabled( value ); }

	/* Fields */
	private SfListView list;

	// External ref
	private readonly CustomControl control;

	// Item pending deletion
	private CustomReport deleteReport;

	/* Methods */
	public CustomList( CustomControl control )
	{
		this.control = control;
		
		Horizontal = LayoutOptions.Fill;
		Vertical = LayoutOptions.Start;
		
		BackgroundColor = DXColors.Light1;

		// Create underlying control
		CreateList();
	}

	// Creates and configures underlying list control
	private void CreateList()
	{
		// (Re)create list
		list = new SfListView()
		{
			Background = DXColors.Light1,

			// Vertical, fixed sized rows
			Orientation = ItemsLayoutOrientation.Vertical,
			AutoFitMode = AutoFitMode.None,
			LoadMoreOption = LoadMoreOption.None,

			ItemSize = ItemHt,
			ItemSpacing = Pad,

			// Scrollable
			IsScrollingEnabled = true,
			ScrollBarVisibility = ScrollBarVisibility.Default,

			// Single select
			SelectionMode = Syncfusion.Maui.ListView.SelectionMode.Single,
			SelectionGesture = TouchGesture.Tap,
			SelectionBackground = DXColors.Action,

			// Drag 'n drop reordering
			DragStartMode = DragStartMode.OnHold,

			// Swipe left to delete
			AllowSwiping = true,
			SwipeOffset = ItemHt,
			SwipeThreshold = (ItemHt / 2),

			EndSwipeTemplate = new DataTemplate( () => new CustomListDelete() { Deleted = OnItemDeleted } ),

			// Layout templates
			ItemTemplate = new DataTemplate( () => new CustomListTemplate() ),
			SelectedItemTemplate = new DataTemplate( () => new CustomListTemplate( true ) )
		};

		// Drag 'n drop config
		AutoScroller scroller = list.AutoScroller;

		if ( scroller != null )
		{
			scroller.ScrollMargin = 15;
			scroller.Interval = TimeSpan.FromMilliseconds( 150 );
			scroller.AllowOutsideScroll = true;
		}

		if ( list.DragDropController != null )
		{
			list.DragDropController.UpdateSource = true;
		}

		// Listen for events
		list.SelectionChanged += OnSelectionChanged;
		list.ItemDragging += OnItemDragging;

		list.SwipeEnded += OnSwipeEnded;
		list.SwipeReset += OnSwipeReset;

		Content = list;
	}

	// Visually enables/disables list control
	private void SetDisabled( bool disabled )
	{
		list.IsEnabled = !disabled;
		list.Opacity = disabled ? DXFormControl.DisabledOpacity : 1.0;
	}

	/* Items */

	// Returns underlying report list in current ordering
	public List<CustomReport> GetItems()
	{
		return list.ItemsSource as List<CustomReport>;
	}

	// Sets list of custom reports to be displayed
	public void SetItems( IList<CustomReport> items )
	{
		// MUST recreate list each time to see edits
		CreateList();

		// Update underlying data
		list.ItemsSource = items;
	}

	/* Event Callbacks */

	// User tapped list item
	private void OnSelectionChanged( object sender, ItemSelectionChangedEventArgs args )
	{
		if ( args.AddedItems != null )
		{
			CustomReport report = args.AddedItems[0] as CustomReport;

			// Create edit form
			CustomListForm form = new( control, report )
			{
				Config = Config,

				Completed = Completed,
				Cancelled = Cancelled
			};

			form.Init();

			// Show modal popup centered on screen
			form.Show();
		}
	}

	// User dragging item, notify listener when dropped
	private void OnItemDragging( object sender, ItemDraggingEventArgs args )
	{
		if ( args.Action == DragAction.Drop )
		{
			Reordered?.Invoke();
		}
	}

	// User finished swipe motion
	private void OnSwipeEnded( object sender, Syncfusion.Maui.ListView.SwipeEndedEventArgs args )
	{
		// Swiped left, item pending delete
		if ( args.Direction == SwipeDirection.Left )
		{
			deleteReport = args.DataItem as CustomReport;
		}
		// Swiped right, cancel delete
		else
		{
			list.ResetSwipeItem();
		}
	}

	// Swipe to delete cancelled
	private void OnSwipeReset( object sender, ResetSwipeEventArgs args )
	{
		deleteReport = null;
	}

	// User tapped delete after swiping, notifiy listener
	private void OnItemDeleted()
	{
		if ( deleteReport != null )
		{
			Deleted?.Invoke( deleteReport );
		}
	}
}

//
