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

using Plugin.Firebase.Firestore;

using DXLib.Data;
using DXLib.Data.Model;

namespace iStatVball3;

/*
 * Base class for all DXModels that include a shared Root ID. The shared root allows multiple instances of a model type,
 * each with their own unique ID and property values, to be connected by the common Root ID.
 */
public class RootModel : LinkModel
{
	/* Properties */

	// Global root (map)
	public Root Root { get; set; }

	/* Ignored */

	// ID handling
	public bool IsRooted => Root != null;
	public string RootId => IsRooted ? Root.RootId : UniqueId;

	/* Methods */

	// Tests equality based on unique identifier (including Root)
	public bool EqualsId( string uniqueId )
	{
		return UniqueId.Equals( uniqueId ) || RootId.Equals( uniqueId );
	}

	// Connect roots between this model and specified model (batched)
	protected void Connect( IWriteBatch batch, RootModel model )
	{
		// Specified model already has root
		if ( model.IsRooted )
		{
			Root = new Root
			{
				RootId = model.RootId
			};
		}
		// Create new root
		else
		{
			Root = new Root
			{
				RootId = DXData.Guid()
			};

			// Both models must be persisted
			model.UpdateRoot( batch, Root );
		}
	}

	// Connects roots between this player and player from previous season (batched)
	protected void ConnectPlayer( IWriteBatch batch, Player player )
	{
		// Root ID
		Connect( batch, player );

		Season season = player.Season;

		// Additional player specific fields
		Root.TeamId = season.Team.UniqueId;
		Root.SeasonId = season.UniqueId;
		Root.ObjectId = player.UniqueId;
	}

	// Returns all models from previous list not already in current list
	public static List<DXModel> GetModels( List<DXModel> models, List<DXModel> prevModels )
	{
		List<DXModel> list;

		// New season (all previous models eligible)
		if ( models == null )
		{
			list = [ ..prevModels ];
		}
		// Existing season (only include models not already in season)
		else
		{
			list = [];

			foreach ( DXModel prevModel in prevModels )
			{
				if ( !Contains( models, prevModel ) )
				{
					list.Add( prevModel );
				}
			}
		}

		return list;
	}

	// Determines if specified model exists in given list based on Root ID
	private static bool Contains( List<DXModel> models, DXModel model )
	{
		foreach ( DXModel testModel in models )
		{
			if ( testModel is RootModel testRoot )
			{
				// Root IDs match
				if ( model is RootModel rootModel )
				{
					if ( testRoot.RootId.Equals( rootModel.RootId ) )
					{
						return true;
					}
				}
			}
		}

		// No match found
		return false;
	}

	/* Abstracts */

	// Not used
	public override Task UpdateLink( string username, Link.StatusType status )
	{
		throw new NotImplementedException();
	}

	/* CRUD */

	// Persists underlying root ID (batched)
	private void UpdateRoot( IWriteBatch batch, Root root )
	{
		Root = root;

		Update( batch, "Root", Root );
	}
}

//
