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<SiteConfiguration> _configurations;
        private readonly IMemoryCache _cache;
        private readonly IConfiguration _config;
        private readonly ILogger<SiteConfigurationService> _logger;
        private readonly TimeSpan _cacheExpiration = TimeSpan.FromMinutes(30);

        public SiteConfigurationService(
            IMongoDatabase database,
            IMemoryCache cache,
            IConfiguration config,
            ILogger<SiteConfigurationService> logger)
        {
            _database = database;
            _cache = cache;
            _config = config;
            _logger = logger;
            _configurations = _database.GetCollection<SiteConfiguration>("site_configurations");
        }

        public async Task<SiteConfiguration> GetConfigurationAsync(string language)
        {
            var cacheKey = $"site_config_{language}";

            if (_cache.TryGetValue(cacheKey, out SiteConfiguration? cachedConfig) && cachedConfig != null)
            {
                return cachedConfig;
            }

            try
            {
                var filter = Builders<SiteConfiguration>.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<SiteConfiguration>.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<PageContent?> 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<string> GenerateSitemapAsync()
        {
            var sb = new StringBuilder();
            sb.AppendLine("<?xml version=\"1.0\" encoding=\"UTF-8\"?>");
            sb.AppendLine("<urlset xmlns=\"http://www.sitemaps.org/schemas/sitemap/0.9\" xmlns:xhtml=\"http://www.w3.org/1999/xhtml\">");

            var baseUrl = _config.GetValue<string>("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("  <url>");
                    sb.AppendLine($"    <loc>{url}</loc>");
                    sb.AppendLine($"    <lastmod>{lastMod}</lastmod>");
                    sb.AppendLine($"    <changefreq>weekly</changefreq>");
                    sb.AppendLine($"    <priority>{priority}</priority>");

                    // Adicionar links alternativos (hreflang)
                    foreach (var altLang in languages)
                    {
                        var altUrl = BuildUrl(baseUrl, altLang, page);
                        sb.AppendLine($"    <xhtml:link rel=\"alternate\" hreflang=\"{altLang}\" href=\"{altUrl}\" />");
                    }

                    sb.AppendLine("  </url>");
                }
            }

            sb.AppendLine("</urlset>");
            return sb.ToString();
        }

        public async Task<string> GenerateRobotsAsync()
        {
            var sb = new StringBuilder();
            var baseUrl = _config.GetValue<string>("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<SiteConfiguration>.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<List<string>> GetAvailableLanguagesAsync()
        {
            const string cacheKey = "available_languages";

            if (_cache.TryGetValue(cacheKey, out List<string>? cachedLanguages) && cachedLanguages != null)
            {
                return cachedLanguages;
            }

            try
            {
                var projection = Builders<SiteConfiguration>.Projection.Include(x => x.Language);
                var languages = await _configurations
                    .Find(Builders<SiteConfiguration>.Filter.Empty)
                    .Project<SiteConfiguration>(projection)
                    .ToListAsync();

                var availableLanguages = languages.Select(x => x.Language).Distinct().ToList();

                if (!availableLanguages.Any())
                {
                    availableLanguages = new List<string> { "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<string> { "pt", "en", "es" };
            }
        }

        private async Task<SiteConfiguration> 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<bool> ConfigurationExistsAsync(string language)
        {
            try
            {
                var filter = Builders<SiteConfiguration>.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<SiteConfiguration>.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<string>("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<string>("SEO:GoogleTagManagerId") ?? "",
                    GoogleAnalyticsId = _config.GetValue<string>("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<string>("SEO:GoogleTagManagerId") ?? "",
                    GoogleAnalyticsId = _config.GetValue<string>("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<string>("SEO:GoogleTagManagerId") ?? "",
                    GoogleAnalyticsId = _config.GetValue<string>("SEO:GoogleAnalyticsId") ?? "",
                    Author = "Equipe Site de Conversão"
                }
            };
        }

        private Dictionary<string, PageContent> CreateDefaultPages(string language)
        {
            return language switch
            {
                "en" => new Dictionary<string, PageContent>
                {
                    ["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<string, PageContent>
                {
                    ["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<string, PageContent>
                {
                    ["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<FormField>
                {
                    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<FormField>
                {
                    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<FormField>
                {
                    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;
        }
    }
}
