/*
 * 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;

/*
 * Layout for the Season Home page. This page differs from a standard card page in that cards are not all the same size
 * and are not organized in a regular grid pattern. Home page data always pertains to 1 season only.
 */ 
public class HomePage : DXCardPage
{
	/* Fields */

	// Cards
	private readonly HomeCardLarge roster;
	private readonly HomeCardLarge lineups;

	private readonly HomeCardMedium matches;
	private readonly HomeCardMedium tournaments;

	private readonly HomeCardSmall coaches;
	private readonly HomeCardSmall statisticians;
	private readonly HomeCardSmall opponents;
	private readonly HomeCardSmall venues;

	// Parent
	private readonly Season homeSeason;
	private readonly string homeName;

	/* Methods */
	public HomePage( Season season ) : base( season )
	{
		homeSeason = season;

		Title = DXString.Get( "home.title" );
		homeName = Title;

		/* Large Cards */

		// Roster
		roster = new HomeCardLarge
		{
			DefaultIcon = "team",
			ImageColor = season.Color,

			Type = CardGrid.GridType.Roster,
			Title = DXString.Get( "home.roster" ),

			CardTapped = OnRosterTapped
		};

		roster.Init();
		cards.Add( roster );

		// Lineups
		lineups = new HomeCardLarge
		{
			DefaultIcon = "lineup",
			ImageColor = season.Color,

			Type = CardGrid.GridType.Lineup,
			Title = DXString.Get( "lineup.plural" ),

			CardTapped = OnLineupsTapped
		};

		lineups.Init();
		cards.Add( lineups );

		/* Medium Cards */

		// Matches
		matches = new HomeCardMedium
		{
			DefaultIcon = "season",
			ImageColor = season.Color,

			Title = DXString.Get( "match.plural" ),
			CardTapped = OnMatchesTapped
		};

		matches.Init();
		cards.Add( matches );

		// Tournaments
		tournaments = new HomeCardMedium
		{
			DefaultIcon = "tournament",
			ImageColor = season.Color,

			Title = DXString.Get( "tournament.plural" ),
			CardTapped = OnTournamentsTapped
		};

		tournaments.Init();
		cards.Add( tournaments );

		/* Small Cards */

		// Coaches
		coaches = new HomeCardSmall
		{
			DefaultIcon = "coach",
			ImageColor = season.Color,

			Title = DXString.Get( "coach.plural" ),
			CardTapped = OnCoachesTapped
		};

		coaches.Init();
		cards.Add( coaches );

		// Statisticians
		statisticians = new HomeCardSmall
		{
			DefaultIcon = "statistician",
			ImageColor = season.Color,

			Title = DXString.Get( "statistician.plural" ),
			CardTapped = OnStatisticiansTapped
		};

		statisticians.Init();
		cards.Add( statisticians );

		// Opponents
		opponents = new HomeCardSmall
		{
			DefaultIcon = "opponent",
			ImageColor = season.Color,

			Title = DXString.Get( "opponent.plural" ),
			CardTapped = OnOpponentsTapped
		};

		opponents.Init();
		cards.Add( opponents );

		// Venues
		venues = new HomeCardSmall
		{
			DefaultIcon = "venue",
			ImageColor = season.Color,

			Title = DXString.Get( "venue.plural" ),
			CardTapped = OnVenuesTapped
		};

		venues.Init();
		cards.Add( venues );

		// Save path so next launch goes directly to Season Home
		string path = $"{season.Team.Organization.UniqueId}|{season.Team.UniqueId}|{season.UniqueId}";
		DXPreferences.Set( "launch.path", path );
	}

	// Cards not fully reloaded (only dynamic labels/images updated)
	public override void LoadCards()
	{
		UpdateLabels();
		UpdateImages();

		// Reset tap states
		foreach ( DXCard card in cards )
		{
			card.Reset();
		}

		// Sync button
		UpdateSync();
	}

	// User can force resync all season data
	public void UpdateSync()
	{
		ToolBar toolbar = Shell.Instance.ToolBar;

		// Network required
		if ( DXData.HasConnection() )
		{
			toolbar.AddCustom( 1, "sync", "home.sync" );
			toolbar.Custom1Tapped = OnSyncTapped;

			Shell.Instance.AppBar.UpdateLayout();
		}
		else
		{
			toolbar.RemoveCustom( 1 );
		}
	}

