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

using System.Reflection;
using Syncfusion.Maui.Popup;

using DXLib.UI.Layout;
using DXLib.UI.Control;
using DXLib.UI.Control.Button;

using DXLib.Utils;

namespace DXLib.UI.Container;

/*
 * Used to implement a tool drawer that slides in/out from the right-hand side of the screen. The drawer has a header
 * and content area. Supports advancing to a second content view within the drawer and then returning to the first view.
 */
public class DXDrawer : SfPopup
{
	/* Constants */
	public static readonly Color FillColor = DXColors.Light2;
	
	// Sizing
	private const double DefaultWd = 320;
	private const int DefaultHeaderHt = 56;

	// Slide in/out animation duration
	private const int Duration = 667;
	
	/* Events */
	private Action Dismissed { get; set; }

	/* Properties */
	private string Title { set => titleLbl.Text = DXString.Get( value ); }
	private View View { set => viewContent.Content = value; }

	// Custom sizing
	public double DrawerWd { set => WidthRequest = value; }

	/* Fields */
	private View popupOverlayView;

	// UI components
	private DXIconButton actionBtn;
	private DXLabel titleLbl;
	private readonly DXContent viewContent;

	// Primary view
	private string firstTitle;
	private View firstView;
	private Action firstCallback;

	/* Methods */
	public DXDrawer()
	{
		Padding = 0;
		Margin = 0;

		Background = DXColors.Light2;
		
		// Modal with translucent overlay
		StaysOpen = true;
		ShowOverlayAlways = true;
		IgnoreActionBar = true;

		// Configure popup
		ShowFooter = false;
		ShowCloseButton = false;

		// Slide in/out
		AnimationMode = PopupAnimationMode.SlideOnRight;
		AnimationEasing = PopupAnimationEasing.SinIn;
		AnimationDuration = Duration;

		PopupStyle style = PopupStyle;

		// Style
		style.CornerRadius = 0;
		style.HasShadow = false;
		style.StrokeThickness = 0;

		style.HeaderBackground = DXColors.Light2;
		style.FooterBackground = DXColors.Light2;
		
		// Sizing
		double ht = (DXDevice.GetScreenHt() - DXDevice.GetSafeTop());

		WidthRequest = DefaultWd;
		HeightRequest = ht;
		
		HeaderHeight = DefaultHeaderHt;
		
		// Header
		DXGridLayout header = CreateHeader( string.Empty );
		HeaderTemplate = new DataTemplate( () => header );

		// View
		viewContent = new DXContent();
		ContentTemplate = new DataTemplate( () => viewContent );

		// Listen for events
		Opening += OnOpening;
	}

	// Sets first view title
	public void SetTitle( string title )
	{
		firstTitle = title;
		
		Title = firstTitle;
	}

	// Sets first view content
	public void SetView( View view )
	{
		firstView = view;
		
		View = firstView;
	}

	// Sets first view action callback
	public void SetCallback( Action callback )
	{
		firstCallback = callback;

		Dismissed = callback;
	}

	// Slides drawer in to screen from right
	public void Show()
	{
		double x = (DXDevice.GetScreenWd() - WidthRequest);

		Show( x, -40 );//0 );
	}

	// Slides drawer out of screen from right
	public void Hide()
	{
		IsOpen = false;
	}
	
	// Advances to specified second view
	public void Next( string title, View view, Action callback )
	{
		Title = title;
		View = view;
		Dismissed = callback;

		actionBtn.Resource = "back";
	}

	// Returns to previous (first) view
	public void Previous()
	{
		Title = firstTitle;
		View = firstView;
		Dismissed = firstCallback;
		
		actionBtn.Resource = "close";
	}

	// Creates header layout with specified title
	private DXGridLayout CreateHeader( string title )
	{
		bool ios = DXDevice.IsIOS;
		
		// Header contains action button and title
		DXGridLayout headerLayout = new()
		{
			BackgroundColor = FillColor,

			Padding = new Thickness( 20, 0 ),
			ColumnSpacing = 16,
			
			Horizontal = LayoutOptions.Fill,
			Vertical = LayoutOptions.Fill
		};

		headerLayout.AddFixedColumn( 26 );
		headerLayout.AddStarColumn();

		// Close/Back
		actionBtn = new DXIconButton
		{
			Margin = 0,
			Padding = 0,
			
			Resource = "close",
			IconColor = DXColors.Dark1,
			Size = 26,

			Horizontal = LayoutOptions.Start,
			Vertical = LayoutOptions.Center,

			ButtonTapped = OnActionTapped
		};

		headerLayout.Add( actionBtn, 0, 0 );

		// Title
		titleLbl = new DXLabel
		{
			Margin = new Thickness( 0, (ios ? 0 : -3), 0, 0 ),
			Padding = 0,
			
			Resource = title,
			
			Font = DXFonts.Roboto,
			FontSize = 24,
			TextColor = DXColors.Dark1,

			VAlign = TextAlignment.Center,

			Horizontal = LayoutOptions.Start,
			Vertical = LayoutOptions.Center
		};

		headerLayout.Add( titleLbl, 1, 0 );
		
		return headerLayout;
	}

	/* Event Callbacks */

	// User tapped close/return button
	private void OnActionTapped()
	{
		Dismissed?.Invoke();
	}
	
	// Syncfusion boilerplate to override fade animation
	private void OnOpening( object sender, System.ComponentModel.CancelEventArgs e )
	{
		FieldInfo propertyInfo = GetType().GetField( "PopupOverlayContainer", BindingFlags.NonPublic | BindingFlags.Instance );

		popupOverlayView = propertyInfo?.GetValue( this ) as View;

		if ( popupOverlayView != null )
		{
			popupOverlayView.PropertyChanged += OnPropertyChanged;
		}
	} 

	// Syncfusion boilerplate to override fade animation
	private void OnPropertyChanged( object sender, System.ComponentModel.PropertyChangedEventArgs args )
	{
		if ( args.PropertyName == "Opacity" )
		{
			popupOverlayView.Opacity = 1;
		}
	}	
}

//
