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

using System.Text.Json.Serialization;
using Plugin.Firebase.Firestore;

namespace iStatVball3;

/*
 * Used to persist additional fields specific to point stats. Persisted as a map within the parent Stat NOT as a root
 * level collection.
 */ 
public class StatPoint : IFirestoreObject
{
	/* Properties */

	// Point was a sideout?
	[FirestoreProperty("Sideout")] public bool Sideout { get; set; }

	// Earned point (kill, block, ace)?
	[FirestoreProperty("Earned")] public bool Earned { get; set; }

	// Sideout handling
	[FirestoreProperty("ServeCount")] public int ServeCount { get; set; }
	[FirestoreProperty("ServeSide")] public string ServeSide { get; set; }

	// Score independent of side A/B
	[FirestoreProperty("Score1")] public int Score1 { get; set; }
	[FirestoreProperty("Score2")] public int Score2 { get; set; }

	// Rotation of team earning point and receiving (BEFORE sideout)
	[FirestoreProperty("Rotation")] public int Rotation { get; set; }
	[FirestoreProperty("RecvRotation")] public int RecvRotation { get; set; }

	[FirestoreProperty("Touches")] public int Touches { get; set; }
	[FirestoreProperty("Transitions")] public int Transitions { get; set; }

	[FirestoreProperty("Duration")] public int Duration { get; set; }

	// References (FKs)

	// Players on court at time of point (array)
	[FirestoreProperty("PlayerIds1")] public IList<string> PlayerIds1 { get; set; }

	// Sides
	[FirestoreProperty("TeamAId")] public string TeamAId { get; set; }
	[FirestoreProperty("TeamBId")] public string TeamBId { get; set; }

	// Team receiving serve
	[FirestoreProperty("ReceiveId")] public string ReceiveId { get; set; }

	// Team CAUSING point (earned or error)
	[FirestoreProperty("CausedId")] public string CausedId { get; set; }

	// Team actually AWARDED point
	[FirestoreProperty("TeamId")] public string TeamId { get; set; }

	/* Ignored */
	[JsonIgnore] private List<Player> Players { get; }

	/* Methods */
	public StatPoint()
	{
		// Allocate containers
		PlayerIds1 = new List<string>();
		Players = [];
	}
	
	// Determines if specified player was on court at time of point
	public bool IsPlayerOnCourt( Player player )
	{
		foreach ( Player courtPlayer in Players )
		{
			if ( (courtPlayer != null) && courtPlayer.Equals( player ) )
			{
				return true;
			}
		}

		return false;
	}

	// Saves list of all players on court at time of point (no db)
	public void SaveLineup( RecordLineup lineup1 )
	{
		foreach ( LineupEntry entry in lineup1.Entries )
		{
			PlayerIds1.Add( entry.PlayerId );
		}
	}

    // Changes previous team to new team, for changing opponent (no db)
    public void UpdateTeam( string oldId, string newId )
	{
		// Could be either court side
		if ( (TeamAId == oldId) || (TeamAId == null) )
		{
			TeamAId = newId;
		}
		else if ( (TeamBId == oldId) || (TeamBId == null) )
		{
			TeamBId = newId;
		}

		// Null always anon opponent
		if ( (ReceiveId == oldId) || (ReceiveId == null) )
		{
			ReceiveId = newId;
		}

		if ( (CausedId == oldId) || (CausedId == null) )
		{
			CausedId = newId;
		}

		if ( (TeamId == oldId) || (TeamId == null) )
		{
			TeamId = newId;
		}
	}

	/* Populate */

	// Populates players on court at time of point (for Root mapping)
	public void Populate( Season season )
	{
		Players.Clear();

		// Lookup each player within season scope
		foreach ( string playerId in PlayerIds1 )
		{
			if ( playerId != null )
			{
				Player player = season.GetPlayer( playerId );

				Players.Add( player );
			}
		}
	}
}

//