	// Updates all dynamic text labels
	private void UpdateLabels()
	{
		// Large
		roster.SubTitle = DXString.GetCount( "player", homeSeason.Players.Count );
		lineups.SubTitle = DXString.GetCount( "lineup", homeSeason.Lineups.Count );

		List<Match> matchList = Shell.Settings.GeneralFilter ? homeSeason.GetMatches( null ) : homeSeason.Matches;

		// Medium
		matches.SubTitle = DXString.GetCount( "match", matchList.Count );
		tournaments.SubTitle = DXString.GetCount( "tournament", homeSeason.Tournaments.Count );

		matches.UpdateRecord( homeSeason );

		// Small
		coaches.SubTitle = homeSeason.GetHomeCoach()?.FullName ?? DXString.GetCount( "coach", homeSeason.Coaches.Count );
		statisticians.SubTitle = homeSeason.GetHomeStatistician()?.FullName ?? DXString.GetCount( "statistician", homeSeason.Statisticians.Count );
		opponents.SubTitle = DXString.GetCount( "opponent", homeSeason.Opponents.Count );
		venues.SubTitle = DXString.GetCount( "venue", homeSeason.Venues.Count );
	}

	// Updates all card images
	private void UpdateImages()
	{
		// Large
		roster.Players = homeSeason.GetHomePlayers( 12, true );
		lineups.Players = homeSeason.GetHomeLineup()?.GetPlayers();

		// Small
		coaches.ImageUrl = homeSeason.GetHomeCoach()?.ImageUrl;
		statisticians.ImageUrl = homeSeason.GetHomeStatistician()?.ImageUrl;
		opponents.ImageUrl = homeSeason.GetHomeOpponent()?.ImageUrl;
		venues.ImageUrl = homeSeason.GetHomeVenue()?.ImageUrl;
	}

	// Navigates to specified page for this season
	private void PushPage( DXCardPage page )
	{
		Shell shell = Shell.Instance;

		shell.PageStack.Push( page, homeName );

		// No longer need sync
		shell.AppBar.ToolBar.RemoveCustom( 1 );
	}

	/* Event Callbacks */

	/* Large Cards */

	// Roster
	private void OnRosterTapped( DXCard card )
	{
		PushPage( new PlayerPage( data as Season ) );
	}

	// Lineups
	private void OnLineupsTapped( DXCard card )
	{
		PushPage( new LineupPage( data as Season ) );
	}

	/* Medium Cards */

	// Matches
	private void OnMatchesTapped( DXCard card )
	{
		PushPage( new MatchPage( data as Season, null ) );
	}

	// Tournaments
	private void OnTournamentsTapped( DXCard card )
	{
		PushPage( new TournamentPage( data as Season ) );
	}

	/* Small Cards */

	// Coaches
	private void OnCoachesTapped( DXCard card )
	{
		PushPage( new CoachPage( data as Season ) );
	}

	// Statisticians
	private void OnStatisticiansTapped( DXCard card )
	{
		PushPage( new StatisticianPage( data as Season ) );
	}

	// Opponents
	private void OnOpponentsTapped( DXCard card )
	{
		PushPage( new OpponentPage( data as Season ) );
	}

	// Venues
	private void OnVenuesTapped( DXCard card )
	{
		PushPage( new VenuePage( data as Season ) );
	}

	// User tapped data sync
	private void OnSyncTapped()
	{
		if ( DXData.HasConnection() )
		{
			DXAlert.ShowOkCancel( "home.sync", "home.sync.msg", OnSyncConfirmed, Shell.Instance.ToolBar.ResetCustom );
		}
		else
		{
			DXAlert.ShowNetworkError( "net.err.sync" );
		}
	}

	// User confirmed data sync
	private async void OnSyncConfirmed()
	{
		DXSpinner.Start();

		// Force resync of all season data
		if ( data is Season season )
		{
			await season.Resync();

			Shell shell = Shell.Instance;

			// Update UI
			shell.PageStack.Refresh();
			shell.ToolBar.ResetCustom();

			DXSpinner.Stop();
		}
	}

	/* Layout */

	// Device/orientation specific layout
	public override void UpdateLayout( LayoutType type )
	{
		layout.ClearAll();

		double bottomPad = (DXDevice.IsTablet ? 0 : BasePadding);
		Thickness basePadding = new( BasePadding, BasePadding, BasePadding, bottomPad );

		// Account for mobile notch
		Padding = DXUtils.AddPadding( basePadding, DXDevice.SafeAreaLR() );

		// Do NOT call base here
		switch ( type )
		{
			case LayoutType.Landscape: Landscape(); break;
			case LayoutType.Portrait: Portrait(); break;
			case LayoutType.MobileLandscape: MobileLandscape(); break;
			case LayoutType.MobilePortrait: MobilePortrait(); break;
			
			case LayoutType.WideLandscape: case LayoutType.WidePortrait: default: break;
		}

		// Update children (must be last)
		roster.UpdateLayout();
		lineups.UpdateLayout();

		matches.UpdateLayout();
		tournaments.UpdateLayout();

		coaches.UpdateLayout();
		statisticians.UpdateLayout();
		opponents.UpdateLayout();
		venues.UpdateLayout();

		DXSpinner.Stop();
	}

