using DigitalData.UserManager.Application.Contracts;
using DigitalData.UserManager.Application.MappingProfiles;
using DigitalData.UserManager.Application.Services;
using DigitalData.UserManager.Application.Services.Options;
using DigitalData.UserManager.Infrastructure.Contracts;
using DigitalData.UserManager.Infrastructure.Repositories;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;

namespace DigitalData.UserManager.Application
{
    public static class DIExtensions
    {
        /// <summary>
        /// Adds the UserManager services and repositories to the specified <see cref="IServiceCollection"/>.
        /// This method registers the necessary mappings, repositories, and services for the UserManager.
        /// </summary>
        /// <typeparam name="TDbContext">The type of the DbContext to use for the repositories.</typeparam>
        /// <param name="services">The IServiceCollection to which the services will be added.</param>
        /// <returns>The updated IServiceCollection.</returns>
        public static IServiceCollection AddUserManager<TDbContext>(this IServiceCollection services)
            where TDbContext : DbContext, IUserManagerDbContext
            => services
            .AddAutoMapper(typeof(UserMappingProfile).Assembly)
            .AddAutoMapper(typeof(GroupMappingProfile).Assembly)
            .AddAutoMapper(typeof(GroupOfUserMappingProfile).Assembly)
            .AddAutoMapper(typeof(ModuleMappingProfile).Assembly)
            .AddAutoMapper(typeof(ModuleOfUserMappingProfile).Assembly)
            .AddAutoMapper(typeof(UserRepMappingProfile).Assembly)

            .AddScoped<IUserRepository, UserRepository<TDbContext>>()
            .AddScoped<IGroupRepository, GroupRepository<TDbContext>>()
            .AddScoped<IGroupOfUserRepository, GroupOfUserRepository<TDbContext>>()
            .AddScoped<IModuleRepository, ModuleRepository<TDbContext>>()
            .AddScoped<IModuleOfUserRepository, ModuleOfUserRepository<TDbContext>>()
            .AddScoped<IUserRepRepository, UserRepRepository<TDbContext>>()

            .AddScoped<IUserService, UserService>()
            .AddScoped<IGroupService, GroupService>()
            .AddScoped<IGroupOfUserService, GroupOfUserService>()
            .AddScoped<IModuleService, ModuleService>()
            .AddScoped<IModuleOfUserService, ModuleOfUserService>()
            .AddScoped<IUserRepService, UserRepService>();

        public static IServiceCollection AddEncryptor(this IServiceCollection services, IConfiguration configuration)
        {
            services.AddSingleton<Encryptor>();
            services.Configure<EncryptionParameters>(configuration);
            return services;
        }
    }
}