using ScadaLink.Commons.Messages.Health;

namespace ScadaLink.HealthMonitoring;

/// <summary>
/// In-memory state for a single site's health, stored by the central aggregator.
/// Immutable: every state transition produces a new instance which the aggregator
/// installs into its <c>ConcurrentDictionary</c> via an atomic compare-and-swap.
/// This makes handing the reference straight to UI callers safe — a consumer can
/// never observe a torn or half-applied update.
/// </summary>
public sealed record SiteHealthState
{
    public required string SiteId { get; init; }

    /// <summary>
    /// The latest full <see cref="SiteHealthReport"/> received for the site, or
    /// <c>null</c> if the site is known only via heartbeats and has not yet sent
    /// a report.
    /// </summary>
    public SiteHealthReport? LatestReport { get; init; }

    /// <summary>
    /// Time the latest full <see cref="SiteHealthReport"/> was processed.
    /// Used by the UI to surface report staleness during failover.
    /// </summary>
    public DateTimeOffset LastReportReceivedAt { get; init; }

    /// <summary>
    /// Time the most recent signal of any kind (full report OR heartbeat) was
    /// received. Drives offline detection — heartbeats from the standby keep the
    /// site marked online even when the active node is unable to produce a report
    /// (mid-failover, brief stalls). See the heartbeat scheduler owned by the
    /// Cluster Infrastructure / SiteCommunicationActor for the actual cadence.
    /// </summary>
    public DateTimeOffset LastHeartbeatAt { get; init; }

    public long LastSequenceNumber { get; init; }
    public bool IsOnline { get; init; }
}
