using NSubstitute;
using SIGCM2.Application.Abstractions.Persistence;
using SIGCM2.Application.IngresosBrutos.GetHistorial;
using SIGCM2.Domain.Fiscal;
using IibbEntity = SIGCM2.Domain.Entities.IngresosBrutos;

namespace SIGCM2.Application.Tests.IngresosBrutos.GetHistorial;

public class GetHistorialIngresosBrutosQueryHandlerTests
{
    private readonly IIngresosBrutosRepository _repo = Substitute.For<IIngresosBrutosRepository>();
    private readonly GetHistorialIngresosBrutosQueryHandler _handler;

    public GetHistorialIngresosBrutosQueryHandlerTests()
    {
        _handler = new GetHistorialIngresosBrutosQueryHandler(_repo);
    }

    private static IibbEntity MakeEntity(int id, int? predecesorId, DateOnly desde) =>
        IibbEntity.FromDb(
            id: id, provincia: ProvinciaArgentina.BuenosAires,
            descripcion: "IIBB BA", alicuota: 3m, activo: true,
            vigenciaDesde: desde,
            vigenciaHasta: predecesorId.HasValue ? desde.AddYears(1).AddDays(-1) : null,
            predecesorId: predecesorId,
            fechaCreacion: DateTime.UtcNow, fechaModificacion: null);

    [Fact]
    public async Task Handle_ChainOf2_ReturnsListWith2ItemsInOrder()
    {
        var chain = new List<IibbEntity>
        {
            MakeEntity(1, null, new DateOnly(2023, 1, 1)),
            MakeEntity(2, 1,   new DateOnly(2024, 1, 1)),
        };
        _repo.GetHistorialAsync(2, Arg.Any<CancellationToken>()).Returns(chain);

        var result = await _handler.Handle(new GetHistorialIngresosBrutosQuery(2));

        Assert.Equal(2, result.Count);
        Assert.Equal(1, result[0].Version);
        Assert.Equal(2, result[1].Version);
    }

    [Fact]
    public async Task Handle_SingleVersion_Returns1Item()
    {
        var chain = new List<IibbEntity>
            { MakeEntity(1, null, new DateOnly(2024, 1, 1)) };
        _repo.GetHistorialAsync(1, Arg.Any<CancellationToken>()).Returns(chain);

        var result = await _handler.Handle(new GetHistorialIngresosBrutosQuery(1));

        Assert.Single(result);
        Assert.Equal(ProvinciaArgentina.BuenosAires, result[0].Provincia);
    }
}
