using System.Net.Http.Headers;
using System.Security.Claims;
using System.Text.Json;
using Microsoft.AspNetCore.Authentication;
using Microsoft.AspNetCore.Authentication.OAuth;
using OAuthClient;

var builder = WebApplication.CreateBuilder(args);
builder.Logging.AddConsole();

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

builder.Services.AddAuthentication(options => {
        options.DefaultAuthenticateScheme = "Cookie";
        options.DefaultChallengeScheme = "OAuth";
    })
    .AddCookie("Cookie", options => {
        options.Cookie.Name = "ClientCookie";
    })
    .AddOAuth("OAuth", options => {
        var authConfig = builder.Configuration.GetSection("Authentication:OAuth");

        options.ClientId = authConfig["ClientId"]!;
        options.ClientSecret = authConfig["ClientSecret"]!;
        options.CallbackPath = authConfig["CallbackPath"]!;
        options.AuthorizationEndpoint = authConfig["AuthorizationEndpoint"]!;
        options.TokenEndpoint = authConfig["TokenEndpoint"]!;
        options.UserInformationEndpoint = authConfig["UserInformationEndpoint"]!;
        options.SignInScheme = "Cookie";
        options.Backchannel = new HttpClient(new OriginHandler("http://localhost:5255"));

        options.ClaimActions.MapJsonKey(ClaimTypes.NameIdentifier, "userId");

        options.Events = new OAuthEvents {
            OnCreatingTicket = async context => {
                var request = new HttpRequestMessage(HttpMethod.Get, context.Options.UserInformationEndpoint);
                request.Headers.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
                request.Headers.Authorization = new AuthenticationHeaderValue("Bearer", context.AccessToken);

                var response = await context.Backchannel.SendAsync(request);
                response.EnsureSuccessStatusCode();

                var user = JsonDocument.Parse(await response.Content.ReadAsStringAsync());

                context.RunClaimActions(user.RootElement);
            }
        };
    });

builder.Services.AddAuthorization();

var app = builder.Build();

// Configure the HTTP request pipeline.
if (app.Environment.IsDevelopment()) {
    app.UseDeveloperExceptionPage();
} else {
    app.UseExceptionHandler("/Home/Error");
}

app.UseStaticFiles();

app.UseRouting();

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

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

app.Run();