using FluentAssertions;
using foodmarket.Api.Background;
using foodmarket.Domain.Inventory;
using foodmarket.Domain.Platform;
using foodmarket.Infrastructure.Persistence;
using foodmarket.UnitTests.Support;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.Logging.Abstractions;
using Xunit;

namespace foodmarket.UnitTests;

/// <summary>Юнит-тест: HousekeepingJobs.PruneStockMovements удаляет только
/// движения старше N дней (по умолчанию 730). Stock-инвариант не проверяем —
/// это межтенантная задача очистки далёкой истории, документы за этот горизонт
/// в норме закрыты.</summary>
public class HousekeepingJobsTests
{
    private static IConfiguration CfgWith(int stockDays = 730, int auditDays = 90) =>
        new ConfigurationBuilder().AddInMemoryCollection(new Dictionary<string, string?>
        {
            ["Hangfire:Retention:StockMovementDays"] = stockDays.ToString(),
            ["Hangfire:Retention:AuditLogDays"] = auditDays.ToString(),
        }).Build();

    [Fact]
    public async Task PruneStockMovements_deletes_only_old_rows()
    {
        using var sqlite = new SqliteDb(foreignKeys: false);
        var orgId = Guid.NewGuid();
        var tenant = new FakeTenantContext { OrganizationId = orgId };

        using (var db = sqlite.Create(tenant))
        {
            db.StockMovements.AddRange(
                new StockMovement
                {
                    OrganizationId = orgId, ProductId = Guid.NewGuid(), StoreId = Guid.NewGuid(),
                    Quantity = 1m, Type = MovementType.Supply, DocumentType = "supply",
                    OccurredAt = DateTime.UtcNow.AddYears(-3), // старая
                },
                new StockMovement
                {
                    OrganizationId = orgId, ProductId = Guid.NewGuid(), StoreId = Guid.NewGuid(),
                    Quantity = 1m, Type = MovementType.Supply, DocumentType = "supply",
                    OccurredAt = DateTime.UtcNow.AddDays(-30), // свежая
                });
            await db.SaveChangesAsync();
        }

        int deleted;
        using (var db = sqlite.Create(tenant))
        {
            var jobs = new HousekeepingJobs(db, CfgWith(stockDays: 730), NullLogger<HousekeepingJobs>.Instance);
            deleted = await jobs.PruneStockMovementsAsync();
        }

        deleted.Should().Be(1);
        using (var db = sqlite.Create(tenant))
        {
            (await db.StockMovements.IgnoreQueryFilters().CountAsync()).Should().Be(1);
        }
    }
}
