using NSubstitute;
using SIGCM2.Application.Abstractions.Persistence;
using SIGCM2.Application.Audit;
using SIGCM2.Application.Auth.Logout;

namespace SIGCM2.Application.Tests.Auth.Logout;

public class LogoutCommandHandlerTests
{
    private readonly IRefreshTokenRepository _refreshRepo = Substitute.For<IRefreshTokenRepository>();
    private readonly ISecurityEventLogger _security = Substitute.For<ISecurityEventLogger>();
    private readonly LogoutCommandHandler _handler;

    public LogoutCommandHandlerTests()
    {
        _handler = new LogoutCommandHandler(_refreshRepo, _security, TimeProvider.System);
    }

    [Fact]
    public async Task Handle_RevokesAllActiveForUser()
    {
        _refreshRepo.RevokeAllActiveForUserAsync(42, Arg.Any<DateTime>()).Returns(3);

        var result = await _handler.Handle(new LogoutCommand(42));

        Assert.True(result.Success);
        Assert.False(string.IsNullOrWhiteSpace(result.Mensaje));
        await _refreshRepo.Received(1).RevokeAllActiveForUserAsync(42, Arg.Any<DateTime>());
    }

    [Fact]
    public async Task Handle_NoActiveTokens_StillReturnsSuccess()
    {
        // 0 rows affected = idempotent logout
        _refreshRepo.RevokeAllActiveForUserAsync(Arg.Any<int>(), Arg.Any<DateTime>()).Returns(0);

        var result = await _handler.Handle(new LogoutCommand(99));

        Assert.True(result.Success);
    }
}
