using ZB.MOM.WW.ScadaBridge.Commons.Interfaces.Kpi;

namespace ZB.MOM.WW.ScadaBridge.HealthMonitoring.Kpi;

/// <summary>
/// Central <see cref="IAuditBacklogProvider"/> — sums the latest per-site
/// <c>SiteAuditBacklog.PendingCount</c> across the in-memory
/// <see cref="ICentralHealthAggregator"/>, the same aggregate the live
/// Health-dashboard "Audit" backlog tile shows
/// (<c>AuditLogQueryService.GetKpiSnapshotAsync</c>).
/// </summary>
/// <remarks>
/// Registered only on the central node (where the aggregator lives), so the
/// <see cref="ZB.MOM.WW.ScadaBridge.Commons.Interfaces.Kpi.IKpiSampleSource"/>
/// backing the <c>backlogTotal</c> trend records the real backlog instead of the
/// append-only repository's hardwired zero. Best-effort: sites with no report or
/// a null <c>SiteAuditBacklog</c> contribute nothing.
/// </remarks>
public sealed class CentralHealthAuditBacklogProvider : IAuditBacklogProvider
{
    private readonly ICentralHealthAggregator _aggregator;

    /// <summary>
    /// Initializes a new instance of the <see cref="CentralHealthAuditBacklogProvider"/> class.
    /// </summary>
    /// <param name="aggregator">The central health aggregator whose per-site latest reports carry the backlog.</param>
    public CentralHealthAuditBacklogProvider(ICentralHealthAggregator aggregator)
    {
        ArgumentNullException.ThrowIfNull(aggregator);
        _aggregator = aggregator;
    }

    /// <inheritdoc />
    public long GetPendingBacklogTotal()
    {
        // Ported verbatim from AuditLogQueryService.GetKpiSnapshotAsync: a null
        // SiteAuditBacklog is "unknown" (contributes zero), and the `> 0` guard
        // ignores any defensive negative/zero value so the tile and the history
        // agree exactly.
        long backlog = 0;
        foreach (var state in _aggregator.GetAllSiteStates().Values)
        {
            var pending = state.LatestReport?.SiteAuditBacklog?.PendingCount;
            if (pending is > 0)
            {
                backlog += pending.Value;
            }
        }

        return backlog;
    }
}
