using MongoDB.Bson;
using StellaOps.Feedser.Source.Common.Cursors;

namespace StellaOps.Feedser.Source.CertCc.Internal;

internal sealed record CertCcCursor(TimeWindowCursorState SummaryState, DateTimeOffset? LastRun)
{
    public static CertCcCursor Empty { get; } = new(TimeWindowCursorState.Empty, null);

    public BsonDocument ToBsonDocument()
    {
        var document = new BsonDocument();

        var summary = new BsonDocument();
        SummaryState.WriteTo(summary, "start", "end");
        document["summary"] = summary;

        if (LastRun.HasValue)
        {
            document["lastRun"] = LastRun.Value.UtcDateTime;
        }

        return document;
    }

    public static CertCcCursor FromBson(BsonDocument? document)
    {
        if (document is null || document.ElementCount == 0)
        {
            return Empty;
        }

        TimeWindowCursorState summaryState = TimeWindowCursorState.Empty;
        if (document.TryGetValue("summary", out var summaryValue) && summaryValue is BsonDocument summaryDocument)
        {
            summaryState = TimeWindowCursorState.FromBsonDocument(summaryDocument, "start", "end");
        }

        DateTimeOffset? lastRun = null;
        if (document.TryGetValue("lastRun", out var lastRunValue))
        {
            lastRun = lastRunValue.BsonType switch
            {
                BsonType.DateTime => DateTime.SpecifyKind(lastRunValue.ToUniversalTime(), DateTimeKind.Utc),
                BsonType.String when DateTimeOffset.TryParse(lastRunValue.AsString, out var parsed) => parsed.ToUniversalTime(),
                _ => null,
            };
        }

        return new CertCcCursor(summaryState, lastRun);
    }

    public CertCcCursor WithSummaryState(TimeWindowCursorState state)
        => this with { SummaryState = state };

    public CertCcCursor WithLastRun(DateTimeOffset? timestamp)
        => this with { LastRun = timestamp };
}
