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

namespace IamService.API.Application.Commands.Verifications;

/// <summary>
/// EN: Handler for RequestPhoneVerificationCommand.
/// VI: Handler cho RequestPhoneVerificationCommand.
/// </summary>
public class RequestPhoneVerificationCommandHandler 
    : IRequestHandler<RequestPhoneVerificationCommand, RequestVerificationCommandResult>
{
    private readonly IIdentityVerificationRepository _verificationRepository;
    private readonly ILogger<RequestPhoneVerificationCommandHandler> _logger;

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

    public async Task<RequestVerificationCommandResult> Handle(
        RequestPhoneVerificationCommand request,
        CancellationToken cancellationToken)
    {
        _logger.LogInformation("Requesting phone verification for user: {UserId}", request.UserId);

        // EN: Check if there's an active verification
        // VI: Kiểm tra có verification đang hoạt động không
        var existingVerification = await _verificationRepository.GetActiveByUserIdAndTypeAsync(
            request.UserId,
            VerificationType.Phone,
            cancellationToken);

        if (existingVerification != null)
        {
            throw new DomainException("A phone verification is already pending. Please wait for it to expire or complete it.");
        }

        // EN: Create new phone verification
        // VI: Tạo xác thực điện thoại mới
        var (verification, otp) = IdentityVerification.CreatePhoneVerification(
            request.UserId,
            request.PhoneNumber);

        _verificationRepository.Add(verification);

        await _verificationRepository.UnitOfWork.SaveEntitiesAsync(cancellationToken);

        // EN: TODO: Send OTP via SMS service
        // VI: TODO: Gửi OTP qua SMS service
        _logger.LogInformation(
            "Phone verification created for user {UserId}. OTP: {OTP} (in production, send via SMS)",
            request.UserId,
            otp);  // EN: Remove OTP from logs in production!

        return new RequestVerificationCommandResult(
            verification.Id,
            VerificationType.Phone.Name,
            verification.ExpiresAt,
            "Verification code sent to your phone number.");
    }
}

/// <summary>
/// EN: Handler for RequestEmailVerificationCommand.
/// VI: Handler cho RequestEmailVerificationCommand.
/// </summary>
public class RequestEmailVerificationCommandHandler 
    : IRequestHandler<RequestEmailVerificationCommand, RequestVerificationCommandResult>
{
    private readonly IIdentityVerificationRepository _verificationRepository;
    private readonly ILogger<RequestEmailVerificationCommandHandler> _logger;

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

    public async Task<RequestVerificationCommandResult> Handle(
        RequestEmailVerificationCommand request,
        CancellationToken cancellationToken)
    {
        _logger.LogInformation("Requesting email verification for user: {UserId}", request.UserId);

        // EN: Check if there's an active verification
        // VI: Kiểm tra có verification đang hoạt động không
        var existingVerification = await _verificationRepository.GetActiveByUserIdAndTypeAsync(
            request.UserId,
            VerificationType.Email,
            cancellationToken);

        if (existingVerification != null)
        {
            throw new DomainException("An email verification is already pending. Please wait for it to expire or complete it.");
        }

        // EN: Create new email verification (using phone verification method with email type)
        // VI: Tạo xác thực email mới
        var (verification, otp) = IdentityVerification.CreatePhoneVerification(
            request.UserId,
            request.Email);

        // EN: Update type to Email
        // VI: Cập nhật loại thành Email
        // Note: In real implementation, we would have a separate factory method for email
        _verificationRepository.Add(verification);

        await _verificationRepository.UnitOfWork.SaveEntitiesAsync(cancellationToken);

        // EN: TODO: Send OTP via Email service
        // VI: TODO: Gửi OTP qua Email service
        _logger.LogInformation(
            "Email verification created for user {UserId}. OTP: {OTP} (in production, send via Email)",
            request.UserId,
            otp);

        return new RequestVerificationCommandResult(
            verification.Id,
            VerificationType.Email.Name,
            verification.ExpiresAt,
            "Verification code sent to your email address.");
    }
}
