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

namespace iStatVball3;

/*
 * Represents a Coach (head coach or assistant coach) for the parent Season.
 */
public class Coach : RootModel
{
	/* Constants */
	public const string CollectionKey = "Coaches";

    /* Properties */

    // Required
    [FirestoreProperty("Type")] public string Type { get; set; }
    [FirestoreProperty("FirstName")] public string FirstName { get; set; }
    [FirestoreProperty("LastName")] public string LastName { get; set; }

    // Optional
    [FirestoreProperty("Nickname")] public string Nickname { get; set; }
    [FirestoreProperty("Notes")] public string Notes { get; set; }

    // Account Link (map)
    [FirestoreProperty("Link")] public Link Link { get; set; }

    // Parent (FK)
    [FirestoreProperty("SeasonId")] public string SeasonId { get; set; }

	/* Ignored */
	public string TypeName => DXString.GetLookupValue( "coach.type", Type );
	public string FullName => $"{FirstName} {LastName}";
	public override string ObjectName => FullName;

	public bool HasLink => Link is { HasValue: true };

	// Parent
	public Season Season { get; set; }

	/* Methods */
	public Coach()
	{
		BaseCollectionKey = CollectionKey;
	}

	// Tests coach equality based on unique ID
	public override bool Equals( object obj )
	{
		return (obj is Coach coach) && coach.UniqueId.Equals( UniqueId );
	}

	// Generates unique hash code for lists
	public override int GetHashCode()
	{
		return UniqueId.GetHashCode();
	}

	/* Permissions */

	// Determines if user has permission to create Coaches
	public static bool CanCreate( Season season, User user )
	{
		return user.Level switch
		{
			// Director/coach/stat always can
			User.LevelType.Director or 
			User.LevelType.Coach or 
			User.LevelType.Statistician => !season.IsSample || user.IsAdmin,
			
			// No-one else can
			_ => false
		};
	}

	// Determines if user has permission to edit Coaches
	public static bool CanEdit( User user )
	{
		return user.Level switch
		{
			// Director/coach/stat always can
			User.LevelType.Director or 
			User.LevelType.Coach or 
			User.LevelType.Statistician => true,
			
			// No-one else can
			_ => false
		};
	}

	// Determines if user has permission to analyze Coach stats
	public static bool CanAnalyze( User user )
	{
		// NA
		return user.IsAdmin;
	}

	/* CRUD */

	// Reads and returns Coach matching specified unique identifier
	public static async Task<Coach> Read( string uniqueId )
	{
		return await Read<Coach>( CollectionKey, uniqueId );
	}

	// Updates status for permission link
	public override async Task UpdateLink( string username, Link.StatusType status )
	{
		await UpdateLink( Link, username, status, "Link" );
	}

	// Performs cascading delete for this Coach
	public override async Task Delete( bool remove = false )
	{
		// Delete permissions from any user with access to coach
		await Permission.Delete( UniqueId, Link );

		// No children to delete

		// Remove from parent
		if ( remove )
		{
			Season.Coaches.Remove( this );
		}

		// Delete self
		await base.Delete( remove );
	}

	// Deletes all links for specified user for this object
	public override async Task DeleteLink( string username )
	{
		await DeleteLink( Link, username, "Link" );

		Link = null;
	}

	/* Import */

	// Creates new Coach in specified season from existing object (batched)
	public static void Import( IWriteBatch batch, Season season, Coach coach )
	{
		Coach newCoach = new()
		{
			// Copy fields from existing object
			Type = coach.Type,
			FirstName = coach.FirstName,
			LastName = coach.LastName,

			Nickname = coach.Nickname,
			Notes = coach.Notes,

			// Account Link
			Link = coach.Link,

			// Start with existing image
			ImageUrl = coach.ImageUrl,

			// Connect to this season
			SeasonId = season.UniqueId,
			Season = season
		};

		// Add to parent
		season.Coaches.Add( newCoach );

		// Connect roots
		newCoach.Connect( batch, coach );

		// Persist
		newCoach.Create( batch );
	}
}

//
