using Application.Auth.DTOs;
using Domain.Ports.Repositories;
using MediatR;

namespace Application.Auth.Commands;

public record ResetPasswordCommand(
    string Username,
    string RecoveryCode,
    string NewPassword
) : IRequest<ResetPasswordResponse>;

public class ResetPasswordCommandHandler(
    IUserRepository userRepository,
    IPasswordService passwordService,
    IUnitOfWork unitOfWork
) : IRequestHandler<ResetPasswordCommand, ResetPasswordResponse>
{
    public async Task<ResetPasswordResponse> Handle(ResetPasswordCommand request, CancellationToken ct)
    {
        // Validate new password
        if (request.NewPassword.Length < 6)
            return new ResetPasswordResponse(false, "La nueva contrasena debe tener al menos 6 caracteres");

        // Find user
        var user = await userRepository.GetByUsernameAsync(request.Username, ct);
        if (user is null)
            return new ResetPasswordResponse(false, "Usuario no encontrado");

        // Verify recovery code
        if (!passwordService.VerifyPassword(request.RecoveryCode, user.RecoveryCodeHash))
            return new ResetPasswordResponse(false, "Codigo de recuperacion invalido");

        // Update password
        var newPasswordHash = passwordService.HashPassword(request.NewPassword);
        user.UpdatePassword(newPasswordHash);

        await unitOfWork.SaveChangesAsync(ct);

        return new ResetPasswordResponse(true);
    }
}
