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 GetPageContentAsync(string language, string pageName) { var configuration = await GetConfigurationAsync(language); if (configuration.Pages.TryGetValue(pageName.ToLowerInvariant(), out var pageContent)) { return pageContent; } return null; } 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 = new SiteConfiguration { Language = language, Seo = CreateDefaultSeoConfig(language), Pages = CreateDefaultPages(language), Conversion = CreateDefaultConversionConfig(language), CreatedAt = DateTime.UtcNow, UpdatedAt = DateTime.UtcNow }; 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) { var defaultConfig = new SiteConfiguration { Language = language, Seo = CreateDefaultSeoConfig(language), Pages = CreateDefaultPages(language), Conversion = CreateDefaultConversionConfig(language), CreatedAt = DateTime.UtcNow, UpdatedAt = DateTime.UtcNow }; return defaultConfig; } 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 SeoConfig CreateDefaultSeoConfig(string language) { var defaultSiteName = _config.GetValue("SEO:DefaultSiteName") ?? "Site de Conversão"; return language switch { "en" => new SeoConfig { SiteName = defaultSiteName, DefaultTitle = "Conversion Site - Transform Your Business", DefaultDescription = "Professional conversion solutions to boost your business results", DefaultKeywords = "conversion, business, marketing, results", TwitterCard = "summary_large_image", GoogleTagManagerId = _config.GetValue("SEO:GoogleTagManagerId") ?? "", GoogleAnalyticsId = _config.GetValue("SEO:GoogleAnalyticsId") ?? "", Author = "Conversion Site Team" }, "es" => new SeoConfig { SiteName = defaultSiteName, DefaultTitle = "Sitio de Conversión - Transforma Tu Negocio", DefaultDescription = "Soluciones profesionales de conversión para potenciar los resultados de tu negocio", DefaultKeywords = "conversión, negocio, marketing, resultados", TwitterCard = "summary_large_image", GoogleTagManagerId = _config.GetValue("SEO:GoogleTagManagerId") ?? "", GoogleAnalyticsId = _config.GetValue("SEO:GoogleAnalyticsId") ?? "", Author = "Equipo Sitio de Conversión" }, _ => new SeoConfig { SiteName = defaultSiteName, DefaultTitle = "Site de Conversão - Transforme Seu Negócio", DefaultDescription = "Soluções profissionais de conversão para alavancar os resultados do seu negócio", DefaultKeywords = "conversão, negócio, marketing, resultados", TwitterCard = "summary_large_image", GoogleTagManagerId = _config.GetValue("SEO:GoogleTagManagerId") ?? "", GoogleAnalyticsId = _config.GetValue("SEO:GoogleAnalyticsId") ?? "", Author = "Equipe Site de Conversão" } }; } private Dictionary CreateDefaultPages(string language) { return language switch { "en" => new Dictionary { ["index"] = new PageContent { Title = "Home - Transform Your Business", Description = "Professional conversion solutions to boost your business results", H1 = "Transform Your Business Today", MetaTitle = "Business Transformation | Conversion Solutions" }, ["about"] = new PageContent { Title = "About Us - Our Mission", Description = "Learn about our mission to help businesses achieve better conversion rates", H1 = "About Our Company", MetaTitle = "About Us | Conversion Experts" } }, "es" => new Dictionary { ["index"] = new PageContent { Title = "Inicio - Transforma Tu Negocio", Description = "Soluciones profesionales de conversión para potenciar los resultados de tu negocio", H1 = "Transforma Tu Negocio Hoy", MetaTitle = "Transformación Empresarial | Soluciones de Conversión" }, ["about"] = new PageContent { Title = "Acerca de Nosotros - Nuestra Misión", Description = "Conoce nuestra misión de ayudar a las empresas a lograr mejores tasas de conversión", H1 = "Acerca de Nuestra Empresa", MetaTitle = "Acerca de Nosotros | Expertos en Conversión" } }, _ => new Dictionary { ["index"] = new PageContent { Title = "Início - Transforme Seu Negócio", Description = "Soluções profissionais de conversão para alavancar os resultados do seu negócio", H1 = "Transforme Seu Negócio Hoje", MetaTitle = "Transformação Empresarial | Soluções de Conversão" }, ["about"] = new PageContent { Title = "Sobre Nós - Nossa Missão", Description = "Conheça nossa missão de ajudar empresas a alcançar melhores taxas de conversão", H1 = "Sobre Nossa Empresa", MetaTitle = "Sobre Nós | Especialistas em Conversão" } } }; } private ConversionConfig CreateDefaultConversionConfig(string language) { return new ConversionConfig { FormAction = "/conversion/submit", ThankYouPage = language switch { "en" => "/thank-you", "es" => "/gracias", _ => "/obrigado" }, FormFields = language switch { "en" => new List { new() { Name = "name", Type = "text", Label = "Full Name", Placeholder = "Enter your full name", Required = true, Order = 1 }, new() { Name = "email", Type = "email", Label = "Email", Placeholder = "Enter your email", Required = true, Order = 2 }, new() { Name = "phone", Type = "tel", Label = "Phone", Placeholder = "Enter your phone number", Required = false, Order = 3 } }, "es" => new List { new() { Name = "name", Type = "text", Label = "Nombre Completo", Placeholder = "Ingresa tu nombre completo", Required = true, Order = 1 }, new() { Name = "email", Type = "email", Label = "Correo Electrónico", Placeholder = "Ingresa tu correo", Required = true, Order = 2 }, new() { Name = "phone", Type = "tel", Label = "Teléfono", Placeholder = "Ingresa tu número de teléfono", Required = false, Order = 3 } }, _ => new List { new() { Name = "name", Type = "text", Label = "Nome Completo", Placeholder = "Digite seu nome completo", Required = true, Order = 1 }, new() { Name = "email", Type = "email", Label = "E-mail", Placeholder = "Digite seu e-mail", Required = true, Order = 2 }, new() { Name = "phone", Type = "tel", Label = "Telefone", Placeholder = "Digite seu telefone", Required = false, Order = 3 } } } }; } 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; } } }