using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Server.Kestrel.Core;
using MongoDB.Driver;
using OnlyOneAccessTemplate.Services;

var builder = WebApplication.CreateBuilder(args);

// Configurações otimizadas para produção ARM64
if (builder.Environment.IsProduction())
{
    // Configurar Kestrel para melhor performance
    builder.WebHost.ConfigureKestrel(options =>
    {
        options.Limits.MaxConcurrentConnections = 100;
        options.Limits.MaxConcurrentUpgradedConnections = 100;
        options.Limits.MaxRequestBodySize = 10 * 1024 * 1024; // 10MB
        options.Limits.MinRequestBodyDataRate = new MinDataRate(bytesPerSecond: 100, gracePeriod: TimeSpan.FromSeconds(10));
        options.Limits.MinResponseDataRate = new MinDataRate(bytesPerSecond: 100, gracePeriod: TimeSpan.FromSeconds(10));
        options.AddServerHeader = false;
    });

    // Configurações de logging otimizadas
    builder.Logging.ClearProviders();
    builder.Logging.AddConsole();
    builder.Logging.SetMinimumLevel(LogLevel.Warning);
}

// Add services to the container.
builder.Services.AddControllersWithViews(options =>
{
    if (builder.Environment.IsProduction())
    {
        // Configurações de cache para produção
        options.CacheProfiles.Add("Default", new CacheProfile()
        {
            Duration = 300 // 5 minutos
        });
    }
});

// Configurar Response Caching
builder.Services.AddResponseCaching(options =>
{
    options.MaximumBodySize = 1024 * 1024; // 1MB
    options.UseCaseSensitivePaths = false;
});

// Configurar Response Compression
builder.Services.AddResponseCompression(options =>
{
    options.EnableForHttps = true;
});

// Add services to the container
builder.Services.AddControllersWithViews();

// Session support
builder.Services.AddDistributedMemoryCache();
builder.Services.AddSession(options =>
{
    options.IdleTimeout = TimeSpan.FromMinutes(30);
    options.Cookie.HttpOnly = true;
    options.Cookie.IsEssential = true;
});

// MongoDB Configuration
builder.Services.AddSingleton<IMongoClient>(sp =>
{
    var connectionString = builder.Configuration.GetConnectionString("MongoDB");
    return new MongoClient(connectionString);
});

builder.Services.AddScoped(sp =>
{
    var client = sp.GetRequiredService<IMongoClient>();
    var databaseName = builder.Configuration.GetValue<string>("MongoDB:DatabaseName");
    return client.GetDatabase(databaseName);
});

// Custom Services
builder.Services.AddScoped<ISiteConfigurationService, SiteConfigurationService>();
builder.Services.AddScoped<ILanguageService, LanguageService>();
builder.Services.AddScoped<ISeoService, SeoService>();
builder.Services.AddScoped<IConversionService, ConversionService>();

// Converter Services - Registrar todos os conversores dispon�veis
builder.Services.AddScoped<TextCaseConverterService>();
builder.Services.AddScoped<CsvToJsonConverterService>();
builder.Services.AddScoped<ImageToTextConverterService>();

// Substituindo UpperLowerConversorService por API com Polly
builder.Services.AddHttpClient<ITextConversionApiService, TextConversionApiService>();
builder.Services.AddScoped<ApiBasedSentenceConverterService>();

// HttpClient for external calls
builder.Services.AddHttpClient<ConversionService>();
builder.Services.AddHttpClient<ImageToTextConverterService>();

// Response Compression
builder.Services.AddResponseCompression(options =>
{
    options.EnableForHttps = true;
});

// Response Caching
builder.Services.AddResponseCaching();

// Memory Cache
builder.Services.AddMemoryCache();

// Loggingbuilder.Logging.ClearProviders();
builder.Logging.AddConsole();
builder.Logging.AddDebug();

var app = builder.Build();

// Configure the HTTP request pipeline
if (!app.Environment.IsDevelopment())
{
    app.UseExceptionHandler("/Home/Error");
    app.UseHsts();
}

app.UseHttpsRedirection();
app.UseStaticFiles(new StaticFileOptions
{
    OnPrepareResponse = ctx =>
    {
        // Cache estático por 1 hora
        ctx.Context.Response.Headers.Append("Cache-Control", "public,max-age=3600");
    }
});

// Session
app.UseSession();

// Response Compression & Caching
app.UseResponseCompression();
app.UseResponseCaching();

app.UseRouting();

// Custom routing for multilingual support
app.MapControllerRoute(
    name: "converter-api",
    pattern: "converter/api/{action}/{converterType?}",
    defaults: new { controller = "Converter" });

app.MapControllerRoute(
    name: "converter-config",
    pattern: "converter/config/{converterType}",
    defaults: new { controller = "Converter", action = "GetConverterConfig" });

// Rotas específicas por idioma
app.MapControllerRoute(
    name: "multilingual",
    pattern: "{language:regex(en|es)}/{controller=Home}/{action=Index}/{id?}");

app.MapControllerRoute(
    name: "default",
    pattern: "{controller=Home}/{action=Index}/{id?}");

// SEO Routes
app.MapGet("/sitemap.xml", async (ISiteConfigurationService siteConfig) =>
{
    var sitemap = await siteConfig.GenerateSitemapAsync();
    return Results.Content(sitemap, "application/xml");
});

app.MapGet("/robots.txt", async (ISiteConfigurationService siteConfig) =>
{
    var robots = await siteConfig.GenerateRobotsAsync();
    return Results.Content(robots, "text/plain");
});

// Health check endpoint
app.MapGet("/health", () => Results.Ok(new { status = "healthy", timestamp = DateTime.UtcNow }));

// Initialize default data on startup (only in development)
if (app.Environment.IsDevelopment())
{
    using var scope = app.Services.CreateScope();
    var siteConfigService = scope.ServiceProvider.GetRequiredService<ISiteConfigurationService>();
    var logger = scope.ServiceProvider.GetRequiredService<ILogger<Program>>();

    try
    {
        // Verificar se j� existem configura��es
        var languages = new[] { "pt", "en", "es" };
        foreach (var lang in languages)
        {
            var configExists = await siteConfigService.ConfigurationExistsAsync(lang);
            if (!configExists)
            {
                logger.LogInformation("Criando configura��o padr�o para idioma: {Language}", lang);
                _ = await siteConfigService.GetConfigurationAsync(lang); // Isso criar� a configura��o padr�o
            }
        }
    }
    catch (Exception ex)
    {
        logger.LogError(ex, "Erro ao inicializar dados padr�o");
    }
}

app.Run();