using Akka.Actor;

namespace ZB.MOM.WW.ScadaBridge.NotificationOutbox.Messages;

/// <summary>
/// Actor-internal message types for the <see cref="NotificationOutboxActor"/>. These are
/// never sent across the network — they bridge the actor's async repository/delivery work
/// back onto the actor's own mailbox so handlers run single-threaded on the actor.
/// </summary>
internal static class InternalMessages
{
    /// <summary>
    /// Result of an asynchronous ingest persistence attempt, piped back to the actor.
    /// Carries the original <paramref name="Sender"/> so the actor can ack the site that
    /// submitted the notification once the insert completes.
    /// </summary>
    /// <param name="NotificationId">Id of the notification that was submitted.</param>
    /// <param name="Sender">Original submitter to receive the ack.</param>
    /// <param name="Succeeded">
    /// True if persistence completed without error — covers both a fresh insert and an
    /// already-existing row (idempotent re-submission). False only when the repository threw.
    /// </param>
    /// <param name="Error">Failure detail when <paramref name="Succeeded"/> is false; otherwise null.</param>
    internal sealed record IngestPersisted(
        string NotificationId,
        IActorRef Sender,
        bool Succeeded,
        string? Error);

    /// <summary>
    /// Periodic tick that triggers a dispatch sweep. Started as a periodic timer in
    /// <c>PreStart</c> at the configured <c>DispatchInterval</c>. A singleton instance is
    /// reused so the timer carries no per-tick state.
    /// </summary>
    internal sealed class DispatchTick
    {
        /// <summary>The shared singleton tick instance scheduled by the dispatch timer.</summary>
        internal static readonly DispatchTick Instance = new();

        private DispatchTick() { }
    }

    /// <summary>
    /// Completion signal for an asynchronous dispatch sweep, piped back to the actor so the
    /// in-flight guard is cleared on the actor thread. Sent on both success and failure of
    /// the sweep — the actor only needs to know the sweep has finished.
    /// </summary>
    internal sealed class DispatchComplete
    {
        /// <summary>The shared singleton completion instance.</summary>
        internal static readonly DispatchComplete Instance = new();

        private DispatchComplete() { }
    }

    /// <summary>
    /// Periodic tick that triggers a purge sweep of terminal notification rows. Started as a
    /// periodic timer in <c>PreStart</c> at the configured <c>PurgeInterval</c>. A singleton
    /// instance is reused so the timer carries no per-tick state.
    /// </summary>
    internal sealed class PurgeTick
    {
        /// <summary>The shared singleton tick instance scheduled by the purge timer.</summary>
        internal static readonly PurgeTick Instance = new();

        private PurgeTick() { }
    }

    /// <summary>
    /// Completion signal for an asynchronous purge sweep, piped back to the actor so the
    /// sweep's outcome (logged in the pipe projection) is observed on the actor thread.
    /// Sent on both success and failure of the sweep.
    /// </summary>
    internal sealed class PurgeComplete
    {
        /// <summary>The shared singleton completion instance.</summary>
        internal static readonly PurgeComplete Instance = new();

        private PurgeComplete() { }
    }
}
