using System.Globalization;

namespace QRRapidoApp.Middleware
{
    public class LanguageRedirectionMiddleware
    {
        private readonly RequestDelegate _next;
        private readonly ILogger<LanguageRedirectionMiddleware> _logger;
        private readonly string[] _supportedCultures = { "pt-BR", "es-PY" };
        private const string DefaultCulture = "pt-BR";

        public LanguageRedirectionMiddleware(RequestDelegate next, ILogger<LanguageRedirectionMiddleware> logger)
        {
            _next = next;
            _logger = logger;
        }

        public async Task InvokeAsync(HttpContext context)
        {
            var path = context.Request.Path.Value?.TrimStart('/') ?? "";

            if (HasCultureInPath(path) || IsSpecialRoute(path))
            {
                await _next(context);
                return;
            }

            var detectedCulture = DetectBrowserLanguage(context);

            // If the detected culture is the default, do not redirect.
            if (detectedCulture == DefaultCulture)
            {
                await _next(context);
                return;
            }

            var redirectUrl = $"/{detectedCulture}";
            if (!string.IsNullOrEmpty(path))
            {
                redirectUrl += $"/{path}";
            }

            if (context.Request.QueryString.HasValue)
            {
                redirectUrl += context.Request.QueryString.Value;
            }

            _logger.LogInformation("Redirecting to localized URL: {RedirectUrl} (detected culture: {Culture})",
                redirectUrl, detectedCulture);

            context.Response.Redirect(redirectUrl, permanent: false);
        }

        private bool HasCultureInPath(string path)
        {
            if (string.IsNullOrEmpty(path))
                return false;

            var segments = path.Split('/', StringSplitOptions.RemoveEmptyEntries);
            if (segments.Length == 0)
                return false;

            return _supportedCultures.Contains(segments[0]);
        }

        private bool IsSpecialRoute(string path)
        {
            var specialRoutes = new[]
            {
                "api/", "health", "_framework/", "lib/", "css/", "js/", "images/",
                "favicon.ico", "robots.txt", "sitemap.xml",
                "signin-microsoft", "signin-google", "signout-callback-oidc",
                "Account/ExternalLoginCallback", "Account/Logout", "Pagamento/CreateCheckout",
                "Pagamento/StripeWebhook", "api/QR", "Home/Error", "ads.txt"
            };

            return specialRoutes.Any(route => path.StartsWith(route, StringComparison.OrdinalIgnoreCase));
        }

        private string DetectBrowserLanguage(HttpContext context)
        {
            var acceptLanguage = context.Request.GetTypedHeaders().AcceptLanguage;

            if (acceptLanguage != null && acceptLanguage.Any())
            {
                foreach (var lang in acceptLanguage.OrderByDescending(x => x.Quality ?? 1.0))
                {
                    var langCode = lang.Value.Value;

                    // Exact match for es-PY
                    if (string.Equals(langCode, "es-PY", StringComparison.OrdinalIgnoreCase))
                    {
                        return "es-PY";
                    }

                    // Generic 'es' maps to 'es-PY'
                    if (langCode.StartsWith("es-", StringComparison.OrdinalIgnoreCase) || string.Equals(langCode, "es", StringComparison.OrdinalIgnoreCase))
                    {
                        return "es-PY";
                    }
                    
                    // Check for pt-BR
                    if (langCode.StartsWith("pt-", StringComparison.OrdinalIgnoreCase) || string.Equals(langCode, "pt", StringComparison.OrdinalIgnoreCase))
                    {
                        return "pt-BR";
                    }
                }
            }

            return DefaultCulture;
        }
    }
}