using KArtSell.BuildingBlocks.Time;
using KArtSell.BuildingBlocks.Versioning;
using KArtSell.Modules.ModelOperations.Application;

namespace KArtSell.ModelOperations.UnitTests;

public sealed class ModelOperationRequestServiceTests
{
    [Fact]
    public async Task Persists_the_scheduled_occurrence_and_catch_up_provenance()
    {
        var scheduledFor = new DateTimeOffset(2026, 8, 9, 1, 0, 0, TimeSpan.Zero);
        var context = new ApprovedModelContext(
            "GLOBAL",
            new VersionSet("dataset", "data-hash", "model", "config", "code-sha", "contract"),
            "APPROVED",
            scheduledFor.AddDays(-1));
        var repository = new CapturingRequestRepository();
        var service = new ModelOperationRequestService(
            new FixedContextReader(context),
            repository,
            new FixedClock(scheduledFor.AddHours(2)));

        var request = await service.RequestAsync(
            Guid.NewGuid(), "J31", "GLOBAL", "EVALUATION_ONLY", "J31:GLOBAL:1:20260809010000Z",
            scheduledFor, "ALL_WITH_LIMIT", 2, "correlation", CancellationToken.None);

        Assert.NotNull(request);
        Assert.Same(request, repository.Request);
        Assert.Equal(scheduledFor, request.ScheduledFor);
        Assert.Equal("ALL_WITH_LIMIT", request.CatchUpPolicy);
        Assert.Equal(2, request.MaxCatchUp);
    }

    private sealed class FixedContextReader(ApprovedModelContext context) : IApprovedModelContextReader
    {
        public Task<ApprovedModelContext?> ReadAsync(string scopeKey, DateTimeOffset asOf, CancellationToken cancellationToken)
            => Task.FromResult<ApprovedModelContext?>(context);
    }

    private sealed class CapturingRequestRepository : IModelOperationRequestRepository
    {
        public ModelOperationRequest? Request { get; private set; }

        public Task<bool> AddAsync(ModelOperationRequest request, CancellationToken cancellationToken)
        {
            Request = request;
            return Task.FromResult(true);
        }
    }

    private sealed class FixedClock(DateTimeOffset utcNow) : IClock
    {
        public DateTimeOffset UtcNow => utcNow;
    }
}
