using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Database.Configuration;
using Database.Services;

namespace Database.Extensions
{
    public static class ServiceCollectionExtensions
    {
        public static IServiceCollection AddDatabase(this IServiceCollection services, IConfiguration configuration)
        {
            // Bind database configuration
            var dbConfig = new DatabaseConfiguration();
            configuration.GetSection(DatabaseConfiguration.SectionName).Bind(dbConfig);
            services.AddSingleton(dbConfig);
            
            // Add Entity Framework DbContext
            services.AddDbContext<DatabaseContext>(options =>
            {
                options.UseNpgsql(dbConfig.ConnectionString, npgsqlOptions =>
                {
                    npgsqlOptions.CommandTimeout(dbConfig.CommandTimeout);
                    npgsqlOptions.EnableRetryOnFailure(
                        maxRetryCount: dbConfig.Retry.MaxRetryCount,
                        maxRetryDelay: TimeSpan.FromSeconds(dbConfig.Retry.MaxRetryDelay),
                        errorCodesToAdd: null);
                });
                
                if (dbConfig.EnableSensitiveDataLogging)
                {
                    options.EnableSensitiveDataLogging();
                }
                
                if (dbConfig.EnableDetailedErrors)
                {
                    options.EnableDetailedErrors();
                }
                
                // Configure connection pooling
                options.UseNpgsql(dbConfig.ConnectionString, npgsqlOptions =>
                {
                    npgsqlOptions.CommandTimeout(dbConfig.CommandTimeout);
                });
            });
            
            // Add database services
            services.AddScoped<IDatabaseSeeder, DatabaseSeeder>();
            services.AddScoped<IDatabaseMigrator, DatabaseMigrator>();
            services.AddScoped<IPasswordHasher, PasswordHasher>();
            
            return services;
        }
        
        public static IServiceCollection AddDatabaseRepositories(this IServiceCollection services)
        {
            // Add repository pattern services if needed
            services.AddScoped<IUserRepository, UserRepository>();
            services.AddScoped<IPackageRepository, PackageRepository>();
            services.AddScoped<IProjectRepository, ProjectRepository>();
            services.AddScoped<IBuildRepository, BuildRepository>();
            services.AddScoped<IFogBugzRepository, FogBugzRepository>();
            services.AddScoped<IPublicationRepository, PublicationRepository>();
            
            return services;
        }
    }
}