using Auth0.AspNetCore.Authentication;
using Blazored.SessionStorage;
using BlazorServer.Services;
using BlazorWebApp;
using BlazorWebApp.Client.Interfaces;
using BlazorWebApp.Client.Pages;
using BlazorWebApp.Client.Services;
using BlazorWebApp.Components;
using BlazorWebApp.Database;
using BlazorWebApp.Endpoints;
using BlazorWebApp.Repositories;
using Microsoft.AspNetCore.Authentication;
using Microsoft.AspNetCore.Authentication.Cookies;
using Microsoft.AspNetCore.Components.Authorization;
using Microsoft.EntityFrameworkCore;
using BlazorWebApp.Hubs;

var builder = WebApplication.CreateBuilder(args);

builder.AddServiceDefaults();

// Add services to the container.
builder.Services.AddRazorComponents()
    .AddInteractiveServerComponents()
    .AddInteractiveWebAssemblyComponents()
    .AddAuthenticationStateSerialization();
var connectionString = builder.Configuration.GetConnectionString("myBlogDb");

builder.Services.AddDbContextFactory<BlogDbContext>(options =>
    options.UseNpgsql(connectionString));

builder.Services.AddScoped<IBlogRepository, BlogRepositoryEntityFrameworkDirectAccess>();
builder.Services.AddSingleton<IBlogNotificationService, BlazorServerBlogNotificationService>();
builder.Services.AddCascadingAuthenticationState();
builder.Services.AddBlazoredSessionStorage();
builder.Services.AddScoped<BlogBrowserStorage>();
builder.Services.AddSignalR();
builder.Services
    .AddAuth0WebAppAuthentication(options =>
    {
        options.Domain = builder.Configuration["Auth0:Authority"] ?? ""; ;
        options.ClientId = builder.Configuration["Auth0:ClientId"] ?? ""; ;
    });


var app = builder.Build();

app.MapDefaultEndpoints();

// Configure the HTTP request pipeline.
if (app.Environment.IsDevelopment())
{
    app.UseWebAssemblyDebugging();

    using (var scope = app.Services.CreateScope())
    {
        var context = scope.ServiceProvider.GetRequiredService<BlogDbContext>();
        await context.Database.EnsureCreatedAsync();
    }
}
else
{
    app.UseExceptionHandler("/Error", createScopeForErrors: true);
    // 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.UseStatusCodePagesWithReExecute("/not-found", createScopeForStatusCodePages: true);
app.UseHttpsRedirection();

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

app.MapStaticAssets();
app.MapHub<BlogNotificationHub>("/BlogNotificationHub");
app.MapRazorComponents<App>()
    .AddInteractiveServerRenderMode()
    .AddInteractiveWebAssemblyRenderMode()
    .AddAdditionalAssemblies(typeof(BlazorWebApp.Client._Imports).Assembly, typeof(SharedComponents._Imports).Assembly);
app.MapBlogPostApi();
app.MapCategoryApi();
app.MapTagApi();
app.MapCommentApi();
app.MapGet("account/login", async (string returnUrl, HttpContext context) =>
{
    var authenticationProperties = new LoginAuthenticationPropertiesBuilder()
         .WithRedirectUri(returnUrl)
         .Build();
    await context.ChallengeAsync(Auth0Constants.AuthenticationScheme, authenticationProperties);
});
app.MapGet("authentication/logout", async (HttpContext context) =>
{
    var authenticationProperties = new LogoutAuthenticationPropertiesBuilder()
         .WithRedirectUri("/")
         .Build();
    await context.SignOutAsync(Auth0Constants.AuthenticationScheme, authenticationProperties);
    await context.SignOutAsync(CookieAuthenticationDefaults.AuthenticationScheme);
});


app.Run();
