using Common.Global;
using Database.Database;
using Esim.Apis.Business;
using log4net;
using log4net.Config;
using Microsoft.AspNetCore.Authentication.JwtBearer;
using Microsoft.EntityFrameworkCore;
using Microsoft.IdentityModel.Tokens;
using System.Security.Cryptography;
using System.Text;

var builder = WebApplication.CreateBuilder(args);

// Initialize log4net
XmlConfigurator.Configure(
    new FileInfo(Path.Combine(builder.Environment.ContentRootPath, "log4net.config"))
);

// Set global configuration for use by singletons like ConfigManager
GlobalConfig.Configuration = builder.Configuration;

// Add services to the container.
builder
    .Services.AddControllersWithViews()
    .AddJsonOptions(options =>
    {
        // Use camelCase for JSON property names (categoryId instead of CategoryId)
        options.JsonSerializerOptions.PropertyNamingPolicy = System
            .Text
            .Json
            .JsonNamingPolicy
            .CamelCase;
    });

// Add DbContext with Oracle provider
var connectionString = builder.Configuration.GetSection("Connection").Value;
builder.Services.AddDbContext<ModelContext>(options => options.UseOracle(connectionString));

// Add Business Services
builder.Services.AddScoped<IUserBusiness, UserBusinessImpl>();
builder.Services.AddScoped<IArticleBusiness, ArticleBusinessImpl>();
builder.Services.AddScoped<IContentBusiness, ContentBusinessImpl>();

// Configure CORS - Allow frontend to access APIs
builder.Services.AddCors(options =>
{
    options.AddPolicy(
        "AllowFrontend",
        policy =>
        {
            policy
                .WithOrigins(
                    "http://localhost:3000", // React development
                    "http://localhost:5173", // Vite development
                    "http://localhost:4200", // Angular development
                    "http://simgetgo.vn", // Production domain
                    "http://simgetgo.com", // Production www domain
                    "https://skysimhub.vn", // Production www domain
                    "https://skysimhub.com", // Production www domain
                    "https://simgetgo.vn", // Production www domain
                    "https://simgetgo.com" // Production www domain
                )
                .AllowAnyMethod()
                .AllowAnyHeader()
                .AllowCredentials();
        }
    );
});

// Configure JWT Authentication
var jwtKey =
    builder.Configuration["Jwt:Key"]
    ?? "EsimLaoSecretKey1234567890ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789ABCD";
var jwtIssuer = builder.Configuration["Jwt:Issuer"] ?? "EsimLao";
var jwtAudience = builder.Configuration["Jwt:Audience"] ?? "EsimLaoClient";

builder
    .Services.AddAuthentication(options =>
    {
        options.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme;
        options.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme;
    })
    .AddJwtBearer(options =>
    {
        options.TokenValidationParameters = new TokenValidationParameters
        {
            ValidateIssuer = true,
            ValidateAudience = true,
            ValidateLifetime = true,
            ValidateIssuerSigningKey = true,
            ValidIssuer = jwtIssuer,
            ValidAudience = jwtAudience,
            IssuerSigningKey = new SymmetricSecurityKey(Encoding.ASCII.GetBytes(jwtKey))
        };
    });

// Add Swagger for API documentation
builder.Services.AddEndpointsApiExplorer();
builder.Services.AddSwaggerGen();

var app = builder.Build();

// Initialize ConfigManager to load configs from database
using (var scope = app.Services.CreateScope())
{
    var logger = scope.ServiceProvider.GetRequiredService<ILogger<Program>>();
    try
    {
        logger.LogInformation("Initializing ConfigManager...");
        Esim.Apis.Singleton.ConfigManager.Instance.Initialize();
        logger.LogInformation("ConfigManager initialized successfully");
        byte[] keyBytes = Encoding.UTF8.GetBytes("9kw1wLMLG2u1j2zX");
        var encrypt = DotnetLib.Secure.SecureLogic.EncryptAes("{\"username\": \"10014331\",\"fullName\": \"User6066871357\",\"phoneNumber\": \"8560010014331\",\"email\": \"abc@gmail.com\",}", "9kw1wLMLG2u1j2zX");
        logger.LogInformation($"encrypt: {encrypt}");

        var decrypt = DotnetLib.Secure.SecureLogic.DecryptAes(encrypt, "9kw1wLMLG2u1j2zX");
        logger.LogInformation($"decrypt: {decrypt}");
        // Start background refresh task
        Task.Run(() => Esim.Apis.Singleton.ConfigManager.Instance.RefreshConfigs());
    }
    catch (Exception ex)
    {
        logger.LogError(ex, "Failed to initialize ConfigManager");
    }
}
app.UseSwagger();
app.UseSwaggerUI();

// Configure the HTTP request pipeline.
//if (app.Environment.IsDevelopment())
//{
//    app.UseSwagger();
//    app.UseSwaggerUI();
//}
//else
//{
//    app.UseExceptionHandler("/Home/Error");
//    // The default HSTS value is 30 days. You may want to change this for production scenarios, see https://aka.ms/aspnetcore-hsts.
//    app.UseHsts();
//}

// Only redirect to HTTPS in production
if (!app.Environment.IsDevelopment())
{
    app.UseHttpsRedirection();
}

app.UseRouting();

// Enable CORS - MUST be after UseRouting and before UseAuthentication
app.UseCors("AllowFrontend");

app.UseAuthentication();
app.UseAuthorization();

//app.MapStaticAssets();

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

app.MapControllers();

app.Run();
