using Microsoft.AspNetCore.Authentication;
using Microsoft.AspNetCore.Authentication.Cookies;
using Microsoft.AspNetCore.Authentication.OpenIdConnect;
using Microsoft.EntityFrameworkCore;
using Microsoft.IdentityModel.Tokens;
using Watcher.Data;
using Watcher.Models;

var builder = WebApplication.CreateBuilder(args);

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

// HttpContentAccessor
builder.Services.AddHttpContextAccessor();

// ---------- Konfiguration laden ----------
var configuration = builder.Configuration;

// ---------- DB-Kontext mit MySQL ----------
builder.Services.AddDbContext<AppDbContext>(options =>
    options.UseMySql(
        configuration.GetConnectionString("DefaultConnection"),
        ServerVersion.AutoDetect(configuration.GetConnectionString("DefaultConnection"))
    )
);

// ---------- Authentifizierung konfigurieren ----------
builder.Services.AddAuthentication(options =>
{
    options.DefaultScheme = "Cookies";
    options.DefaultChallengeScheme = "oidc";
})
.AddCookie("Cookies")
.AddOpenIdConnect("oidc", options =>
{
    var config = builder.Configuration.GetSection("Authentication:PocketID");
    options.Authority = config["Authority"];
    options.ClientId = config["ClientId"];
    options.ClientSecret = config["ClientSecret"];
    options.ResponseType = "code";
    options.CallbackPath = config["CallbackPath"];
    options.SaveTokens = true;

    options.GetClaimsFromUserInfoEndpoint = true;

    options.Scope.Clear();
    options.Scope.Add("openid");
    options.Scope.Add("profile");
    options.Scope.Add("email");
    
    options.Events = new OpenIdConnectEvents
{
    OnTokenValidated = async ctx =>
    {
        var db = ctx.HttpContext.RequestServices.GetRequiredService<AppDbContext>();

        var principal = ctx.Principal;
        var pocketId = principal.FindFirst("http://schemas.xmlsoap.org/ws/2005/05/identity/claims/nameidentifier")?.Value;
        var preferredUsername = principal.FindFirst("preferred_username")?.Value;
        var email = principal.FindFirst("email")?.Value;

        if (string.IsNullOrEmpty(pocketId))
            return;

        var user = await db.Users.FirstOrDefaultAsync(u => u.PocketId == pocketId);

        if (user == null)
        {
            user = new User
            {
                PocketId = pocketId,
                PreferredUsername = preferredUsername ?? "",
                Email = email,
                LastLogin = DateTime.UtcNow
            };
            db.Users.Add(user);
        }
        else
        {
            user.LastLogin = DateTime.UtcNow;
            user.PreferredUsername = preferredUsername ?? user.PreferredUsername;
            user.Email = email ?? user.Email;
            db.Users.Update(user);
        }

        await db.SaveChangesAsync();
    }
};

});


var app = builder.Build();

// Configure the HTTP request pipeline.
if (!app.Environment.IsDevelopment())
{
    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();
}

app.UseHttpsRedirection();
app.UseRouting();

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

app.UseStaticFiles();


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


app.Run();
