using Application.Services.Database;
using Application.Services.Database.MongoDB;
using Application.Services.HashingAlgorithms;
using Application.Services.Jwt;

using Infrastructure.Data;
using Infrastructure.Services.HashingAlgorithms;
using Infrastructure.Services.MongoDB;
using Infrastructure.Services.PostgreSQL;

using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using MongoDB.Driver;

namespace Infrastructure;

public static class DependencyInjection
{
    public static IServiceCollection AddInfrastructureServices(this IServiceCollection services,
        IConfiguration configuration)
    {
        services.AddDbContext<HealthcareManagerDatabase>(options =>
            options.UseNpgsql(configuration.GetConnectionString("HealthcareManagerDatabase")));

        //PostgreSQL Services
        services.AddScoped<IPatientRepository, PatientRepository>();
        services.AddScoped<IDoctorRepository, DoctorRepository>();
        services.AddScoped<IMedicalHistoryRepository, MedicalHistoryRepository>();

        // MongoDB services
        services.AddSingleton<IMedicalHistoryMongoDbService>(serviceProvider =>
        {
            var configuration = serviceProvider.GetRequiredService<IConfiguration>();
            var connectionString = configuration.GetConnectionString("MongoDBConnection");
            var databaseName = configuration["HealthcareManagerDatabase:Name"];
            var collectionName = configuration["HealthcareManagerDatabase:MedicalRecordCollectionName"];

            return new MedicalHistoryMongoDbService(connectionString, databaseName, collectionName);
        });
        
        services.AddSingleton<IChatMongoDbService>(serviceProvider =>
        {
            var configuration = serviceProvider.GetRequiredService<IConfiguration>();
            var connectionString = configuration.GetConnectionString("MongoDBConnection");
            var databaseName = configuration["HealthcareManagerDatabase:Name"];
            var collectionName = configuration["HealthcareManagerDatabase:ChatCollectionName"];

            return new ChatMongoDbService(connectionString, databaseName, collectionName);
        });
        
        // Other Services
        services.AddScoped<IHashingAlgorithms, HashingAlgorithms>();
        services.AddSingleton<IJwtService, JwtService>(serviceProvider =>
        {
            var configuration = serviceProvider.GetRequiredService<IConfiguration>();
            return new JwtService(configuration);
        });
        // services.AddScoped<IEmailService, EmailService>();

        return services;
    }

    private static string ExtractMongoDbDatabaseName(string connectionString)
    {
        var connectionStringBuilder = new MongoUrlBuilder(connectionString);
        return connectionStringBuilder.DatabaseName;
    }
}