using System.Text;
using Microsoft.AspNetCore.Authentication.JwtBearer;
using Microsoft.IdentityModel.Tokens;

namespace eSuite.API.Middleware;

/// <summary>
/// Methods used to extend WebAPI authentication to use the Bearer token.
/// </summary>
internal static class AuthenticationExtension
{
    public const string SessionCookieName = "eSuiteSession";

    /// <summary>
    /// Adds support for JWT Tokens passed as Bearer to the application.
    /// </summary>
    /// <param name="builder"></param>
    public static void AddTokenAuthentication(this WebApplicationBuilder builder)
    {
        builder.Services.AddAuthentication(options =>
            {
                options.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme;
                options.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme;
                options.DefaultScheme = JwtBearerDefaults.AuthenticationScheme;
            })
            .AddJwtBearer(options =>
            {
                options.SaveToken = true;
                options.RequireHttpsMetadata = true;
                options.TokenValidationParameters = new TokenValidationParameters
                {
                    ValidateIssuer = true,
                    ValidateAudience = true,
                    ValidateIssuerSigningKey = true,
                    ValidateLifetime = true,
                    ValidAudience = builder.Configuration["JwtConfig:audience"],
                    ValidIssuer = builder.Configuration["JwtConfig:issuer"],
                    IssuerSigningKey =
                        new SymmetricSecurityKey(Encoding.UTF8.GetBytes(builder.Configuration["JwtConfig:secret"]!)),
                    ClockSkew = TimeSpan.FromSeconds(5)
                };
                options.Events = new JwtBearerEvents
                {
                    OnMessageReceived = context =>
                    {
                        if (context.Request.Cookies.ContainsKey(SessionCookieName))
                        {
                            context.Token = context.Request.Cookies[SessionCookieName];
                        }

                        return Task.CompletedTask;
                    }
                };
            });
    }
}