using System.Diagnostics;
using PkmnLib.Dynamic.ScriptHandling.Registry;
using PkmnLib.Static.Utils;

namespace PkmnLib.Dynamic.ScriptHandling;

/// <summary>
/// The script class is used to make changes to how a battle executes, without requiring hardcoded
/// changes. This allows for easily defining generational differences, and add effects that the
/// developer might require.
/// </summary>
[DebuggerDisplay("{Category} - {Name}")]
public abstract class Script : IDeepCloneable, IScriptOnRemove
{
    internal event Action<Script>? OnRemoveEvent;

    /// <summary>
    /// Remove the script from its owner.
    /// </summary>
    public void RemoveSelf()
    {
        OnRemoveEvent?.Invoke(this);
    }

    /// <summary>
    /// The name of a script is its unique identifier.
    /// If not overridden, this will resolve the name from the <see cref="ScriptAttribute"/> of the
    /// script.
    /// </summary>
    public virtual StringKey Name => this.ResolveName();

    /// <summary>
    /// The category of a script is used to determine what kind of script it is. This is used to
    /// determine what kind of script it is, and what kind of events it can handle.
    /// </summary>
    public virtual ScriptCategory Category => this.ResolveCategory();

    /// <summary>
    /// This function is ran when this script stops being in effect, and is removed from its owner.
    /// </summary>
    public virtual void OnRemove()
    {
    }

    /// <summary>
    /// This function is ran when this script is added to a parent. 
    /// </summary>
    public virtual void OnAddedToParent(IScriptSource source)
    {
    }
}