using DataBase.Entities.Models;
using Microsoft.EntityFrameworkCore;
using User.Insight.Tracker.DataProviders;
using User.Insight.Tracker.Services;
using Amazon;
using Amazon.SimpleSystemsManagement;
using Amazon.SimpleSystemsManagement.Model;
using User.Insight.Tracker.Common;
using Microsoft.OpenApi.Models;

var builder = WebApplication.CreateBuilder(args);

// Logging setup
builder.Logging.ClearProviders();
builder.Logging.AddConsole();

builder.Services.AddHttpContextAccessor();
var configuration = builder.Configuration;
string DefaultConnection = string.Empty;
var pathBase = builder.Configuration["PATH_BASE"];
if (builder.Environment.IsDevelopment())
{
    DefaultConnection = configuration.GetConnectionString("DefaultConnection");
}
else
{
    string parameterName;
    var region = RegionEndpoint.GetBySystemName("ap-south-1");
    parameterName = "/prod/userinsighttracking/connectionstring";
    try
    {
        using var ssmClient = new AmazonSimpleSystemsManagementClient(region);
        var request = new GetParameterRequest
        {
            Name = parameterName,
            WithDecryption = true
        };

        var response = await ssmClient.GetParameterAsync(request);
        DefaultConnection = response.Parameter.Value;
    }
    catch (ParameterNotFoundException ex)
    {
        Console.WriteLine("SSM Parameter not found: " + ex.Message);
    }
    catch (Exception ex)
    {
        Console.WriteLine("SSM fetch error: " + ex.Message);
    }
}

// CORS
builder.Services.AddCors(options =>
{
    options.AddPolicy("AllowAll", policy =>
    {
        policy.AllowAnyOrigin()
              .AllowAnyMethod()
              .AllowAnyHeader();
    });
});

// Controllers & JSON
builder.Services.AddControllers().AddJsonOptions(options =>
{
    options.JsonSerializerOptions.PropertyNamingPolicy = null;
    options.JsonSerializerOptions.WriteIndented = true;
});

// Swagger + JWT
builder.Services.AddSwaggerGen(c =>
{
    c.SwaggerDoc("v1", new OpenApiInfo { Title = "User Tracking Insight", Version = "v1" });

    // Tell Swagger to use the base path (important!)   
    if (!string.IsNullOrEmpty(pathBase))
    {
        c.AddServer(new OpenApiServer
        {
            Url = pathBase
        });
    }

    c.AddSecurityDefinition("Bearer", new OpenApiSecurityScheme
    {
        In = ParameterLocation.Header,       
        Description = "Enter your JWT token in the format 'Bearer {token}'",
        Name = "Authorization",
        BearerFormat = "JWT",
        Type = SecuritySchemeType.ApiKey
    });
    c.AddSecurityDefinition("RoleId", new OpenApiSecurityScheme
    {
        In = ParameterLocation.Header,
        Description = "User Current Role",
        Name = "RoleId",
        Type = SecuritySchemeType.ApiKey
    });

    c.AddSecurityRequirement(new OpenApiSecurityRequirement {
    {
        new OpenApiSecurityScheme
        {
        Reference = new OpenApiReference
        {
            Type = ReferenceType.SecurityScheme,
            Id = "Bearer"
        }
        },
        new string[] { }
    },
    {
        new OpenApiSecurityScheme
        {
            Reference = new OpenApiReference
            {
                Type = ReferenceType.SecurityScheme,
                Id = "RoleId"
            }
        },
        new string[] {}
    }
    });
});

builder.Services.AddEndpointsApiExplorer();
builder.Services.AddHealthChecks();
builder.Services.AddAuthorization();

// DB Context
builder.Services.AddDbContext<ComputraceqaContext>(options =>
    options.UseMySql(DefaultConnection,
        new MySqlServerVersion(new Version(8, 0, 36)),
        mySqlOptions =>
        {
            mySqlOptions.CommandTimeout(180);
            mySqlOptions.EnableRetryOnFailure(
                maxRetryCount: 5,
                maxRetryDelay: TimeSpan.FromSeconds(10),
                errorNumbersToAdd: null);
        }));

// DI
builder.Services.AddScoped<IUtils, Utils>();
builder.Services.AddScoped<IUserInsightTrackerService, UserInsightTrackerService>();
builder.Services.AddScoped<IUserInsightTrackerProvider, UserInsightTrackerProvider>();
builder.Services.AddScoped<IAzureSyncingService, AzureSyncingService>();
builder.Services.AddScoped<IAzureSyncingServiceProvider, AzureSyncingServiceProvider>();
builder.Services.AddScoped<IS3BucketService, S3BucketService>();
builder.Services.AddHttpClient<ICommonService, CommonService>();
builder.Services.AddScoped<ICommonServiceProvider, CommonServiceProvider>();

var app = builder.Build();

// Middleware Pipeline
if (!app.Environment.IsDevelopment())
{
    app.UseHsts();
    app.UseHttpsRedirection();
}

if (!string.IsNullOrEmpty(pathBase))
{
    app.UsePathBase(pathBase);
}

app.UseSwagger();
app.UseSwaggerUI(c =>
{
    c.SwaggerEndpoint($"{pathBase}/swagger/v1/swagger.json", "User Tracking Insight v1");
    c.RoutePrefix = "swagger"; // DO NOT include pathBase here
});

app.UseRouting();
app.UseMiddleware<ExceptionHandlerMiddleware>();
app.UseCors("AllowAll");
app.UseAuthentication();
app.UseAuthorization();

app.MapControllers(); // respects path base (/api)
app.MapHealthChecks("/health");
await app.RunAsync();
