using MongoDB.Driver; using Microsoft.Extensions.Caching.Memory; using System.Text; using OnlyOneAccessTemplate.Models; namespace OnlyOneAccessTemplate.Services { public class SiteConfigurationService : ISiteConfigurationService { private readonly IMongoDatabase _database; private readonly IMongoCollection _configurations; private readonly IMemoryCache _cache; private readonly IConfiguration _config; private readonly ILogger _logger; private readonly TimeSpan _cacheExpiration = TimeSpan.FromMinutes(30); public SiteConfigurationService( IMongoDatabase database, IMemoryCache cache, IConfiguration config, ILogger logger) { _database = database; _cache = cache; _config = config; _logger = logger; _configurations = _database.GetCollection("site_configurations"); } public async Task GetConfigurationAsync(string language) { var cacheKey = $"site_config_{language}"; if (_cache.TryGetValue(cacheKey, out SiteConfiguration? cachedConfig) && cachedConfig != null) { return cachedConfig; } try { var filter = Builders.Filter.Eq(x => x.Language, language); var configuration = await _configurations.Find(filter).FirstOrDefaultAsync(); if (configuration == null) { configuration = await CreateDefaultConfigurationAsync(language); } _cache.Set(cacheKey, configuration, _cacheExpiration); return configuration; } catch (Exception ex) { _logger.LogError(ex, "Erro ao buscar configuração para idioma {Language}", language); return await CreateDefaultConfigurationAsync(language); } } public SiteConfiguration GetConfiguration(string language) { var cacheKey = $"site_config_{language}"; if (_cache.TryGetValue(cacheKey, out SiteConfiguration? cachedConfig) && cachedConfig != null) { return cachedConfig; } try { var filter = Builders.Filter.Eq(x => x.Language, language); var configuration = _configurations.Find(filter).FirstOrDefault(); if (configuration == null) { configuration = CreateDefaultConfiguration(language); } _cache.Set(cacheKey, configuration, _cacheExpiration); return configuration; } catch (Exception ex) { _logger.LogError(ex, "Erro ao buscar configuração para idioma {Language}", language); return CreateDefaultConfiguration(language); } } public async Task GenerateSitemapAsync() { var sb = new StringBuilder(); sb.AppendLine(""); sb.AppendLine(""); var baseUrl = _config.GetValue("SEO:DefaultDomain") ?? "https://localhost"; var languages = await GetAvailableLanguagesAsync(); // Páginas principais para cada idioma var mainPages = new[] { "", "about", "contact", "privacy", "terms" }; foreach (var page in mainPages) { foreach (var lang in languages) { var url = BuildUrl(baseUrl, lang, page); var lastMod = DateTime.UtcNow.ToString("yyyy-MM-ddTHH:mm:ssZ"); var priority = page == "" ? "1.0" : "0.8"; sb.AppendLine(" "); sb.AppendLine($" {url}"); sb.AppendLine($" {lastMod}"); sb.AppendLine($" weekly"); sb.AppendLine($" {priority}"); // Adicionar links alternativos (hreflang) foreach (var altLang in languages) { var altUrl = BuildUrl(baseUrl, altLang, page); sb.AppendLine($" "); } sb.AppendLine(" "); } } sb.AppendLine(""); return sb.ToString(); } public async Task GenerateRobotsAsync() { var sb = new StringBuilder(); var baseUrl = _config.GetValue("SEO:DefaultDomain") ?? "https://localhost"; sb.AppendLine("User-agent: *"); sb.AppendLine("Allow: /"); sb.AppendLine(""); sb.AppendLine("# Sitemaps"); sb.AppendLine($"Sitemap: {baseUrl}/sitemap.xml"); sb.AppendLine(""); sb.AppendLine("# Crawl delay"); sb.AppendLine("Crawl-delay: 1"); return sb.ToString(); } public async Task UpdateConfigurationAsync(SiteConfiguration config) { try { config.UpdatedAt = DateTime.UtcNow; var filter = Builders.Filter.Eq(x => x.Language, config.Language); var options = new ReplaceOptions { IsUpsert = true }; await _configurations.ReplaceOneAsync(filter, config, options); // Invalidar cache var cacheKey = $"site_config_{config.Language}"; _cache.Remove(cacheKey); _logger.LogInformation("Configuração atualizada para idioma {Language}", config.Language); } catch (Exception ex) { _logger.LogError(ex, "Erro ao atualizar configuração para idioma {Language}", config.Language); throw; } } public async Task> GetAvailableLanguagesAsync() { const string cacheKey = "available_languages"; if (_cache.TryGetValue(cacheKey, out List? cachedLanguages) && cachedLanguages != null) { return cachedLanguages; } try { var projection = Builders.Projection.Include(x => x.Language); var languages = await _configurations .Find(Builders.Filter.Empty) .Project(projection) .ToListAsync(); var availableLanguages = languages.Select(x => x.Language).Distinct().ToList(); if (!availableLanguages.Any()) { availableLanguages = new List { "pt", "en", "es" }; } _cache.Set(cacheKey, availableLanguages, TimeSpan.FromHours(1)); return availableLanguages; } catch (Exception ex) { _logger.LogError(ex, "Erro ao buscar idiomas disponíveis"); return new List { "pt", "en", "es" }; } } private async Task CreateDefaultConfigurationAsync(string language) { var defaultConfig = CreateDefaultConfiguration(language); try { await _configurations.InsertOneAsync(defaultConfig); _logger.LogInformation("Configuração padrão criada para idioma {Language}", language); } catch (Exception ex) { _logger.LogError(ex, "Erro ao criar configuração padrão para idioma {Language}", language); } return defaultConfig; } private SiteConfiguration CreateDefaultConfiguration(string language) { return language switch { "en" => new SiteConfiguration { Language = "en", Currency = "USD", CountryCode = "US", SiteTitle = "Convert-it Online - Free Converters", SiteDescription = "Convert your files online for free. PDF to Word, images, text and much more.", SiteKeywords = "convert, converter, pdf, word, text, online, free", HomePage = new HomePageContent { MainTitle = "Free Online Converters", MainDescription = "Convert your files quickly and securely", CallToAction = "Choose your converter" } }, "es" => new SiteConfiguration { Language = "es", Currency = "EUR", CountryCode = "ES", SiteTitle = "Convert-it Online - Convertidores Gratuitos", SiteDescription = "Convierte tus archivos en línea gratis. PDF a Word, imágenes, texto y mucho más.", SiteKeywords = "convertir, convertidor, pdf, word, texto, en línea, gratis", HomePage = new HomePageContent { MainTitle = "Convertidores en Línea Gratuitos", MainDescription = "Convierte tus archivos rápidamente y con seguridad", CallToAction = "Elige tu convertidor" } }, _ => new SiteConfiguration { Language = "pt", Currency = "BRL", CountryCode = "BR", SiteTitle = "Convert-it Online - Conversores Gratuitos", SiteDescription = "Converta seus arquivos online gratuitamente. PDF para Word, imagens, textos e muito mais.", SiteKeywords = "converter, conversor, pdf, word, texto, online, grátis", HomePage = new HomePageContent { MainTitle = "Conversores Online Gratuitos", MainDescription = "Converta seus arquivos rapidamente e com segurança", CallToAction = "Escolha seu conversor" } } }; } public async Task ConfigurationExistsAsync(string language) { try { var filter = Builders.Filter.Eq(x => x.Language, language); var count = await _configurations.CountDocumentsAsync(filter); return count > 0; } catch (Exception ex) { _logger.LogError(ex, "Erro ao verificar se configuração existe para idioma {Language}", language); return false; } } public async Task DeleteConfigurationAsync(string language) { try { var filter = Builders.Filter.Eq(x => x.Language, language); await _configurations.DeleteOneAsync(filter); // Invalidar cache var cacheKey = $"site_config_{language}"; _cache.Remove(cacheKey); _logger.LogInformation("Configuração deletada para idioma {Language}", language); } catch (Exception ex) { _logger.LogError(ex, "Erro ao deletar configuração para idioma {Language}", language); throw; } } private string BuildUrl(string baseUrl, string language, string page) { var url = baseUrl.TrimEnd('/'); if (language != "pt") // português é o padrão { url += $"/{language}"; } if (!string.IsNullOrEmpty(page)) { url += $"/{page}"; } return url; } } }