using System;
using System.Collections.Generic;
using UnityEngine;
using Mirror;

/*
	Documentation: https://mirror-networking.gitbook.io/docs/guides/networkbehaviour
	API Reference: https://mirror-networking.com/docs/api/Mirror.NetworkBehaviour.html
*/

public class #SCRIPTNAME# : NetworkBehaviour
{
    // You can adjust the parameters of the Actions below to suit your needs and pass the values through the Invoke() method.

    public event Action<NetworkIdentity> OnStartServerAction;
    public event Action<NetworkIdentity> OnStopServerAction;
    public event Action OnStartClientAction;
    public event Action OnStopClientAction;
    public event Action OnStartLocalPlayerAction;
    public event Action OnStopLocalPlayerAction;
    public event Action OnStartAuthorityAction;
    public event Action OnStopAuthorityAction;

    #region Unity Callbacks

    /// <summary>
    /// Add your validation code here after the base.OnValidate(); call.
    /// </summary>
    protected override void OnValidate()
    {
        base.OnValidate();
    }

    // NOTE: Do not put objects in DontDestroyOnLoad (DDOL) in Awake.  You can do that in Start instead.
    void Awake()
    {
        // Example of adding a handler for OnStartServerAction
        // Multiple handlers can be added for actions
        // Use -= to remove handlers
        // Set the action to null to remove all handlers
        OnStartServerAction += OnStartServerHandler;
    }

    void Start()
    {
    }

    /// <summary>
    /// Example handler for OnStartServerAction
    /// </summary>
    /// <remarks>Handlers can be assigned from, and exist, in any script</remarks>
    public void OnStartServerHandler(NetworkIdentity identity)
    {
        Debug.Log($"#SCRIPTNAME#.OnStartServerAction invoked for {identity}");
    }

    #endregion

    #region Start & Stop Callbacks

    /// <summary>
    /// This is invoked for NetworkBehaviour objects when they become active on the server.
    /// <para>This could be triggered by NetworkServer.Listen() for objects in the scene, or by NetworkServer.Spawn() for objects that are dynamically created.</para>
    /// <para>This will be called for objects on a "host" as well as for object on a dedicated server.</para>
    /// </summary>
    public override void OnStartServer()
    {
        OnStartServerAction?.Invoke(netIdentity);
    }

    /// <summary>
    /// Invoked on the server when the object is unspawned
    /// <para>Useful for saving object data in persistent storage</para>
    /// </summary>
    public override void OnStopServer()
    {
        OnStopServerAction?.Invoke(netIdentity);
    }

    /// <summary>
    /// Called on every NetworkBehaviour when it is activated on a client.
    /// <para>Objects on the host have this function called, as there is a local client on the host. The values of SyncVars on object are guaranteed to be initialized correctly with the latest state from the server when this function is called on the client.</para>
    /// </summary>
    public override void OnStartClient()
    {
        OnStartClientAction?.Invoke();
    }

    /// <summary>
    /// This is invoked on clients when the server has caused this object to be destroyed.
    /// <para>This can be used as a hook to invoke effects or do client specific cleanup.</para>
    /// </summary>
    public override void OnStopClient()
    {
        OnStopClientAction?.Invoke();
    }

    /// <summary>
    /// Called when the local player object has been set up.
    /// <para>This happens after OnStartClient(), as it is triggered by an ownership message from the server. This is an appropriate place to activate components or functionality that should only be active for the local player, such as cameras and input.</para>
    /// </summary>
    public override void OnStartLocalPlayer()
    {
        OnStartLocalPlayerAction?.Invoke();
    }

    /// <summary>
    /// Called when the local player object is being stopped.
    /// <para>This happens before OnStopClient(), as it may be triggered by an ownership message from the server, or because the player object is being destroyed. This is an appropriate place to deactivate components or functionality that should only be active for the local player, such as cameras and input.</para>
    /// </summary>
    public override void OnStopLocalPlayer()
    {
        OnStopLocalPlayerAction?.Invoke();
    }

    /// <summary>
    /// This is invoked on behaviours that have authority, based on context and <see cref="NetworkIdentity.hasAuthority">NetworkIdentity.hasAuthority</see>.
    /// <para>This is called after <see cref="OnStartServer">OnStartServer</see> and before <see cref="OnStartClient">OnStartClient.</see></para>
    /// <para>When <see cref="NetworkIdentity.AssignClientAuthority">AssignClientAuthority</see> is called on the server, this will be called on the client that owns the object. When an object is spawned with <see cref="NetworkServer.Spawn">NetworkServer.Spawn</see> with a NetworkConnectionToClient parameter included, this will be called on the client that owns the object.</para>
    /// </summary>
    public override void OnStartAuthority()
    {
        OnStartAuthorityAction?.Invoke();
    }

    /// <summary>
    /// This is invoked on behaviours when authority is removed.
    /// <para>When NetworkIdentity.RemoveClientAuthority is called on the server, this will be called on the client that owns the object.</para>
    /// </summary>
    public override void OnStopAuthority()
    {
        OnStopAuthorityAction?.Invoke();
    }

    #endregion
}
