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

using DXLib.UI.Control.Checkbox;

namespace iStatVball3;

/*
 * Provides utility methods for working with an analyze By Player key. Note that the key itself is a Player object.
 */
public class KeyPlayer
{
	/* Constants */
	private const int DefaultLabelLen = 20;

	/* Methods */

	// Returns unique player key for stat analysis
	public static string GetKey( Stat stat, int number )
	{
		// Stat can have 1-3 players
		return number switch
		{
			1 => stat.Player?.RootId,
			2 => stat.Player2?.RootId,
			3 => stat.Player3?.RootId,

			_ => null,
		};
	}

	// Returns dimension display label for specified stat
	public static string GetLabel( Stat stat, int number, int maxLen )
    {
		int len = (maxLen == 0) ? DefaultLabelLen : maxLen;

        return number switch
        {
            1 => stat.Player.GetAnalyzeName( len ),
            2 => stat.Player2?.GetAnalyzeName( len ),
            3 => stat.Player3?.GetAnalyzeName( len ),

            _ => null,
        };
    }

	// Returns list of filter objects for this dimension
    public static List<object> GetFilter( List<object> objects )
    {
		return objects;
    }

	// Determines whether specified stat should be included in given filter
	public static bool Filter( DataConfig config, List<object> filter, Stat stat, int playerNum )
    {
        Player player = stat.GetPlayer( playerNum );

        // RallyFlow Low detail MUST include null players
        bool allowNull = stat.Set.IsRallyLow;

		string accessId = config.PlayerAccessId;

		// Coach/Director have access to all players (or RallyFlow Low)
		bool unrestricted = (accessId == null) || allowNull;

		// Anonymous or Player 2/3
		bool valid = (player != null) || unrestricted;

		if ( valid )
		{
			// Player/Fan access restricted to 1 player
			bool accessible = unrestricted || accessId.Equals( player.RootId );

			if ( accessible )
			{
				// Multi-select dimension filter
				return (filter == null) || filter.Contains( player );
			}
		}

		return false;
	}

	// Returns comma-delimited list of selected player filter values
	public static string GetValues( List<object> filter )
	{
		int count = filter.Count;
		string[] values = new string[ count ];

		// Build comma delimited list
		for ( int i = 0; i < count; i++ )
		{
			object obj = filter[i];

			values[i] = (obj as Player)?.FullName;
		}

		return string.Join( ", ", values );
	}

	// Loads filter tree for player dimension
	public static void Load( DXCheckboxNode tree, List<object> filter, bool allowEmpty )
	{
		tree.SetChildObjects( filter );

		// Auto-select root if applicable
		if ( (filter.Count == 0) && allowEmpty )
		{
			tree.SelectRoot( true );
		}
	}

	// Updates filter list for player dimension
	public static List<object> Update( DataStats stats )
	{
		List<Player> list = [];

		// Access may be restricted to single player
		string filterId = Shell.CurrentUser.GetPermission();

		// Build list of each player present in data
		foreach ( Stat stat in stats )
		{
			AddPlayer( list, filterId, stat.Player );

			// Single block stat may have multiple players
			if ( stat.IsBlock )
			{
				AddPlayer( list, filterId, stat.Player2 );
				AddPlayer( list, filterId, stat.Player3 );
			}
		}

		// Sort
		return list.OrderBy( p => p.LastName ).Cast<object>().ToList();
	}

	// Adds player to filter list if applicable
	private static void AddPlayer( List<Player> list, string filterId, Player player )
	{
		// Only add if not already in list and matches filter (if any)
		if ( (player != null) && !list.Contains( player ) && ((filterId == null) || player.EqualsId( filterId )) )
		{
			list.Add( player );
		}
	}
}

//
