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

using DXLib.UI.Card;
using DXLib.UI.Alert;
using DXLib.UI.Control;

using DXLib.Data;
using DXLib.Utils;

namespace iStatVball3;

/*
 * Card page for list of sets within a parent match.
 */
public class SetPage : CardPage
{
	/* Fields */
	private Set cardSet;

	/* Methods */
	public SetPage( Match match ) : base( match )
	{
		Title = DXString.Get( "set.plural" );
		ScrollPosition = ScrollToPosition.Start;
	}

	/* Abstracts */

	// Displays all set cards
	public override void LoadCards()
	{
		Clear();

		// Required for permissions
		User user = Shell.CurrentUser;

		if ( data is Match match )
		{
			// Add card for each set
			foreach ( Set set in match.Sets )
			{
				SetCard card = new( set )
				{
					ShowSpinner = false,
					HasAnalyze = true,

					IsEditEnabled = Set.CanEdit( user ),
					IsAnalyzeEnabled = set.CanAnalyze( user ) && !set.IsNew,
					IsTappable = false,

					AnalyzeTapped = OnAnalyzeTapped,
					EditTapped = OnEditTapped,

					RecordTapped = OnRecordTapped
				};

				card.Init();
				
				AddCard( card );
			}

			// New set only valid between sets and up to 5
			if ( Set.CanCreate( match, user ) )
			{
				if ( !match.IsEnded && !match.SetInProgress() && !match.HasMaxSets )
				{
					AddNewCard( "set", CardSmall.CardHt );
				}
			}
		}
	}

	/* Event Callbacks */

	// Called back when 'Add New' tapped
	protected override void OnNewCardTapped( DXCard card )
	{
		if ( data is Match match )
		{
			// Must have roster created
			if ( match.Season.Players.Count >= Lineup.BaseEntries )
			{
				// Only show set info mode
				SetForm form = new( null, match );

				Shell.Instance.ShowForm( form );
			}
			else
			{
				DXAlert.ShowError( "set.singular", "set.err.roster", DXSpinner.Stop );
			}
		}
	}

	// Called back when card analyze button tapped
	private static async void OnAnalyzeTapped( DXCard card )
	{
		if ( card.Data is Set set )
		{
			Match match = set.Match;
			Season season = match.Season;
		
			Shell shell = Shell.Instance;
		
			// Init dashboard with aggregated data
			shell.DashboardForm.Init( new DashboardConfig
			{
				Scope = DataConfig.SetScope,
				ScopeName = set.Name,
				ScopeObject = set,
		
				Organization = season.Team.Organization,
		
				Team1 = match.Team1,
				Team2 = match.Opponent
			});
		
			bool sync = DXData.HasConnection() && set.IsInProgress && !Shell.CurrentUser.IsRecording;
		
			// Show with optional sync button
			await shell.ShowDashboardForm( set.Name, sync );
		}
	}

	// Called back when card edit button tapped
	private static void OnEditTapped( DXCard card )
	{
		if ( card.Data is Set set )
		{
			// Set has special edit form
			SetEditForm form = new();
			form.Init( set );

			// Open in set info mode
			Shell.Instance.ShowForm( form );
		}
	}

	// User started/resumed recording
	private void OnRecordTapped( DXCard card )
	{
		cardSet = card.Data as Set;

		// Cannot change engines once set started
		if ( (cardSet != null) && cardSet.Legacy == Shell.IsLegacy )
		{
			// Record UI is read-only if org locked
			if ( DXCard.GlobalLock )
			{
				DXAlert.ShowOk( "record.sample", "record.sample.msg", OnRecordConfirmed );
			}
			else
			{
				// RallySync requires tablet
				if ( cardSet.IsRallySynced && DXDevice.IsMobile )
				{
					DXAlert.ShowNeutral( "video.rally", "video.rally.mobile", () => OnError( card ) );
				}
				// OK to proceed
				else
				{
					OnRecordConfirmed();
				}
			}
		}
		else
		{
			DXAlert.ShowError( "record.err.engine", () => OnError( card ) );
		}
	}

	// User confirmed recording UI launch
	private async void OnRecordConfirmed()
	{
		if ( data is Match match )
		{
			Shell shell = Shell.Instance;

			// RallySync (video)
			if ( match.IsRallySynced )
			{
				SyncTool syncTool = new( cardSet );
				
				await shell.ShowTool( syncTool, true );
			}
			// Normal
			else
			{
				await shell.ShowRecordForm( cardSet );
			}
		}
	}

	// User acknowledged start/resume error
	private static void OnError( DXCard card )
	{
		DXSpinner.Stop();
		card.Reset();
	}
	
	/* Layout */

	// Resets tap state of all cards
	public override void UpdateLayout( LayoutType type )
	{
		base.UpdateLayout( type );

		Reset();
	}
}

//
