// EN: Handler for ConfirmEmailCommand
// VI: Handler cho ConfirmEmailCommand

using MediatR;
using Microsoft.AspNetCore.Identity;
using Microsoft.Extensions.Logging;
using IamService.Domain.AggregatesModel.UserAggregate;

namespace IamService.API.Application.Commands.Auth;

/// <summary>
/// EN: Handler for ConfirmEmailCommand.
/// VI: Handler cho ConfirmEmailCommand.
/// </summary>
public class ConfirmEmailCommandHandler : IRequestHandler<ConfirmEmailCommand, ConfirmEmailResult>
{
    private readonly UserManager<ApplicationUser> _userManager;
    private readonly ILogger<ConfirmEmailCommandHandler> _logger;

    public ConfirmEmailCommandHandler(
        UserManager<ApplicationUser> userManager,
        ILogger<ConfirmEmailCommandHandler> logger)
    {
        _userManager = userManager;
        _logger = logger;
    }

    public async Task<ConfirmEmailResult> Handle(
        ConfirmEmailCommand request,
        CancellationToken cancellationToken)
    {
        _logger.LogInformation("Confirming email for {Email}", request.Email);

        // EN: Find user by email
        // VI: Tìm user theo email
        var user = await _userManager.FindByEmailAsync(request.Email);
        if (user == null)
        {
            _logger.LogWarning("User not found with email {Email}", request.Email);
            return new ConfirmEmailResult(false, "Invalid email or token.");
        }

        // EN: Check if email is already confirmed
        // VI: Kiểm tra xem email đã được xác nhận chưa
        if (user.EmailConfirmed)
        {
            _logger.LogInformation("Email {Email} is already confirmed", request.Email);
            return new ConfirmEmailResult(true, "Email is already verified.");
        }

        // EN: Confirm email with token
        // VI: Xác nhận email với token
        var result = await _userManager.ConfirmEmailAsync(user, request.Token);

        if (!result.Succeeded)
        {
            var errors = string.Join(", ", result.Errors.Select(e => e.Description));
            _logger.LogWarning("Failed to confirm email for {Email}: {Errors}", request.Email, errors);
            return new ConfirmEmailResult(false, "Invalid or expired token.");
        }

        _logger.LogInformation("Email confirmed successfully for {Email}", request.Email);

        return new ConfirmEmailResult(true, "Email confirmed successfully.");
    }
}
