using System.Globalization; using System.Text.RegularExpressions; using System.Text; namespace BCards.Web.Utils { public static class SlugHelper { /// /// Remove acentos e caracteres especiais, criando um slug limpo /// public static string RemoveAccents(string text) { if (string.IsNullOrWhiteSpace(text)) return string.Empty; // Normalizar para NFD (decompor caracteres acentuados) var normalizedString = text.Normalize(NormalizationForm.FormD); var stringBuilder = new StringBuilder(); // Filtrar apenas caracteres que não são marcas diacríticas foreach (var c in normalizedString) { var unicodeCategory = CharUnicodeInfo.GetUnicodeCategory(c); if (unicodeCategory != UnicodeCategory.NonSpacingMark) { stringBuilder.Append(c); } } return stringBuilder.ToString().Normalize(NormalizationForm.FormC); } /// /// Cria um slug limpo e URL-friendly /// public static string CreateSlug(string text) { if (string.IsNullOrWhiteSpace(text)) return string.Empty; // 1. Remover acentos var slug = RemoveAccents(text); // 2. Converter para minúsculas slug = slug.ToLowerInvariant(); // 3. Substituir espaços e caracteres especiais por hífen slug = Regex.Replace(slug, @"[^a-z0-9\s-]", ""); // 4. Substituir múltiplos espaços por hífen único slug = Regex.Replace(slug, @"[\s-]+", "-"); // 5. Remover hífens do início e fim slug = slug.Trim('-'); // 6. Limitar tamanho (opcional) if (slug.Length > 50) slug = slug.Substring(0, 50).TrimEnd('-'); return slug; } /// /// Cria uma categoria limpa (sem acentos, minúscula) /// public static string CreateCategorySlug(string category) { if (string.IsNullOrWhiteSpace(category)) return string.Empty; var slug = RemoveAccents(category); slug = slug.ToLowerInvariant(); slug = Regex.Replace(slug, @"[^a-z0-9]", ""); return slug; } /// /// Dicionário de conversões comuns para categorias brasileiras /// private static readonly Dictionary CategoryMappings = new() { { "saúde", "saude" }, { "educação", "educacao" }, { "tecnologia", "tecnologia" }, { "negócios", "negocios" }, { "serviços", "servicos" }, { "alimentação", "alimentacao" }, { "construção", "construcao" }, { "automóveis", "automoveis" }, { "beleza", "beleza" }, { "esportes", "esportes" }, { "música", "musica" }, { "fotografia", "fotografia" } }; /// /// Converte categoria com mapeamento personalizado /// public static string ConvertCategory(string category) { if (string.IsNullOrWhiteSpace(category)) return string.Empty; var lowerCategory = category.ToLowerInvariant().Trim(); // Verificar mapeamento direto if (CategoryMappings.ContainsKey(lowerCategory)) return CategoryMappings[lowerCategory]; // Fallback para conversão automática return CreateCategorySlug(category); } } }