using Ablera.Serdica.Authority.Constants;
using Ablera.Serdica.Authority.Extensions;
using Ablera.Serdica.Authority.Services;
using Microsoft.AspNetCore;
using Microsoft.AspNetCore.Authentication;
using Microsoft.AspNetCore.Authentication.Cookies;
using Microsoft.Extensions.DependencyInjection;
using OpenIddict.Abstractions;
using System;
using System.Linq;
using System.Threading.Tasks;

namespace Ablera.Serdica.Authority.Extensions;

public static class RedirectToLoginHandler
{
    public static async Task HandlerRedirectToLogin(this RedirectContext<CookieAuthenticationOptions> ctx)
    {
        var oidcSettings = ctx.HttpContext.RequestServices.GetRequiredService<OidcJsonSettingsProvider>()
                   .Settings;
        // only intercept the OIDC authorize endpoint
        if (ctx.Request.Path.StartsWithSegments(oidcSettings!.Endpoints.Authorization.EnsureStartsWith("/") ) == false)
        {
            ctx.Response.Redirect(ctx.RedirectUri); // normal behaviour
        }

        var appMgr = ctx.HttpContext.RequestServices
                    .GetRequiredService<IOpenIddictApplicationManager>();
        var oidReq = ctx.HttpContext.GetOpenIddictServerRequest();
        var app = await appMgr.FindByClientIdAsync(oidReq!.ClientId!);
        var props = await appMgr.GetPropertiesAsync(app!);

        var delegateUrl = props.GetStringOrThrow(ConstantsClass.AuthenticationDelegateUrlKey, oidReq.ClientId!);
        var confirm = $"{ctx.HttpContext.Request.Scheme}://{ctx.HttpContext.Request.Host}{ctx.Request.Path}{ctx.Request.QueryString}";
        var redir = delegateUrl + "&confirmUrl=" + Uri.EscapeDataString(confirm);

        ctx.Response.Redirect(redir);
    }
}
