using MediatR;
using Modules.User.Application.Errors;
using Modules.User.Application.Gateways;
using Modules.User.Domain.ValueObjects;

namespace Modules.User.Application.Commands;

public class CreateUserCommand : IRequest<Guid>
{
    public string Email { get; init; } = null!;
    public string Password { get; init; } = null!;
    public string Nickname { get; init; } = null!;
}

public class CreateUserCommandHandler(IUserRepository userRepository, IPasswordHasher passwordHasher, IUnitOfWork unitOfWork) : IRequestHandler<CreateUserCommand, Guid>
{
    public async Task<Guid> Handle(CreateUserCommand request, CancellationToken cancellationToken)
    {
        var exists = await userRepository.ExistsByEmailAsync(request.Email, cancellationToken);
        if (exists) throw new AccountException();
        var hashedPassword = passwordHasher.HashPassword(request.Password);
        var newUser = Domain.Entities.User.User.Create(request.Nickname, Email.Create(request.Email), hashedPassword);
        
        await userRepository.AddAsync(newUser, cancellationToken);
        await unitOfWork.SaveChangesAsync(cancellationToken);

        return newUser.Id;
    }
}