namespace ZB.MOM.WW.OtOpcUa.Client.Shared.Models;

/// <summary>
///     Event data for an alarm or condition notification from the OPC UA server.
/// </summary>
public sealed class AlarmEventArgs : EventArgs
{
    /// <summary>Initializes a new instance of the <see cref="AlarmEventArgs"/> class.</summary>
    /// <param name="sourceName">The name of the source object that raised the alarm.</param>
    /// <param name="conditionName">The condition type name.</param>
    /// <param name="severity">The alarm severity (0-1000).</param>
    /// <param name="message">Human-readable alarm message.</param>
    /// <param name="retain">Whether the alarm should be retained in the display.</param>
    /// <param name="activeState">Whether the alarm condition is currently active.</param>
    /// <param name="ackedState">Whether the alarm has been acknowledged.</param>
    /// <param name="time">The time the event occurred.</param>
    /// <param name="eventId">The EventId used for alarm acknowledgment.</param>
    /// <param name="conditionNodeId">The NodeId of the condition instance.</param>
    /// <param name="operatorComment">Operator-supplied comment on acknowledgment transitions.</param>
    /// <param name="originalRaiseTimestampUtc">When the alarm originally entered the active state.</param>
    /// <param name="alarmCategory">Upstream alarm taxonomy bucket (e.g. Process, Safety, Diagnostics).</param>
    public AlarmEventArgs(
        string sourceName,
        string conditionName,
        ushort severity,
        string message,
        bool retain,
        bool activeState,
        bool ackedState,
        DateTime time,
        byte[]? eventId = null,
        string? conditionNodeId = null,
        string? operatorComment = null,
        DateTime? originalRaiseTimestampUtc = null,
        string? alarmCategory = null)
    {
        SourceName = sourceName;
        ConditionName = conditionName;
        Severity = severity;
        Message = message;
        Retain = retain;
        ActiveState = activeState;
        AckedState = ackedState;
        Time = time;
        EventId = eventId;
        ConditionNodeId = conditionNodeId;
        OperatorComment = operatorComment;
        OriginalRaiseTimestampUtc = originalRaiseTimestampUtc;
        AlarmCategory = alarmCategory;
    }

    /// <summary>The name of the source object that raised the alarm.</summary>
    public string SourceName { get; }

    /// <summary>The condition type name.</summary>
    public string ConditionName { get; }

    /// <summary>The alarm severity (0-1000).</summary>
    public ushort Severity { get; }

    /// <summary>Human-readable alarm message.</summary>
    public string Message { get; }

    /// <summary>Whether the alarm should be retained in the display.</summary>
    public bool Retain { get; }

    /// <summary>Whether the alarm condition is currently active.</summary>
    public bool ActiveState { get; }

    /// <summary>Whether the alarm has been acknowledged.</summary>
    public bool AckedState { get; }

    /// <summary>The time the event occurred.</summary>
    public DateTime Time { get; }

    /// <summary>The EventId used for alarm acknowledgment.</summary>
    public byte[]? EventId { get; }

    /// <summary>The NodeId of the condition instance (SourceNode), used for acknowledgment.</summary>
    public string? ConditionNodeId { get; }

    /// <summary>
    ///     PR E.7 — Operator-supplied comment recorded by the upstream alarm system on
    ///     Acknowledge transitions. Null on raise / clear events, and intentionally null
    ///     on the Galaxy OPC UA sub-attribute fallback path for two unrecoverable reasons:
    ///     (a) Galaxy's <c>AckMsg</c> attribute is WRITE-ONLY — no readable attribute
    ///     exposes the last operator comment — and (b) the OPC UA event SelectClause
    ///     carries no comment field. The operator comment is only available via the
    ///     gateway's native alarm feed (<c>GalaxyAlarmTransition.OperatorComment</c>
    ///     in the Galaxy driver path).
    /// </summary>
    public string? OperatorComment { get; }

    /// <summary>
    ///     PR E.7 — When the alarm originally entered the active state. Preserved
    ///     across Acknowledge transitions so OPC UA Part 9 conditions keep the
    ///     original raise time. Null when the upstream path doesn't surface it.
    /// </summary>
    public DateTime? OriginalRaiseTimestampUtc { get; }

    /// <summary>
    ///     PR E.7 — Upstream alarm taxonomy bucket (e.g. <c>Process</c> /
    ///     <c>Safety</c> / <c>Diagnostics</c>). Null when not surfaced.
    /// </summary>
    public string? AlarmCategory { get; }
}