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

namespace SIGCM2.Application.Tests.IngresosBrutos.GetById;

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

    private static IibbEntity MakeEntity(int id = 1) =>
        IibbEntity.FromDb(
            id: id, provincia: ProvinciaArgentina.Cordoba, descripcion: "IIBB Córdoba",
            alicuota: 4m, activo: true,
            vigenciaDesde: new DateOnly(2024, 1, 1),
            vigenciaHasta: null, predecesorId: null,
            fechaCreacion: DateTime.UtcNow, fechaModificacion: null);

    public GetIngresosBrutosByIdQueryHandlerTests()
    {
        _handler = new GetIngresosBrutosByIdQueryHandler(_repo);
        _repo.GetByIdAsync(1, Arg.Any<CancellationToken>()).Returns(MakeEntity());
    }

    [Fact]
    public async Task Handle_Found_ReturnsDtoWithCorrectId()
    {
        var result = await _handler.Handle(new GetIngresosBrutosByIdQuery(1));

        Assert.Equal(1, result.Id);
    }

    [Fact]
    public async Task Handle_Found_ReturnsDtoWithCorrectProvincia()
    {
        var result = await _handler.Handle(new GetIngresosBrutosByIdQuery(1));

        Assert.Equal(ProvinciaArgentina.Cordoba, result.Provincia);
        Assert.Equal(4m, result.Alicuota);
    }

    [Fact]
    public async Task Handle_NotFound_ThrowsIngresosBrutosNotFoundException()
    {
        _repo.GetByIdAsync(99, Arg.Any<CancellationToken>()).Returns((IibbEntity?)null);

        await Assert.ThrowsAsync<IngresosBrutosNotFoundException>(
            () => _handler.Handle(new GetIngresosBrutosByIdQuery(99)));
    }
}
