using System.Diagnostics;

namespace StellaOps.Feedser.WebService.Diagnostics;

internal sealed class ServiceStatus
{
    private readonly TimeProvider _timeProvider;
    private readonly DateTimeOffset _startedAt;
    private readonly object _sync = new();

    private DateTimeOffset? _bootstrapCompletedAt;
    private TimeSpan? _bootstrapDuration;
    private DateTimeOffset? _lastReadyCheckAt;
    private TimeSpan? _lastMongoLatency;
    private string? _lastMongoError;
    private bool _lastReadySucceeded;

    public ServiceStatus(TimeProvider timeProvider)
    {
        _timeProvider = timeProvider ?? TimeProvider.System;
        _startedAt = _timeProvider.GetUtcNow();
    }

    public ServiceHealthSnapshot CreateSnapshot()
    {
        lock (_sync)
        {
            return new ServiceHealthSnapshot(
                CapturedAt: _timeProvider.GetUtcNow(),
                StartedAt: _startedAt,
                BootstrapCompletedAt: _bootstrapCompletedAt,
                BootstrapDuration: _bootstrapDuration,
                LastReadyCheckAt: _lastReadyCheckAt,
                LastMongoLatency: _lastMongoLatency,
                LastMongoError: _lastMongoError,
                LastReadySucceeded: _lastReadySucceeded);
        }
    }

    public void MarkBootstrapCompleted(TimeSpan duration)
    {
        lock (_sync)
        {
            var completedAt = _timeProvider.GetUtcNow();
            _bootstrapCompletedAt = completedAt;
            _bootstrapDuration = duration;
            _lastReadySucceeded = true;
            _lastMongoLatency = duration;
            _lastMongoError = null;
            _lastReadyCheckAt = completedAt;
        }
    }

    public void RecordMongoCheck(bool success, TimeSpan latency, string? error)
    {
        lock (_sync)
        {
            _lastReadySucceeded = success;
            _lastMongoLatency = latency;
            _lastMongoError = success ? null : error;
            _lastReadyCheckAt = _timeProvider.GetUtcNow();
        }
    }
}

internal sealed record ServiceHealthSnapshot(
    DateTimeOffset CapturedAt,
    DateTimeOffset StartedAt,
    DateTimeOffset? BootstrapCompletedAt,
    TimeSpan? BootstrapDuration,
    DateTimeOffset? LastReadyCheckAt,
    TimeSpan? LastMongoLatency,
    string? LastMongoError,
    bool LastReadySucceeded);
