using System.Text;
using System.Text.RegularExpressions;

namespace Meezi.Core.Utilities;

/// <summary>
/// Converts Persian/Arabic café names to URL-safe Latin slugs.
/// Used for Koja profile URLs (koja.meezi.ir/fa/cafe/{slug}).
/// </summary>
public static partial class SlugHelper
{
    private static readonly Dictionary<char, string> PersianToLatin = new()
    {
        // Alef variants
        { 'آ', "a" }, { 'ا', "a" }, { 'أ', "a" }, { 'إ', "a" },
        // Ba, Pa, Ta, Tha
        { 'ب', "b" }, { 'پ', "p" }, { 'ت', "t" }, { 'ث', "s" },
        // Jim, Che, He, Khe
        { 'ج', "j" }, { 'چ', "ch" }, { 'ح', "h" }, { 'خ', "kh" },
        // Dal, Zal, Re, Ze, Zhe
        { 'د', "d" }, { 'ذ', "z" }, { 'ر', "r" }, { 'ز', "z" }, { 'ژ', "zh" },
        // Sin, Shin, Sad, Zad
        { 'س', "s" }, { 'ش', "sh" }, { 'ص', "s" }, { 'ض', "z" },
        // Ta, Za, Ain, Ghain
        { 'ط', "t" }, { 'ظ', "z" }, { 'ع', "a" }, { 'غ', "gh" },
        // Fa, Ghaf, Kaf (Arabic+Persian), Gaf
        { 'ف', "f" }, { 'ق', "gh" }, { 'ک', "k" }, { 'ك', "k" }, { 'گ', "g" },
        // Lam, Mim, Nun, Vav, He, Ye
        { 'ل', "l" }, { 'م', "m" }, { 'ن', "n" }, { 'و', "v" },
        { 'ه', "h" }, { 'ی', "i" }, { 'ي', "i" },
        // Special
        { 'ئ', "y" }, { 'ء', "" }, { 'ة', "t" }, { 'ى', "a" }, { 'ؤ', "o" },
        // Persian digits
        { '۰', "0" }, { '۱', "1" }, { '۲', "2" }, { '۳', "3" }, { '۴', "4" },
        { '۵', "5" }, { '۶', "6" }, { '۷', "7" }, { '۸', "8" }, { '۹', "9" },
        // Arabic-Indic digits
        { '٠', "0" }, { '١', "1" }, { '٢', "2" }, { '٣', "3" }, { '٤', "4" },
        { '٥', "5" }, { '٦', "6" }, { '٧', "7" }, { '٨', "8" }, { '٩', "9" },
    };

    /// <summary>
    /// Converts a café name (Persian or Latin) to a URL-safe lowercase slug.
    /// Returns an empty string if no valid characters can be extracted.
    /// </summary>
    public static string Slugify(string input)
    {
        if (string.IsNullOrWhiteSpace(input)) return string.Empty;

        var sb = new StringBuilder(input.Length * 2);
        foreach (var ch in input)
        {
            if (PersianToLatin.TryGetValue(ch, out var latin))
            {
                sb.Append(latin);
            }
            else if (char.IsAsciiLetterOrDigit(ch))
            {
                sb.Append(char.ToLowerInvariant(ch));
            }
            else if (ch is ' ' or '-' or '_' or '\t')
            {
                sb.Append('-');
            }
            // else: skip punctuation/unsupported characters
        }

        // Collapse consecutive hyphens and trim
        return MultipleHyphen().Replace(sb.ToString(), "-").Trim('-');
    }

    /// <summary>
    /// Returns true if the slug is a valid Koja URL slug:
    /// 2–80 lowercase letters, digits, or internal hyphens. Must start and end with a letter/digit.
    /// </summary>
    public static bool IsValidSlug(string? slug)
    {
        if (string.IsNullOrWhiteSpace(slug)) return false;
        if (slug.Length < 2 || slug.Length > 80) return false;
        return ValidSlugPattern().IsMatch(slug);
    }

    [GeneratedRegex(@"-{2,}")]
    private static partial Regex MultipleHyphen();

    [GeneratedRegex(@"^[a-z0-9][a-z0-9\-]*[a-z0-9]$")]
    private static partial Regex ValidSlugPattern();
}
