using System.Text;
using adas_core.Domain.Models.AppSettings;
using adas_core.Domain.Models.Providers;
using adas_core.module.ProxyDevices;
using adas_core.module.ProxyDevices.Services;
using adas_core.module.Relays.Models;
using Microsoft.AspNetCore.Authentication.JwtBearer;
using Microsoft.IdentityModel.Tokens;
using Serilog;

namespace adas_core.Configurations;

public static class ServiceExtension
{
    public static void CreateConfigEntitiesFromAppSettingsSections(this WebApplicationBuilder builder)
    {
        builder.Services.Configure<DatabaseSettings>(builder.Configuration.GetSection("DatabaseSettings"));
        builder.Services.Configure<RabbitMqSettings>(builder.Configuration.GetSection("RabbitMQSettings"));
        builder.Services.Configure<List<ProvidersSettings>>(builder.Configuration.GetSection("ProvidersSettings"));
        builder.Services.Configure<RecordingSettings>(builder.Configuration.GetSection("RecordingSettings"));
        builder.Services.Configure<RelaySettings>(builder.Configuration.GetSection("RelaySettings"));
        builder.Services.Configure<ApiSettings>(builder.Configuration.GetSection("ApiSettings"));
        builder.Services.Configure<AuthSettings>(builder.Configuration.GetSection("AuthSettings"));
        builder.Services.Configure<RedisSettings>(builder.Configuration.GetSection("RedisSettings"));
        builder.Services.Configure<CacheSettings>(builder.Configuration.GetSection("CacheSettings"));
        builder.Services.Configure<ListSettings>(builder.Configuration.GetSection("ListSettings"));
    }

    public static void UseProxyDevices(
        this WebApplicationBuilder builder)
    {
        if (builder == null)
            throw new ArgumentNullException(nameof(builder));

        builder.Services.AddSingleton<IProxyDeviceService, ProxyDeviceService>();
        builder.Services.Configure<ProxyDeviceSettings>(builder.Configuration.GetSection("ProxyDevicesSettings"));
    }

    public static void ConfigureJwtAuthentication(this WebApplicationBuilder builder)
    {
        var auth = new AuthSettings();
        builder.Configuration.GetSection("AuthSettings").Bind(auth);
        var jwt = auth.JwtConfig;
        if (jwt == null)
            return;

        if (string.IsNullOrEmpty(jwt.Key))
        {
            Log.Error("Jwt secret is empty on appSettings.json");
            throw new Exception("Cant configure jwt without secret");
        }

        builder.Services.AddAuthentication(x =>
            {
                x.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme;
                x.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme;
                x.DefaultScheme = JwtBearerDefaults.AuthenticationScheme;
            })            
            .AddJwtBearer(options =>
            {
                options.RequireHttpsMetadata = false;
                options.SaveToken = true;
                SymmetricSecurityKey symmetricSecurityKey = new(Encoding.UTF8.GetBytes(jwt.Key));
                options.TokenValidationParameters = new TokenValidationParameters
                {
                    ValidateIssuer = jwt.ValidateIssuer,
                    ValidateAudience = jwt.ValidateAudience,
                    ValidateIssuerSigningKey = true,
                    ValidAudience = jwt.Audience,
                    ValidIssuer = jwt.Issuer,
                    IssuerSigningKey = symmetricSecurityKey
                };
                
            });

        builder.Services.AddAuthorization();
    }
}