using NSubstitute;
using TeleWave.Application.Admin.Users;
using TeleWave.Application.Admin.Users.BlockUser;
using TeleWave.Application.Common.Interfaces;
using TeleWave.Application.Common.Models;
using Xunit;

namespace TeleWave.Application.Tests.Admin.Users;

public class BlockUserCommandHandlerTests
{
    private readonly IIdentityService _identityService = Substitute.For<IIdentityService>();
    private readonly ICurrentUser _currentUser = Substitute.For<ICurrentUser>();

    private BlockUserCommandHandler CreateHandler() => new(_identityService, _currentUser);

    [Fact]
    public async Task Handle_WhenTargetingSelf_ReturnsFailureWithoutCallingIdentityService()
    {
        var userId = Guid.NewGuid();
        _currentUser.UserId.Returns(userId);

        var result = await CreateHandler()
            .Handle(new BlockUserCommand(userId), CancellationToken.None);

        Assert.False(result.IsSuccess);
        Assert.Equal(UserErrors.CannotBlockSelf, result.Error);
        await _identityService
            .DidNotReceive()
            .BlockUserAsync(Arg.Any<Guid>(), Arg.Any<CancellationToken>());
    }

    [Fact]
    public async Task Handle_WhenTargetingAnotherUser_DelegatesToIdentityService()
    {
        var adminId = Guid.NewGuid();
        var targetId = Guid.NewGuid();
        _currentUser.UserId.Returns(adminId);
        _identityService
            .BlockUserAsync(targetId, Arg.Any<CancellationToken>())
            .Returns(Result.Success());

        var result = await CreateHandler()
            .Handle(new BlockUserCommand(targetId), CancellationToken.None);

        Assert.True(result.IsSuccess);
        await _identityService.Received(1).BlockUserAsync(targetId, Arg.Any<CancellationToken>());
    }
}
