#nullable enable
using System.Globalization;

namespace Baya.Application.Common;

/// <summary>
/// Cross-checks a credential's printed holder name against the nurse's verified identity name before the
/// credential is recorded — the documented defence against the "imposter nurse" forgery, where a real
/// license belonging to someone else is uploaded. Comparison is normalization-tolerant (ZWNJ, Arabic/Persian
/// yeh &amp; kaf variants, spacing, case) and order-insensitive on name tokens, but still rejects a genuinely
/// different name. An empty identity name fails closed (cannot cross-check ⇒ do not record).
/// </summary>
public static class IdentityNameMatch
{
    public static bool Matches(string? identityName, string? holderName)
    {
        var identityTokens = Tokenize(identityName);
        var holderTokens = Tokenize(holderName);

        if (identityTokens.Count == 0 || holderTokens.Count == 0)
            return false;

        return identityTokens.SetEquals(holderTokens);
    }

    private static HashSet<string> Tokenize(string? value)
    {
        var set = new HashSet<string>(StringComparer.Ordinal);
        if (string.IsNullOrWhiteSpace(value))
            return set;

        foreach (var token in Normalize(value).Split(' ', StringSplitOptions.RemoveEmptyEntries | StringSplitOptions.TrimEntries))
            set.Add(token);

        return set;
    }

    private static string Normalize(string value)
        => value
            .Replace('‌', ' ')  // ZWNJ → space so "علی‌رضا" and "علی رضا" tokenize the same
            .Replace('ي', 'ی') // Arabic yeh → Persian yeh
            .Replace('ك', 'ک') // Arabic kaf → Persian kaf
            .Trim()
            .ToLower(CultureInfo.InvariantCulture);
}
