using Microsoft.Extensions.DependencyInjection;

namespace Managing.Core
{
    public static class ServiceScopeHelpers
    {
        public static async Task WithScopedService<TService>(IServiceScopeFactory scopeFactory, Func<TService, Task> action)
            where TService : notnull
        {
            using var scope = scopeFactory.CreateScope();
            var service = scope.ServiceProvider.GetRequiredService<TService>();
            await action(service);
        }

        public static async Task<TResult> WithScopedService<TService, TResult>(IServiceScopeFactory scopeFactory, Func<TService, Task<TResult>> action)
            where TService : notnull
        {
            using var scope = scopeFactory.CreateScope();
            var service = scope.ServiceProvider.GetRequiredService<TService>();
            return await action(service);
        }

        public static async Task WithScopedServices<T1, T2>(IServiceScopeFactory scopeFactory, Func<T1, T2, Task> action)
            where T1 : notnull
            where T2 : notnull
        {
            using var scope = scopeFactory.CreateScope();
            var s1 = scope.ServiceProvider.GetRequiredService<T1>();
            var s2 = scope.ServiceProvider.GetRequiredService<T2>();
            await action(s1, s2);
        }

        public static async Task<TResult> WithScopedServices<T1, T2, TResult>(IServiceScopeFactory scopeFactory, Func<T1, T2, Task<TResult>> action)
            where T1 : notnull
            where T2 : notnull
        {
            using var scope = scopeFactory.CreateScope();
            var s1 = scope.ServiceProvider.GetRequiredService<T1>();
            var s2 = scope.ServiceProvider.GetRequiredService<T2>();
            return await action(s1, s2);
        }

        public static async Task WithScopedServices<T1, T2, T3>(IServiceScopeFactory scopeFactory, Func<T1, T2, T3, Task> action)
            where T1 : notnull
            where T2 : notnull
            where T3 : notnull
        {
            using var scope = scopeFactory.CreateScope();
            var s1 = scope.ServiceProvider.GetRequiredService<T1>();
            var s2 = scope.ServiceProvider.GetRequiredService<T2>();
            var s3 = scope.ServiceProvider.GetRequiredService<T3>();
            await action(s1, s2, s3);
        }

        public static async Task<TResult> WithScopedServices<T1, T2, T3, TResult>(IServiceScopeFactory scopeFactory, Func<T1, T2, T3, Task<TResult>> action)
            where T1 : notnull
            where T2 : notnull
            where T3 : notnull
        {
            using var scope = scopeFactory.CreateScope();
            var s1 = scope.ServiceProvider.GetRequiredService<T1>();
            var s2 = scope.ServiceProvider.GetRequiredService<T2>();
            var s3 = scope.ServiceProvider.GetRequiredService<T3>();
            return await action(s1, s2, s3);
        }
    }
} 