namespace ZB.MOM.WW.OtOpcUa.Configuration.Entities;

/// <summary>
///     Per Phase 7 plan decision #14 — persistent runtime state for each scripted alarm.
///     Survives process restart so operators don't re-ack and ack history survives for
///     GxP / 21 CFR Part 11 compliance. Keyed on <c>ScriptedAlarmId</c> logically (not
///     per-generation) because ack state follows the alarm's stable identity across
///     generations — a Modified alarm keeps its ack history.
/// </summary>
/// <remarks>
///     <para>
///         <c>ActiveState</c> is deliberately NOT persisted — it rederives from the current
///         predicate evaluation on startup. Only operator-supplied state (<see cref="AckedState"/>,
///         <see cref="ConfirmedState"/>, <see cref="ShelvingState"/>) + audit trail persist.
///     </para>
///     <para>
///         <see cref="CommentsJson"/> is an append-only JSON array of <c>{user, utc, text}</c>
///         tuples — one per operator comment. Core.ScriptedAlarms' <c>AlarmConditionState.Comments</c>
///         serializes directly into this column.
///     </para>
/// </remarks>
public sealed class ScriptedAlarmState
{
    /// <summary>Logical FK — matches <see cref="ScriptedAlarm.ScriptedAlarmId"/>. One row per alarm identity.</summary>
    public required string ScriptedAlarmId { get; set; }

    /// <summary>Enabled/Disabled. Persists across restart per plan decision #14.</summary>
    public required string EnabledState { get; set; } = "Enabled";

    /// <summary>Unacknowledged / Acknowledged.</summary>
    public required string AckedState { get; set; } = "Unacknowledged";

    /// <summary>Unconfirmed / Confirmed.</summary>
    public required string ConfirmedState { get; set; } = "Unconfirmed";

    /// <summary>Unshelved / OneShotShelved / TimedShelved.</summary>
    public required string ShelvingState { get; set; } = "Unshelved";

    /// <summary>When a TimedShelve expires — null if not shelved or OneShotShelved.</summary>
    public DateTime? ShelvingExpiresUtc { get; set; }

    /// <summary>User who last acknowledged. Null if never acked.</summary>
    public string? LastAckUser { get; set; }

    /// <summary>Operator-supplied ack comment. Null if no comment or never acked.</summary>
    public string? LastAckComment { get; set; }

    public DateTime? LastAckUtc { get; set; }

    /// <summary>User who last confirmed.</summary>
    public string? LastConfirmUser { get; set; }

    public string? LastConfirmComment { get; set; }

    public DateTime? LastConfirmUtc { get; set; }

    /// <summary>JSON array of operator comments, append-only (GxP audit).</summary>
    public string CommentsJson { get; set; } = "[]";

    /// <summary>Row write timestamp — tracks last state change.</summary>
    public DateTime UpdatedAtUtc { get; set; }
}
