namespace CSR.Application.Services;

using CSR.Application.Interfaces;
using CSR.Domain.Entities;

public class UserService(IUserRepository userRepository, Domain.Interfaces.IPasswordHasher passwordHasher) : IUserService
{
  private readonly IUserRepository _userRepository = userRepository;
  private readonly Domain.Interfaces.IPasswordHasher _passwordHasher = passwordHasher;

  public async Task<IUserService.RegisterNewUserResult> RegisterNewUser
    (
      string username,
      string email,
      string password
    )
  {
    var errors = new List<string>();
    var (IsValid, Errors) = User.IsValidUsername(username);
    if (!IsValid)
    {
      errors.AddRange(Errors!);
    }

    if (!User.IsValidEmail(email))
    {
      errors.Add("Invalid email address.");
    }

    (IsValid, Errors) = User.IsValidPassword(password);
    if (!IsValid)
    {
      errors.AddRange(Errors!);
    }

    var existingUser = await _userRepository.GetByUsernameAsync(username);
    if (existingUser != null)
    {
      errors.Add("Username already exists.");
    }

    if (errors.Count > 0)
    {
      return new IUserService.RegisterNewUserResult(null, errors);
    }

    // create the new user
    var user = User.CreateNew(username, email, password, _passwordHasher);
    user = await _userRepository.AddAsync(user);

    return new IUserService.RegisterNewUserResult(user, null);
  }
  
  public async Task<IUserService.LoginResult> Login(string username, string password)
  {
    var user = await _userRepository.GetByUsernameAsync(username);
    if (user == null)
    {
      return new IUserService.LoginResult(null, "User not found.");
    }

    if (!user.VerifyPassword(password, _passwordHasher))
    {
      return new IUserService.LoginResult(null, "Wrong password.");
    }

    return new IUserService.LoginResult(user, null);
  }
}
