using DigitalData.UserManager.Application;
using DigitalData.UserManager.Application.Contracts.Repositories;
using DigitalData.UserManager.Infrastructure.Contracts;
using DigitalData.UserManager.Infrastructure.Repositories;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.DependencyInjection;

namespace DigitalData.UserManager.Infrastructure;

public static class DependencyInjection
{
    /// <summary>
    /// Adds the UserManager repositories to the specified <see cref="IServiceCollection"/>.
    /// This method registers the necessary repositories 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 AddUserManagerInfrastructure<TDbContext>(this IServiceCollection services)
            where TDbContext : DbContext, IUserManagerDbContext
    {
        return services
            .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<IClientUserRepository, ClientUserRepository<TDbContext>>();
    }

    /// <summary>
    /// Adds the UserManager services and repositories to the specified <see cref="IServiceCollection"/>.
    /// This method allows configuring the DbContext options using the provided <paramref name="optionsAction"/>.
    /// </summary>
    /// <param name="services">The <see cref="IServiceCollection"/> to which the services will be added.</param>
    /// <param name="optionsAction">An <see cref="Action{T}"/> to configure the <see cref="DbContextOptionsBuilder"/>.</param>
    /// <returns>The updated <see cref="IServiceCollection"/>.</returns>
    public static IServiceCollection AddUserManagerInfrastructure(this IServiceCollection services, Action<DbContextOptionsBuilder> optionsAction) => services
        .AddDbContext<UserManagerDbContext>(optionsAction)
        .AddUserManagerInfrastructure<UserManagerDbContext>();
}
