/* 
 * 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.Layout;
using DXLib.UI.Container;

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

using DXLib.UI.Form;
using DXLib.UI.Form.Control;

using DXLib.Utils;

namespace DXLib.UI.Alert;

/*
 * Displays a modal OK/Cancel popup with a text entry field. The text field supports email, password, or plain text
 * entry. A callback handler will be called when the OK or Cancel buttons are tapped.
 */
public static class DXInputAlert
{
	/* Fields */
	private static SfPopup popup;

	private static DXLabel headerLbl;
	private static DXLabel msgLbl;
	private static DXTextField textField;

	private static DXButton okBtn;
	private static DXButton cancelBtn;

	private static Action<string> okAction;
	private static Action cancelAction;

	/* Methods */

	// Shows input alert with an email address text field
	public static void ShowEmail( string title, string msg, string email, Action<string> action, Action cancel = null )
	{
		Show( DXTextField.TextType.Email, DXFormControl.HintType.Email, title, msg, null, email, 5, 320, action, cancel );
	}

	// Shows input alert for plain text field
	public static void ShowText( string title, string msg, string field, string text, Action<string> action, Action cancel = null )
	{
		Show( DXTextField.TextType.CapitalizeWords, DXFormControl.HintType.RequiredRange, title, msg, field, text, 1, 64, action, cancel );
	}

	// Shows all alert types without resource lookup
	private static void Show( DXTextField.TextType type, DXFormControl.HintType hintType, string title, string msg, string field, string text, int min, int max, Action<string> action, Action cancel = null )
	{
		// Lazily instantiate cached popup
		if ( popup == null )
		{
			popup = new SfPopup();

			Init();
		}

		// Set title
		headerLbl.Text = DXString.Get( title );

		// Set message
		msgLbl.Text = DXString.Get( msg );

		// Config textfield
		textField.SetTitle( field, false );
		textField.Text = text;

		textField.MinLength = min;
		textField.MaxLength = max;

		textField.Type = type;
		textField.Hint = hintType;

		textField.UpdateState( true );

		// Save event callbacks
		okAction = action;
		cancelAction = cancel;

		// Set initial state
		UpdateOk();

		// Display
		popup.Show();
	}

	// Performs all one-time only setup
	private static void Init()
	{
		bool ios = DXDevice.IsIOS;

		popup.Background = DXColors.Light4;

		// Modal
		popup.StaysOpen = true;

		popup.AutoSizeMode = PopupAutoSizeMode.Both;
		popup.AnimationMode = PopupAnimationMode.None;

		// Configure popup
		popup.ShowHeader = true;
		popup.ShowFooter = true;
		
		PopupStyle style = popup.PopupStyle;

		style.CornerRadius = 4;
		style.StrokeThickness = 0;

		double wd = DXDevice.IsTablet ? 360 : 340;
		const int headerHt = 55;
		
		// Header
		DXContent headerView = new()
		{
			Padding = new Thickness( 17, 0, 15, 0 ),
			BackgroundColor = DXColors.Light4,

			WidthRequest = wd,
			HeightRequest = headerHt,
			
			Horizontal = LayoutOptions.Fill,
			Vertical = LayoutOptions.Fill
		};

		headerLbl = new DXLabel
		{
			TextColor = DXColors.Dark1,
			Font = DXFonts.RobotoBold,
			FontSize = 20,

			LineBreakMode = LineBreakMode.NoWrap,
			VerticalTextAlignment = TextAlignment.Center,

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

		headerView.Content = headerLbl;

		popup.ShowHeader = true;
		popup.HeaderHeight = headerHt;
		
		popup.HeaderTemplate = new DataTemplate( () => headerView );

		// Body layout
		DXVerticalLayout bodyLayout = new()
		{
			Padding = new Thickness( 17, 0, 17, 15 ),
			BackgroundColor = DXColors.Light4,

			Spacing = ios ? 10 : 0,

			WidthRequest = wd,
			HeightRequest = 150,
			
			Horizontal = LayoutOptions.Fill,
			Vertical = LayoutOptions.Fill
		};

		// Message
		msgLbl = new DXLabel
		{
			TextColor = DXColors.Dark1,
			Font = DXFonts.Roboto,
			FontSize = 17,

			LineBreakMode = LineBreakMode.WordWrap
		};

		bodyLayout.Add( msgLbl );

		// Textfield
		textField = new DXTextField
		{
			IsRequired = true,
			Margin = 0,

			TextChanged = OnTextChanged
		};

		textField.Init();
		
		bodyLayout.Add( textField );

		popup.ContentTemplate = new DataTemplate( () => bodyLayout );

		const int footerHt = 56;
		
		// Footer
		DXGridLayout footerView = new()
		{
			BackgroundColor = DXColors.Light4,
			
			ColumnSpacing = 10,
			HeightRequest = footerHt,

			Horizontal = LayoutOptions.Fill,
			Vertical = LayoutOptions.Fill
		};

		footerView.AddStarColumn();
		footerView.AddAutoColumn();
		footerView.AddFixedColumn( 5 );

		// Cancel
		cancelBtn = new DXButton
		{
			Resource = "alert.cancel",
			Type = DXButton.ButtonType.Neutral,

			ButtonWd = 80,

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

		cancelBtn.Init();
		
		// OK
		okBtn = new DXButton
		{
			Resource = "alert.ok",
			Type = DXButton.ButtonType.Positive,

			Horizontal = LayoutOptions.End,
			Vertical = LayoutOptions.Center,

			IsDisabled = true
		};

		okBtn.Init();
		
		footerView.Add( cancelBtn, 0, 0 );
		footerView.Add( okBtn, 1, 0 );

		popup.FooterHeight = footerHt;
		popup.FooterTemplate = new DataTemplate( () => footerView );

		// Register for events
		cancelBtn.ButtonTapped += OnCancelTapped;
		okBtn.ButtonTapped += OnOkTapped;
	}

	// Updates OK button disabled state based on input validity
	private static void UpdateOk()
    {
        okBtn.IsDisabled = !textField.IsValid();
    }

    /* Event Callbacks */

    // Cancel tapped
    private static void OnCancelTapped( object sender )
	{
		popup.IsOpen = false;

		cancelAction?.Invoke();
	}

	// OK tapped
	private static void OnOkTapped( object sender)
	{
		popup.IsOpen = false;

		okAction?.Invoke( textField.Text );
	}

	// OK button only enabled with valid text entry
	private static void OnTextChanged()
	{
		UpdateOk();
	}
}

//
