using Microsoft.Extensions.DependencyInjection;
using Modules.User.Database.Database;
using Modules.User.Database.Repositories;
using Microsoft.EntityFrameworkCore;
using System.Reflection;
using Modules.User.Application;
using Modules.User.Application.Repositories;
using Modules.User.Database.Queries;

namespace Modules.User.Database;

public static class ServiceCollectionExtensions
{
    public static IServiceCollection AddDatabase(this IServiceCollection services, string? connectionString)
    {
        if (string.IsNullOrWhiteSpace(connectionString)) throw new ArgumentNullException(nameof(connectionString));

        services.AddDbContext<UserDbContext>(options =>
        {
            options.UseNpgsql(connectionString, q =>
            {
                q.MigrationsAssembly(Assembly.GetAssembly(typeof(UserDbContext))!.GetName().Name);
                q.MigrationsHistoryTable("__Migrations");
            });
            //options.UseNpgsql(connectionString);
            //AppContext.SetSwitch("Npgsql.EnableLegacyTimestampBehavior", true); //Включаем UTC-время.
            //options.UseLazyLoadingProxies(); // lazy loading
        });
        AddRepositories(services);
        // AddGateways(services);
        return services;
    }

    //public static IServiceCollection AddDatabase(this IServiceCollection services, string connectionString, string? databaseName)
    //{
    //    AddMongoDb(services, connectionString, databaseName);
    //    //services.AddScoped<MongoDbContext>();
    //    services.AddScoped<UserDbContext>(q =>
    //    {
    //        var context = new UserDbContext(q.GetRequiredService<IMongoDatabase>());
    //        context.Initialize();
    //        return context;
    //    });
    //    BsonSerializer.RegisterSerializer(new GuidSerializer(GuidRepresentation.Standard));
    //    BsonSerializer.RegisterSerializer(new NullableSerializer<Guid>(new GuidSerializer(GuidRepresentation.Standard)));
    //    AddRepositories(services);
    //    AddGateways(services);
    //    return services;
    //}

    private static void AddRepositories(IServiceCollection services)
    {
        // services.AddScoped<AccountRepository>();
        // // services.AddScoped<UserRepository1>();
        // services.AddScoped<SessionRepository>();
        
        services.AddScoped<IAccountRepository, AccountRepository>();
        services.AddScoped<IAccountAccessQueries, AccountAccessQueries>();

        services.AddScoped<IUserRepository, UserRepository>();
        services.AddScoped<IUserQueries, UserQueries>();
        
        services.AddScoped<IRoleRepository, RoleRepository>();
        services.AddScoped<IRoleQueries, RoleQueries>();
        
        services.AddScoped<IPermissionRepository, PermissionRepository>();
        services.AddScoped<IPermissionQueries, PermissionQueries>();
        
        services.AddScoped<IUnitOfWork, UnitOfWork>();
    }

    // private static void AddGateways(IServiceCollection services)
    // {
    //     services.AddScoped<IUserGateway, UserGateway>();
    //     services.AddScoped<IAccountGateway, AccountGateway>();
    // }

    //private static void AddMongoDb(this IServiceCollection services, string? connectionString)
    //{
    //    if (string.IsNullOrWhiteSpace(connectionString)) throw new ArgumentNullException(nameof(connectionString));
    //    services.AddSingleton(new MongoClient(connectionString));
    //}

    //private static void AddMongoDb(IServiceCollection services, string? connectionString, string? databaseName)
    //{
    //    if (string.IsNullOrWhiteSpace(connectionString)) throw new ArgumentNullException(nameof(connectionString));
    //    if (string.IsNullOrWhiteSpace(databaseName)) throw new ArgumentNullException(nameof(databaseName));
    //    services.AddSingleton(new MongoClient(connectionString).GetDatabase(databaseName));
    //}
}