using Microsoft.EntityFrameworkCore;
using FluentValidation;
using MediatR;
using ColaFlow.Modules.ProjectManagement.Application.Behaviors;
using ColaFlow.Modules.ProjectManagement.Application.Commands.CreateProject;
using ColaFlow.Modules.ProjectManagement.Domain.Repositories;
using ColaFlow.Modules.ProjectManagement.Infrastructure.Persistence;
using ColaFlow.Modules.ProjectManagement.Infrastructure.Repositories;
using ColaFlow.Modules.IssueManagement.Application.Commands.CreateIssue;
using ColaFlow.Modules.IssueManagement.Infrastructure.Persistence;
using ColaFlow.Modules.IssueManagement.Infrastructure.Persistence.Repositories;
using Microsoft.Extensions.Hosting;

namespace ColaFlow.API.Extensions;

/// <summary>
/// Extension methods for registering modules
/// </summary>
public static class ModuleExtensions
{
    /// <summary>
    /// Register ProjectManagement Module
    /// </summary>
    public static IServiceCollection AddProjectManagementModule(
        this IServiceCollection services,
        IConfiguration configuration,
        IHostEnvironment? environment = null)
    {
        // Only register PostgreSQL DbContext in non-Testing environments
        // In Testing environment, WebApplicationFactory will register InMemory provider
        if (environment == null || environment.EnvironmentName != "Testing")
        {
            // Register DbContext
            var connectionString = configuration.GetConnectionString("PMDatabase");
            services.AddDbContext<PMDbContext>(options =>
                options.UseNpgsql(connectionString));
        }

        // Register HTTP Context Accessor (for tenant context)
        services.AddHttpContextAccessor();

        // Register Tenant Context (for multi-tenant isolation)
        services.AddScoped<ColaFlow.Modules.ProjectManagement.Application.Common.Interfaces.ITenantContext,
            ColaFlow.Modules.ProjectManagement.Infrastructure.Services.TenantContext>();

        // Register repositories
        services.AddScoped<IProjectRepository, ProjectRepository>();
        services.AddScoped<IAuditLogRepository, ColaFlow.Modules.ProjectManagement.Infrastructure.Repositories.AuditLogRepository>();
        services.AddScoped<IUnitOfWork, ColaFlow.Modules.ProjectManagement.Infrastructure.Persistence.UnitOfWork>();

        // Register services
        services.AddScoped<ColaFlow.Modules.ProjectManagement.Application.Services.IProjectPermissionService,
            ColaFlow.Modules.ProjectManagement.Infrastructure.Services.ProjectPermissionService>();

        // Register MediatR handlers from Application assembly (v13.x syntax)
        services.AddMediatR(cfg =>
        {
            cfg.LicenseKey = configuration["MediatR:LicenseKey"];
            cfg.RegisterServicesFromAssembly(typeof(CreateProjectCommand).Assembly);
        });

        // Register FluentValidation validators
        services.AddValidatorsFromAssembly(typeof(CreateProjectCommand).Assembly);

        // Register pipeline behaviors
        services.AddTransient(typeof(IPipelineBehavior<,>), typeof(ValidationBehavior<,>));

        Console.WriteLine("[ProjectManagement] Module registered");

        return services;
    }

    /// <summary>
    /// Register IssueManagement Module
    /// </summary>
    public static IServiceCollection AddIssueManagementModule(
        this IServiceCollection services,
        IConfiguration configuration,
        IHostEnvironment? environment = null)
    {
        // Only register PostgreSQL DbContext in non-Testing environments
        if (environment == null || environment.EnvironmentName != "Testing")
        {
            // Register DbContext
            var connectionString = configuration.GetConnectionString("IMDatabase");
            services.AddDbContext<IssueManagementDbContext>(options =>
                options.UseNpgsql(connectionString));
        }

        // Register HTTP Context Accessor (for tenant context)
        services.AddHttpContextAccessor();

        // Register Tenant Context (for multi-tenant isolation)
        services.AddScoped<ColaFlow.Modules.IssueManagement.Infrastructure.Services.ITenantContext,
            ColaFlow.Modules.IssueManagement.Infrastructure.Services.TenantContext>();

        // Register repositories
        services.AddScoped<ColaFlow.Modules.IssueManagement.Domain.Repositories.IIssueRepository, IssueRepository>();
        services.AddScoped<ColaFlow.Modules.IssueManagement.Domain.Repositories.IUnitOfWork, ColaFlow.Modules.IssueManagement.Infrastructure.Persistence.Repositories.UnitOfWork>();

        // Register MediatR handlers from Application assembly
        services.AddMediatR(cfg =>
        {
            cfg.LicenseKey = configuration["MediatR:LicenseKey"];
            cfg.RegisterServicesFromAssembly(typeof(CreateIssueCommand).Assembly);
        });

        // Register FluentValidation validators
        services.AddValidatorsFromAssembly(typeof(CreateIssueCommand).Assembly);

        // Register pipeline behaviors
        services.AddTransient(typeof(IPipelineBehavior<,>), typeof(ColaFlow.Modules.IssueManagement.Application.Behaviors.ValidationBehavior<,>));

        Console.WriteLine("[IssueManagement] Module registered");

        return services;
    }
}