	// Landscape (4:3)
	protected override void Landscape()
	{
		const int homeRowCount = 4;

		// Must manually calculate heights, star rows do NOT work here
		double rowHt = (Shell.ContentHt - (BasePadding * (homeRowCount + 1))) / homeRowCount;

		if ( rowHt > 0 )
		{
			// 3 columns
			layout.AddStarColumns( 3 );
			layout.AddFixedRows( homeRowCount, rowHt );

			// Column 1 (2 rows)
			Add( roster, 0, 0, 2 );
			Add( lineups, 0, 2, 2 );

			// Column 2 (2 rows)
			Add( matches, 1, 0, 2 );
			Add( tournaments, 1, 2, 2 );

			// Column 3 (4 rows)
			Add( coaches, 2, 0 );
			Add( statisticians, 2, 1 );
			Add( opponents, 2, 2 );
			Add( venues, 2, 3 );
		}
	}

	// Portrait (3:4)
	protected override void Portrait()
	{
		const int homeRowCount = 6;

		// Must manually calculate heights, star rows do NOT work here
		double rowHt = (Shell.ContentHt - (BasePadding * (homeRowCount + 1))) / homeRowCount;

		if ( rowHt > 0 )
		{
			// 2 columns, variable height rows
			layout.AddStarColumns( 2 );

			// 6 total rows 
			layout.AddFixedRow( rowHt );
			layout.AddFixedRow( rowHt );
			layout.AddFixedRow( rowHt );
			layout.AddFixedRow( rowHt );
			layout.AddFixedRow( rowHt );
			layout.AddFixedRow( rowHt );

			// Row 1 (double height)
			Add( roster, 0, 0, 2 );
			Add( lineups, 1, 0, 2 );

			// Row 2 (double height)
			Add( matches, 0, 2, 2 );
			Add( tournaments, 1, 2, 2 );

			// Row 3
			Add( coaches, 0, 4 );
			Add( statisticians, 1, 4 );

			// Row 4
			Add( opponents, 0, 5 );
			Add( venues, 1, 5 );
		}
	}

	// Landscape (Mobile)
	protected override void MobileLandscape()
	{
		// 2 columns
		layout.AddStarColumns( 2 );

		// 4 fixed rows 
		layout.AddFixedRow( HomeCardLarge.CardHt );
		layout.AddFixedRow( HomeCardMedium.CardHt );
		layout.AddFixedRow( HomeCardSmall.CardHt );
		layout.AddFixedRow( HomeCardSmall.CardHt );

		// Row 1
		Add( roster, 0, 0 );
		Add( lineups, 1, 0 );

		// Row 2
		Add( matches, 0, 1 );
		Add( tournaments, 1, 1 );

		// Row 3
		Add( coaches, 0, 2 );
		Add( statisticians, 1, 2 );

		// Row 4
		Add( opponents, 0, 3 );
		Add( venues, 1, 3 );
	}

	// Portrait (Mobile)
	protected override void MobilePortrait()
	{
		// Single column, 8 fixed rows
		const double large = HomeCardLarge.CardHt;

		layout.AddFixedRow( large );
		layout.AddFixedRow( large );

		const double medium = HomeCardMedium.CardHt;

		layout.AddFixedRow( medium );
		layout.AddFixedRow( medium );

		const double small = HomeCardSmall.CardHt;

		layout.AddFixedRow( small );
		layout.AddFixedRow( small );
		layout.AddFixedRow( small );
		layout.AddFixedRow( small );

		// Add cards
		Add( roster, 0, 0 );
		Add( lineups, 0, 1 );

		Add( matches, 0, 2 );
		Add( tournaments, 0, 3 );

		Add( coaches, 0, 4 );
		Add( statisticians, 0, 5 );
		Add( opponents, 0, 6 );
		Add( venues, 0, 7 );
	}

	// Used internally to add home card
	private void Add( HomeCard card, int col, int row, int rowSpan = 1 )
	{
		layout.Add( card, col, row );

		if ( rowSpan > 1 )
		{
			layout.SpanRows( card, rowSpan );
		}
	}
}

//
