using System.Data.Odbc;
using System.Text;
using AS400API.Auth;
using AS400API.Configuration;
using AS400API.Endpoints;
using Microsoft.AspNetCore.Authentication.JwtBearer;
using Microsoft.IdentityModel.Tokens;
using Microsoft.OpenApi.Models;
using Serilog;


var builderArgs = args ?? Array.Empty<string>(); 
var builder = WebApplication.CreateBuilder(builderArgs);



builder.Host.UseSerilog((context, services, loggerConfiguration) =>
{
    loggerConfiguration
        .ReadFrom.Configuration(context.Configuration)
        .Enrich.FromLogContext();
});

// Bind ODBC settings
var odbc = new OdbcOptions();
builder.Configuration.GetSection("Odbc").Bind(odbc);

// Allow overriding by environment variables
odbc.System ??= Environment.GetEnvironmentVariable("AS400_SYSTEM");
odbc.DefaultLibraries ??= Environment.GetEnvironmentVariable("AS400_DEFAULT_LIBRARIES");
odbc.User ??= Environment.GetEnvironmentVariable("AS400_USER");
odbc.Password ??= Environment.GetEnvironmentVariable("AS400_PASSWORD");
odbc.Naming ??= Environment.GetEnvironmentVariable("AS400_NAMING") ?? "1";

if (string.IsNullOrWhiteSpace(odbc.System) ||
    string.IsNullOrWhiteSpace(odbc.User) ||
    string.IsNullOrWhiteSpace(odbc.Password))
{
    Console.WriteLine("⚠️  Missing ODBC connection settings. Set in appsettings.json or environment variables.");
}

// JWT configuration
var jwtOptions = builder.Configuration.GetSection(JwtOptions.SectionName).Get<JwtOptions>() ?? new JwtOptions();
jwtOptions.EnsureIsValid();
var signingKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(jwtOptions.Key));

builder.Services.AddEndpointsApiExplorer();
builder.Services.AddSwaggerGen(options =>
{
    options.SwaggerDoc("v1", new OpenApiInfo
    {
        Title = "AS400 API",
        Version = "v1"
    });

    var securityScheme = new OpenApiSecurityScheme
    {
        Name = "Authorization",
        Description = "JWT Authorization header using the Bearer scheme.",
        In = ParameterLocation.Header,
        Type = SecuritySchemeType.Http,
        Scheme = "bearer",
        BearerFormat = "JWT",
        Reference = new OpenApiReference
        {
            Type = ReferenceType.SecurityScheme,
            Id = "Bearer"
        }
    };

    options.AddSecurityDefinition(securityScheme.Reference.Id, securityScheme);
    options.AddSecurityRequirement(new OpenApiSecurityRequirement
    {
        { securityScheme, Array.Empty<string>() }
    });
});
builder.Services.AddSingleton(odbc);
builder.Services.AddScoped<OdbcConnection>(_ => new OdbcConnection(odbc.ToConnectionString()));
builder.Services.AddSingleton(jwtOptions);
builder.Services.AddSingleton<TokenService>();
builder.Services.AddSingleton<DemoUserStore>();

builder.Services
    .AddAuthentication(JwtBearerDefaults.AuthenticationScheme)
    .AddJwtBearer(options =>
    {
        options.TokenValidationParameters = new TokenValidationParameters
        {
            ValidateIssuer = true,
            ValidIssuer = jwtOptions.Issuer,
            ValidateAudience = true,
            ValidAudience = jwtOptions.Audience,
            ValidateIssuerSigningKey = true,
            IssuerSigningKey = signingKey,
            ValidateLifetime = true,
            ClockSkew = TimeSpan.FromMinutes(1)
        };
    });

builder.Services.AddAuthorization(options =>
{
    options.AddPolicy(AuthPolicies.RequireOperator, policy =>
        policy.RequireRole(Roles.Admin, Roles.Operator));
    options.AddPolicy(AuthPolicies.RequireAdmin, policy =>
        policy.RequireRole(Roles.Admin));
});

var app = builder.Build();

if (app.Environment.IsDevelopment())
{
    app.UseSwagger();
    app.UseSwaggerUI();
}

app.UseSerilogRequestLogging();

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

app.MapRootEndpoints();

var api = app.MapGroup("/api");
api.MapSystemEndpoints();
api.MapAuthEndpoints();
api.MapAs400Endpoints();
api.MapORDUAGEndpoints();

await app.RunAsync();


//  env DOTNET_ENVIRONMENT=Development dotnet run
// docker run -d --name sonarqube -p 9000:9000 sonarqube:lts-community

public partial class Program { }
