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

using DXLib.UI;
using DXLib.UI.Alert;
using DXLib.UI.Layout;
using DXLib.UI.Form.Message;

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

using DXLib.Data;
using DXLib.UI.Form;
using DXLib.Utils;

namespace iStatVball3;

/*
 * Displays 'Create New Account' screen and handles all data input and validation for the screen. 
 */ 
public class LaunchCreate : LaunchPage
{
	/* Fields */
	private readonly DXGridLayout outerLayout;
	private readonly DXVerticalLayout innerLayout;

	private readonly LaunchCreateForm form;

	private readonly DXIcon titleIcon;
	private readonly DXLabel titleLbl;
	private readonly DXLabel legalLbl;
	private readonly DXButton createBtn;

	/* Methods */
	public LaunchCreate()
	{
		BackgroundColor = DXColors.Dark1;

		Padding = 0;
		Margin = 0;

		Horizontal = LayoutOptions.Fill;
		Vertical = LayoutOptions.Fill;
		
		// Main layout
		outerLayout = new DXGridLayout
		{
			BackgroundColor = DXColors.Dark1,
			
			Padding = 0,
			Margin = 0,
			
			RowSpacing = 0,
			ColumnSpacing = 0,
			
			Horizontal = LayoutOptions.Fill,
			Vertical = LayoutOptions.Fill
		};

		// Centers everything within main layout
		innerLayout = new DXVerticalLayout
		{
			BackgroundColor = DXColors.Dark1,
			
			Horizontal = LayoutOptions.Center,
			Vertical = LayoutOptions.Center,
		};

		// 'Create Account'
		DXHorizontalLayout titleLayout = new()
		{
			Spacing = 15,

			Margin = new Thickness( 0, 0, 0, 20 ),
			
			Horizontal = LayoutOptions.Center,
			Vertical = LayoutOptions.Center
		};

		titleIcon = new DXIcon
		{
			Resource = "add_circle",
			Color = DXColors.Light4,

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

		titleLayout.Add( titleIcon );

		string title = DXString.Get( "create.title" );

		titleLbl = new DXLabel
		{
			Text = title,
			TextColor = DXColors.Light4,

			Font = DXFonts.Roboto,

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

		titleLayout.Add( titleLbl );

		innerLayout.Add( titleLayout );

		// Data fields
		form = new LaunchCreateForm
		{
			Margin = new Thickness( 0, -25, 0, 0 ),

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

		innerLayout.Add( form );

		// 'By tapping Create Account, you agree to...'
		legalLbl = new DXLabel
		{
			Text = DXString.Get( "create.legal" ),
			TextColor = DXColors.Light4,

			Font = DXFonts.Roboto,
			FontSize = 14,

			Horizontal = LayoutOptions.Center
		};

		innerLayout.Add( legalLbl );

		// '<Terms> and <Privacy Policy>'
		DXHorizontalLayout legalLayout = new()
		{
			Spacing = 5,
			Horizontal = LayoutOptions.Center
		};

		DXTextButton termsBtn = new()
		{
			Text = DXString.Get( "create.terms" ),
			Color = DXColors.Action,

			Font = DXFonts.Roboto,
			FontSize = 14,

			ButtonTapped = OnTermsTapped
		};

		DXLabel andLbl = new()
		{
			Text = DXString.Get( "create.and" ),
			TextColor = DXColors.Light4,

			Font = DXFonts.Roboto,
			FontSize = 14
		};

		DXTextButton privacyBtn = new()
		{
			Text = DXString.Get( "create.privacy" ),
			Color = DXColors.Action,

			Font = DXFonts.Roboto,
			FontSize = 14,

			ButtonTapped = OnPrivacyTapped
		};

		legalLayout.Add( termsBtn );
		legalLayout.Add( andLbl );
		legalLayout.Add( privacyBtn );

		innerLayout.Add( legalLayout );

		// 'Create Account'
		createBtn = new DXButton
		{
			Resource = "create.title",
			Type = DXButton.ButtonType.Positive,

			ButtonWd = 230,
			ButtonHt = 48,

			Horizontal = LayoutOptions.Center,
			ButtonTapped = OnCreateTapped,
			
			IsDisabled = true
		};
		
		createBtn.Init();
		
		innerLayout.Add( createBtn );
		outerLayout.Add( innerLayout, 1, 0 );

		Content = outerLayout;

		// Update appbar
		Shell.Instance.AppBar.Title = title;

		// Start listening for control changes
		Start();
	}
	
	/* Event Callbacks */

	// Start remote account creation process
	private async void OnCreateTapped( object sender )
	{
		// Validate connection
		if ( DXData.HasConnection() )
		{
			DXSpinner.Start();

			createBtn.IsDisabled = true;

			// Hide keyboard before leaving screen
			await form.HideKeyboard();
			
			string username = form.Username;
			string password = form.Password;

			// Wait until callback
			DXAuth.CreateAccount( username, password, OnCreateCompleted );
		}
		else
		{
			DXAlert.ShowNetworkError( "net.err.account" );
		}
	}

	// Account creation complete, either successfully or with error
	private async void OnCreateCompleted( DXAuth.AuthResult result, string resultStr )
	{
		switch ( result )
		{
			// Success
			case DXAuth.AuthResult.Success:
			{
				Settings settings = new();

				// Once only at creation
				settings.SetDefaults();

				string role = form.Role;

				// New billing automatically grants requested access
				Permission.LevelType level = Permission.LevelFromRole( role );

				// Persist new user
				User user = new()
				{
					Version = User.DataVersion,

					Username = form.Username.ToLower(),
					FirstName = form.FirstName,
					LastName = form.LastName,

					Role = role,
					LevelEnum = (int)level,

					IsAdmin = false,
					AuthId = resultStr,

					Settings = settings
				};

				await user.Create();

				// Grant permissions for any pending invites
				await Permission.Grant( user, level );

				DXAlert.ShowOk( "create.title", "create.success", OnSuccessConfirmed );
				break; 
			}
			// Already exists
			case DXAuth.AuthResult.ErrorExists:
			{
				DXAlert.ShowError( "create.err", "create.err.exists", resultStr );
				break;
			}
			// Timeout
			case DXAuth.AuthResult.ErrorTimeout:
			{
				DXAlert.ShowError( "create.err", "create.err.timeout" );
				break;
			}
			// Unknown error
			default:
			{
				DXAlert.ShowError( "create.err", "create.err.unknown", resultStr );
				break;
			}
		}

		createBtn.IsDisabled = false;

		DXSpinner.Stop();
	}

	// Proceed to login screen
	private void OnSuccessConfirmed()
	{
		Stop();

		LaunchStack launch = Shell.Instance.LaunchStack;

		// Make back button return to landing
		launch.Pop( false );
		launch.Push( new LaunchLogin( form.Username ) );
	}

	// Opens T&Cs in external browser
	private static async void OnTermsTapped( object data )
	{
		Uri uri = new( "https://www.istatvball.com/terms" );

		await Browser.OpenAsync( uri, BrowserLaunchMode.SystemPreferred );
	}

	// Opens privacy policy in external browser
	private static async void OnPrivacyTapped( object data )
	{
		Uri uri = new( "https://www.istatvball.com/privacy" );

		await Browser.OpenAsync( uri, BrowserLaunchMode.SystemPreferred );
	}

	// Create button disabled if any fields not valid
	protected override void OnControlChanged( object sender, DXFormChangedMessage msg )
	{
		form.ValidatePasswords( msg.Value as DXFormControl );
		
		createBtn.IsDisabled = !form.IsValid();
	}

	/* Layout */

	// Layout specific to device size/orientation
	public override void UpdateLayout( LayoutType type )
	{
		outerLayout.Clear();

		// Default sizing
		outerLayout.Padding = 0; 
		innerLayout.Spacing = 24;

		titleIcon.Size = 36;
		titleLbl.FontSize = 36;

		legalLbl.Margin = new Thickness( 0, 0, 0, -20 );

		createBtn.WidthRequest = 190;
		createBtn.HeightRequest = 48;

		// Size specific layouts
		base.UpdateLayout( type );

		// Update children
		form.UpdateLayout( type );

		Shell.Instance.AppBar.UpdateLayout( type );
	}

	// Landscape
	protected override void Landscape()
	{
		outerLayout.AddStarColumn( 10 );
		outerLayout.AddStarColumn( 80 );
		outerLayout.AddStarColumn( 10 );
	}

	// Portrait
	protected override void Portrait()
	{
		outerLayout.AddStarColumn( 20 );
		outerLayout.AddStarColumn( 60 );
		outerLayout.AddStarColumn( 20 );
	}
	
	// Mobile landscape
	protected override void MobileLandscape()
	{
		Padding = BasePad;

		innerLayout.Spacing = 16;

		titleIcon.Size = 28;
		titleLbl.FontSize = 28;

		legalLbl.Margin = new Thickness( 0, 0, 0, -12 );

		createBtn.WidthRequest = 174;
		createBtn.HeightRequest = 42;

		outerLayout.AddFixedColumn( 5 );
		outerLayout.AddStarColumn();
		outerLayout.AddFixedColumn( 5 );
	}

	// Mobile portrait
	protected override void MobilePortrait()
	{
		Padding = new Thickness( BasePad, (BasePad * 2), BasePad, BasePad );
		
		innerLayout.Spacing = 16;

		titleIcon.Size = 28;
		titleLbl.FontSize = 28;

		legalLbl.Margin = new Thickness( 0, 0, 0, -12 );

		createBtn.WidthRequest = 174;
		createBtn.HeightRequest = 42;

		outerLayout.AddFixedColumn( 5 );
		outerLayout.AddStarColumn();
		outerLayout.AddFixedColumn( 5 );
	}
}

//
