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

using Syncfusion.Maui.Popup;

using DXLib.UI.Control;
using DXLib.Utils;

namespace DXLib.UI.Container;

/*
 * Displays a modal popup anchored to a view. The body content of the popup can be specified dynamically. A title header
 * can optionally also be specified with optional custom styling.
 */
public class DXPopup : SfPopup
{
	/* Constants */
	public const double DefaultHeaderHt = 30;
	public static readonly Color DefaultHeaderColor = DXColors.Light2;

	// Default header styling
	private static readonly DXPopupHeaderStyle DefaultHeaderStyle = new()
	{
		Height = DefaultHeaderHt,
		Color = DXColors.Light2,
		TextColor = DXColors.Dark1,
		FontSize = 17,
		Font = DXFonts.Roboto,
		Alignment = TextAlignment.Start
	};
	
	/* Events */
	public Action PopupClosed { get; set; }

	/* Properties */
	public string Title { set => SetTitle( value ); }
	public Color Color { set { PopupStyle.PopupBackground = value; BackgroundColor = value; } }

	// Custom title style
	public DXPopupHeaderStyle HeaderStyle { get; set; }

	// Show in modal mode?
	public bool IsModal { set => StaysOpen = value; }

	// Dynamic sizing
	public double ViewWidth { get => WidthRequest; set => WidthRequest = value; }
	public double ViewHeight { get => HeightRequest; set => HeightRequest = (value + (ShowHeader ? HeaderHt : 0)); }

	public bool AutoSize { set => AutoSizeMode = value ? PopupAutoSizeMode.Both : PopupAutoSizeMode.None; }
	public double MaxHeight { set => MaximumHeightRequest = value; }
	
	private double HeaderHt => HeaderStyle?.Height ?? DefaultHeaderStyle.Height;

	/* Methods */

	// Creates popup with no title and view to be set later
	public DXPopup() : this( null, null )
	{}

	// Creates popup with no title and specified view
	public DXPopup( View view ) : this( null, view )
	{}

	// Creates popup with specified title resource and view
	public DXPopup( string resource, View view )
	{
		Padding = DXDevice.SafeArea();
		Margin = 0;
		
		ShowOverlayAlways = false;

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

		// Quick fade animation in/out
		AnimationMode = PopupAnimationMode.Fade;
		AnimationEasing = PopupAnimationEasing.SinIn;
		AnimationDuration = 150;
		
		PopupStyle style = PopupStyle;

		// Style
		style.CornerRadius = 4;
		style.HasShadow = true;
		style.StrokeThickness = 1;
		style.Stroke = DXColors.Dark3;

		Color = DXColors.Light4;

		string title = DXString.Get( resource );
		
		// Header optional
		SetTitle( title );

		// Always has content
		SetContent( view );

		// Listen for events
		Closed += OnClosed;
	}

	/* Set */

	// Sets optional header title, null for no title (RAW STRING)
	public void SetTitle( string value )
	{
		bool hasHeader = (value != null);

		ShowHeader = hasHeader;

		// Optional header
		if ( hasHeader )
		{
			DXPopupHeaderStyle style = HeaderStyle ?? DefaultHeaderStyle;

			// Custom template to workaround text alignment bug
			DXLabel headerLbl = new()
			{
				Text = $"{value} ",
				TextColor = style.TextColor,

				Font = style.Font,
				FontSize = style.FontSize,

				HAlign = style.Alignment,
				VAlign = TextAlignment.Center,

				Padding = DXUtils.Left( (style.Alignment == TextAlignment.Start) ? 10 : 0 ),

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

			PopupStyle.HeaderBackground = style.Color;

			HeaderHeight = (int)style.Height;
			HeaderTemplate = new DataTemplate( () => headerLbl );
		}
	}

	// Sets popup body content
	public void SetContent( View view )
	{
		if ( view != null )
		{
			ContentTemplate = new DataTemplate( () => view );
		}
	}

	/* Show/Hide */

	// Displays popup anchored to center of specified view (with optional x,y adjustment)
	public virtual void ShowFromView( View view, double adjustX = 0, double adjustY = 0, bool forceLeft = false )
	{
		double x = (view.Width / 2);
		double y = (view.Height / 2);

		x += adjustX;
		y += adjustY;

		// WORKAROUND: MAUI bottom safe area issue
		PopupRelativePosition position = DXDevice.HasSafeArea ? (forceLeft ?  PopupRelativePosition.AlignToLeftOf : PopupRelativePosition.AlignToRightOf) : PopupRelativePosition.AlignBottomRight;
		
		ShowRelativeToView( view, position, -x, -y );
	}

	// Manually closes the popup
	public void Hide()
	{
		IsOpen = false;		// Do NOT use Dismiss()
	}
	
	/* Event Callbacks */

	// Callback registered listener
	protected virtual void OnClosed( object sender, EventArgs args )
	{
		PopupClosed?.Invoke();
	}
}

/*
 * Internal class used to encapsulate properties for configuring popup custom header title styling.
 */
public class DXPopupHeaderStyle
{
	/* Properties */
	public double Height { get; init; }

	// Colors
	public Color Color { get; init; }
	public Color TextColor { get; init; }

	// Font
	public string Font { get; init; }
	public double FontSize { get; init; }

	public TextAlignment Alignment { get; init; }
}

//
