using MediatR;
using IamService.Domain.AggregatesModel.VerificationAggregate;
using IamService.Domain.Exceptions;

namespace IamService.API.Application.Commands.Verifications;

/// <summary>
/// EN: Handler for ConfirmVerificationCommand.
/// VI: Handler cho ConfirmVerificationCommand.
/// </summary>
public class ConfirmVerificationCommandHandler 
    : IRequestHandler<ConfirmVerificationCommand, ConfirmVerificationCommandResult>
{
    private readonly IIdentityVerificationRepository _verificationRepository;
    private readonly ILogger<ConfirmVerificationCommandHandler> _logger;

    public ConfirmVerificationCommandHandler(
        IIdentityVerificationRepository verificationRepository,
        ILogger<ConfirmVerificationCommandHandler> logger)
    {
        _verificationRepository = verificationRepository;
        _logger = logger;
    }

    public async Task<ConfirmVerificationCommandResult> Handle(
        ConfirmVerificationCommand request,
        CancellationToken cancellationToken)
    {
        _logger.LogInformation("Confirming verification: {VerificationId}", request.VerificationId);

        var verification = await _verificationRepository.GetByIdAsync(request.VerificationId, cancellationToken);

        if (verification == null)
        {
            throw new DomainException($"Verification with ID '{request.VerificationId}' not found.");
        }

        // EN: Verify the code
        // VI: Xác minh mã
        var isValid = verification.VerifyCode(request.Code);

        if (!isValid)
        {
            _verificationRepository.Update(verification);
            await _verificationRepository.UnitOfWork.SaveEntitiesAsync(cancellationToken);

            _logger.LogWarning(
                "Invalid verification code for {VerificationId}. Attempts: {AttemptCount}",
                request.VerificationId,
                verification.AttemptCount);

            return new ConfirmVerificationCommandResult(
                verification.Id,
                false,
                verification.Status.Name,
                null);
        }

        _verificationRepository.Update(verification);
        await _verificationRepository.UnitOfWork.SaveEntitiesAsync(cancellationToken);

        _logger.LogInformation(
            "Verification {VerificationId} confirmed successfully",
            request.VerificationId);

        return new ConfirmVerificationCommandResult(
            verification.Id,
            true,
            verification.Status.Name,
            verification.VerifiedAt);
    }
}
