using FluentAssertions;
using Knot.Modules.Admin.Application.Admin.Commands;
using Knot.Modules.Auth.Application.Abstractions;
using Knot.Modules.Auth.Domain;
using Knot.Shared.Kernel;
using NSubstitute;
using Xunit;
using System;
using System.Threading;
using System.Threading.Tasks;

namespace Knot.Modules.Admin.UnitTests;

public class ResetUserPasswordCommandHandlerTests
{
    private readonly IAuthUnitOfWork _authUnitOfWork;
    private readonly IUserRepository _userRepository;
    private readonly ResetUserPasswordCommandHandler _handler;

    public ResetUserPasswordCommandHandlerTests()
    {
        _authUnitOfWork = Substitute.For<IAuthUnitOfWork>();
        _userRepository = Substitute.For<IUserRepository>();
        _handler = new ResetUserPasswordCommandHandler(_userRepository, _authUnitOfWork);
    }

    [Fact]
    public async Task Handle_ShouldReturnError_WhenUserNotFound()
    {
        // Arrange
        var command = new ResetUserPasswordCommand(Guid.NewGuid(), "NewP@ssw0rd");
        _userRepository.GetByIdAsync(command.UserId, Arg.Any<CancellationToken>()).Returns((User?)null);

        // Act
        var result = await _handler.Handle(command, CancellationToken.None);

        // Assert
        result.IsFailure.Should().BeTrue();
        result.Error.Should().Be(AuthErrors.UserNotFound);
    }

    [Fact]
    public async Task Handle_ShouldSucceed_WhenUserFound()
    {
        // Arrange
        var user = User.Create("User", "pass", "salt", "admin");
        var command = new ResetUserPasswordCommand(user.Id, "NewP@ssw0rd");
        
        _userRepository.GetByIdAsync(command.UserId, Arg.Any<CancellationToken>()).Returns(user);

        // Act
        var result = await _handler.Handle(command, CancellationToken.None);

        // Assert
        result.IsSuccess.Should().BeTrue();
        await _authUnitOfWork.Received(1).SaveChangesAsync(Arg.Any<CancellationToken>());
    }
}
