using Microsoft.Extensions.Logging;
using MongoDB.Driver;

namespace StellaOps.Feedser.Storage.Mongo.MergeEvents;

public sealed class MergeEventStore : IMergeEventStore
{
    private readonly IMongoCollection<MergeEventDocument> _collection;
    private readonly ILogger<MergeEventStore> _logger;

    public MergeEventStore(IMongoDatabase database, ILogger<MergeEventStore> logger)
    {
        _collection = (database ?? throw new ArgumentNullException(nameof(database)))
            .GetCollection<MergeEventDocument>(MongoStorageDefaults.Collections.MergeEvent);
        _logger = logger ?? throw new ArgumentNullException(nameof(logger));
    }

    public async Task AppendAsync(MergeEventRecord record, CancellationToken cancellationToken)
    {
        ArgumentNullException.ThrowIfNull(record);
        var document = MergeEventDocumentExtensions.FromRecord(record);
        await _collection.InsertOneAsync(document, cancellationToken: cancellationToken).ConfigureAwait(false);
        _logger.LogDebug("Appended merge event {MergeId} for {AdvisoryKey}", record.Id, record.AdvisoryKey);
    }

    public async Task<IReadOnlyList<MergeEventRecord>> GetRecentAsync(string advisoryKey, int limit, CancellationToken cancellationToken)
    {
        var cursor = await _collection.Find(x => x.AdvisoryKey == advisoryKey)
            .SortByDescending(x => x.MergedAt)
            .Limit(limit)
            .ToListAsync(cancellationToken)
            .ConfigureAwait(false);

        return cursor.Select(static x => x.ToRecord()).ToArray();
    }
}
