using IamService.Infrastructure.Email;
using System.Linq;

namespace IamService.API.Application.Services;

/// <summary>
/// EN: OTP dispatcher abstraction for verification workflows.
/// VI: Abstraction gửi OTP cho các luồng xác thực.
/// </summary>
public interface IVerificationOtpDispatcher
{
    /// <summary>
    /// EN: Send OTP to phone number.
    /// VI: Gửi OTP đến số điện thoại.
    /// </summary>
    Task SendPhoneOtpAsync(Guid userId, string phoneNumber, string otp, CancellationToken cancellationToken = default);

    /// <summary>
    /// EN: Send OTP to email address.
    /// VI: Gửi OTP đến địa chỉ email.
    /// </summary>
    Task SendEmailOtpAsync(Guid userId, string email, string otp, CancellationToken cancellationToken = default);
}

/// <summary>
/// EN: Default OTP dispatcher implementation.
/// VI: Implementation mặc định của OTP dispatcher.
/// </summary>
public class VerificationOtpDispatcher : IVerificationOtpDispatcher
{
    private readonly IEmailService _emailService;
    private readonly ILogger<VerificationOtpDispatcher> _logger;

    public VerificationOtpDispatcher(
        IEmailService emailService,
        ILogger<VerificationOtpDispatcher> logger)
    {
        _emailService = emailService;
        _logger = logger;
    }

    public Task SendPhoneOtpAsync(
        Guid userId,
        string phoneNumber,
        string otp,
        CancellationToken cancellationToken = default)
    {
        _logger.LogInformation(
            "Phone OTP dispatch requested for user {UserId} to {MaskedPhone}.",
            userId,
            MaskPhoneNumber(phoneNumber));

        // EN: Placeholder SMS dispatch point (provider integration can be plugged in later).
        // VI: Điểm tích hợp gửi SMS (có thể cắm provider sau).
        _ = otp;
        _ = cancellationToken;
        return Task.CompletedTask;
    }

    public async Task SendEmailOtpAsync(
        Guid userId,
        string email,
        string otp,
        CancellationToken cancellationToken = default)
    {
        await _emailService.Send2FACodeAsync(email, otp, cancellationToken);
        _logger.LogInformation(
            "Email OTP dispatched for user {UserId} to {MaskedEmail}.",
            userId,
            MaskEmail(email));
    }

    private static string MaskEmail(string email)
    {
        var parts = email.Split('@');
        if (parts.Length != 2 || parts[0].Length < 2)
            return "***";

        var localPart = parts[0];
        var maskedLocal = $"{localPart[0]}***{localPart[^1]}";
        return $"{maskedLocal}@{parts[1]}";
    }

    private static string MaskPhoneNumber(string phoneNumber)
    {
        var digits = new string(phoneNumber.Where(char.IsDigit).ToArray());
        if (digits.Length <= 4)
            return "****";
        return $"***{digits[^4..]}";
    }
}
