using System.Reflection;
using Fengling.Console.Services;
using Fengling.Platform.Domain.AggregatesModel.UserAggregate;
using Fengling.Platform.Domain.AggregatesModel.RoleAggregate;
using Fengling.Platform.Infrastructure;
using OpenIddict.Abstractions;
using Microsoft.EntityFrameworkCore;
using Microsoft.AspNetCore.Authentication.JwtBearer;
using Microsoft.AspNetCore.Identity;
using Microsoft.IdentityModel.Tokens;
using System.Text;
using NetCorePal.Extensions.DependencyInjection;
using OpenIddict.Validation.AspNetCore;
using YarpGateway.Data;

var builder = WebApplication.CreateBuilder(args);

builder.Services.AddControllers();

// Use PlatformDbContext for all identity
builder.Services.AddDbContext<PlatformDbContext>(options =>
{
    options.UseNpgsql(builder.Configuration.GetConnectionString("DefaultConnection"));
    if (builder.Environment.IsDevelopment())
    {
        options.EnableSensitiveDataLogging();
    }
    options.EnableDetailedErrors();
});

builder.Services.AddDbContext<GatewayDbContext>(options =>
    options.UseNpgsql(builder.Configuration.GetConnectionString("GatewayConnection")));

// Use Platform's identity
builder.Services.AddIdentity<ApplicationUser, ApplicationRole>()
    .AddEntityFrameworkStores<PlatformDbContext>()
    .AddDefaultTokenProviders();

builder.Services.AddHttpContextAccessor();

builder.Services.AddHttpClient();
builder.Services.AddScoped<IOAuthClientService, OAuthClientService>();

// Register Platform managers
builder.Services.AddScoped<ITenantStore, TenantStore>();
builder.Services.AddScoped<ITenantManager, TenantManager>();

builder.Services.AddScoped<IUserService, UserService>();
builder.Services.AddScoped<ITenantService, TenantService>();
builder.Services.AddScoped<IRoleService, RoleService>();
builder.Services.AddScoped<IGatewayService, GatewayService>();
builder.Services.AddScoped<IH5LinkService, H5LinkService>();

builder.Services.AddOpenIddict()
    .AddCore(options => { options.UseEntityFrameworkCore().UseDbContext<PlatformDbContext>(); })
    .AddValidation(options =>
    {
        options.SetIssuer("http://localhost:5132/");

        options.UseIntrospection()
            .SetClientId("fengling-api")
            .SetClientSecret("fengling-api-secret");

        options.UseSystemNetHttp();

        options.UseAspNetCore();
    });

builder.Services.AddAuthentication(options =>
{
    options.DefaultScheme = OpenIddictValidationAspNetCoreDefaults.AuthenticationScheme;
});

builder.Services.AddAuthorization();

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

builder.Services.AddEndpointsApiExplorer();
builder.Services.AddSwaggerGen(c =>
{
    c.SwaggerDoc("v1", new() { Title = "Fengling.Console API", Version = "v1" });
    c.CustomSchemaIds(type => type.FullName);
    var xmlFile = $"{Assembly.GetExecutingAssembly().GetName().Name}.xml";
    var xmlPath = Path.Combine(AppContext.BaseDirectory, xmlFile);
    if (File.Exists(xmlPath))
    {
        c.IncludeXmlComments(xmlPath);
    }
});

builder.Services.AddRepositories(typeof(PlatformDbContext).Assembly);



var app = builder.Build();

app.UseSwagger();
app.UseSwaggerUI(c => { c.SwaggerEndpoint("/swagger/v1/swagger.json", "Fengling.Console API V1"); });

app.UseCors("AllowAll");

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

app.MapControllers();

app.Run();
