using IamService.Domain.SeedWork;

namespace IamService.Domain.AggregatesModel.UserAggregate;

/// <summary>
/// EN: Phone number value object with validation and formatting.
/// VI: Value object số điện thoại với validation và formatting.
/// </summary>
public class PhoneNumber : ValueObject
{
    /// <summary>
    /// EN: Country code (e.g., +84, +1).
    /// VI: Mã quốc gia (ví dụ: +84, +1).
    /// </summary>
    public string CountryCode { get; }

    /// <summary>
    /// EN: National number without country code.
    /// VI: Số điện thoại quốc gia không có mã quốc gia.
    /// </summary>
    public string NationalNumber { get; }

    /// <summary>
    /// EN: Full phone number with country code.
    /// VI: Số điện thoại đầy đủ với mã quốc gia.
    /// </summary>
    public string FullNumber => $"{CountryCode}{NationalNumber}";

    /// <summary>
    /// EN: Private constructor for EF Core.
    /// VI: Constructor private cho EF Core.
    /// </summary>
    private PhoneNumber()
    {
        CountryCode = string.Empty;
        NationalNumber = string.Empty;
    }

    /// <summary>
    /// EN: Create a new phone number.
    /// VI: Tạo số điện thoại mới.
    /// </summary>
    public PhoneNumber(string countryCode, string nationalNumber)
    {
        if (string.IsNullOrWhiteSpace(countryCode))
            throw new ArgumentException("Country code cannot be empty", nameof(countryCode));
        if (string.IsNullOrWhiteSpace(nationalNumber))
            throw new ArgumentException("National number cannot be empty", nameof(nationalNumber));

        // EN: Normalize country code
        // VI: Chuẩn hóa mã quốc gia
        CountryCode = countryCode.StartsWith("+") ? countryCode : $"+{countryCode}";
        
        // EN: Remove non-digit characters from national number
        // VI: Xóa các ký tự không phải số khỏi số điện thoại
        NationalNumber = new string(nationalNumber.Where(char.IsDigit).ToArray());

        if (NationalNumber.Length < 7 || NationalNumber.Length > 15)
            throw new ArgumentException("National number must be between 7 and 15 digits", nameof(nationalNumber));
    }

    /// <summary>
    /// EN: Parse a full phone number string.
    /// VI: Parse chuỗi số điện thoại đầy đủ.
    /// </summary>
    public static PhoneNumber Parse(string fullNumber)
    {
        if (string.IsNullOrWhiteSpace(fullNumber))
            throw new ArgumentException("Phone number cannot be empty", nameof(fullNumber));

        // EN: Simple parsing - assumes format +XX NNNNNNNN or +XXXNNNNNNNN
        // VI: Parsing đơn giản - giả sử định dạng +XX NNNNNNNN hoặc +XXXNNNNNNNN
        var cleanNumber = new string(fullNumber.Where(c => char.IsDigit(c) || c == '+').ToArray());
        
        if (!cleanNumber.StartsWith("+"))
            throw new ArgumentException("Phone number must start with country code (+XX)", nameof(fullNumber));

        // EN: Assume first 1-3 digits after + are country code
        // VI: Giả sử 1-3 chữ số đầu tiên sau + là mã quốc gia
        var countryCodeLength = cleanNumber.Length switch
        {
            <= 10 => 2,  // +1 format (USA)
            <= 12 => 3,  // +84 format (Vietnam)
            _ => 3
        };

        var countryCode = cleanNumber[..(countryCodeLength + 1)]; // Include +
        var nationalNumber = cleanNumber[(countryCodeLength + 1)..];

        return new PhoneNumber(countryCode, nationalNumber);
    }

    /// <summary>
    /// EN: Format for display.
    /// VI: Định dạng để hiển thị.
    /// </summary>
    public string ToDisplayString()
    {
        // EN: Format as +XX XXX XXX XXXX
        // VI: Định dạng thành +XX XXX XXX XXXX
        if (NationalNumber.Length >= 10)
        {
            return $"{CountryCode} {NationalNumber[..3]} {NationalNumber[3..6]} {NationalNumber[6..]}";
        }
        return FullNumber;
    }

    protected override IEnumerable<object?> GetEqualityComponents()
    {
        yield return CountryCode;
        yield return NationalNumber;
    }
}
