namespace ZB.MOM.WW.OtOpcUa.Commons.OpcUa;

/// <summary>
///     Shared DPS topic for inbound alarm commands (<see cref="AlarmCommand"/>). Publishers — the
///     OPC UA node-manager seam (T18) and the AdminUI path via <c>AdminOperationsActor</c> (T21) —
///     and the subscriber (<c>ScriptedAlarmHostActor</c>, T19) reference this single constant so a
///     rename can't silently desynchronise them. Mirrors the
///     <see cref="Messages.Admin.DriverControlTopic"/> pattern; <c>ScriptedAlarmHostActor</c>
///     re-exports this as its <c>AlarmCommandsTopic</c> const.
/// </summary>
public static class AlarmCommandsTopic
{
    /// <summary>The cluster DistributedPubSub topic name inbound alarm commands are published on.</summary>
    public const string Name = "alarm-commands";
}

/// <summary>
///     Commons-level command carried from an inbound OPC UA Part 9 alarm method call
///     (Acknowledge / Confirm / Shelve / AddComment …) back to the scripted-alarm engine. The SDK
///     node manager builds one of these in its condition method-handler delegates after the
///     <c>AlarmAck</c> role gate passes, then the host routes it onto the cluster
///     <c>alarm-commands</c> DistributedPubSub topic; T19's engine-side subscriber consumes it and
///     drives the matching <c>Part9StateMachine.Apply*</c> transition. This is a pure DTO — it makes
///     no auth decision and holds no SDK/Akka handle.
/// </summary>
/// <param name="AlarmId">
///     The alarm's ScriptedAlarmId — equal to the materialised condition node's NodeId identifier
///     (T14 aligned the condition NodeId to the ScriptedAlarmId). The engine keys its domain state by
///     this id.
/// </param>
/// <param name="Operation">
///     The Part 9 operation, one of: <c>Acknowledge</c>, <c>Confirm</c>, <c>OneShotShelve</c>,
///     <c>TimedShelve</c>, <c>Unshelve</c>, <c>Enable</c>, <c>Disable</c>, <c>AddComment</c>. These map
///     1:1 onto the engine's <c>Part9StateMachine.Apply*</c> calls on the consuming side (T19).
///     All of <c>Acknowledge</c>/<c>Confirm</c>/<c>AddComment</c>/<c>Shelve</c>/<c>TimedUnshelve</c>/
///     <c>Enable</c>/<c>Disable</c> are wired at the node-manager seam; the <c>Enable</c>/<c>Disable</c>
///     operations are produced by the condition's <c>OnEnableDisable</c> delegate.
/// </param>
/// <param name="User">The acting user — the authenticated session identity's display/name.</param>
/// <param name="Comment">
///     The free-text comment supplied with the call (the OPC UA <c>LocalizedText</c> payload's text),
///     or <c>null</c> when none was provided.
/// </param>
/// <param name="UnshelveAtUtc">
///     For <c>TimedShelve</c>, the absolute UTC instant the shelve auto-expires
///     (<c>DateTime.UtcNow + shelvingTime</c>, where the OPC UA <c>Duration</c> <c>shelvingTime</c> is
///     in <b>milliseconds</b>); <c>null</c> for every other operation.
/// </param>
public sealed record AlarmCommand(
    string AlarmId,
    string Operation,
    string User,
    string? Comment,
    DateTime? UnshelveAtUtc);
