using System.Data.Common;
using ColaFlow.Modules.Identity.Domain.Aggregates.Tenants;
using ColaFlow.Modules.Identity.Domain.Aggregates.Users;
using ColaFlow.Modules.ProjectManagement.Domain.Aggregates.ProjectAggregate;
using ColaFlow.Modules.ProjectManagement.Domain.ValueObjects;
using Microsoft.AspNetCore.Mvc.Testing;
using Microsoft.Data.Sqlite;
using Microsoft.Extensions.DependencyInjection;

namespace ColaFlow.IntegrationTests.Mcp;

/// <summary>
/// Multi-tenant test fixture for MCP isolation tests
/// Creates multiple test tenants with isolated data
/// </summary>
public class MultiTenantTestFixture : IDisposable
{
    private readonly WebApplicationFactory<Program> _factory;
    private readonly DbConnection _dbConnection;
    private bool _disposed;

    public MultiTenantTestFixture()
    {
        // Create in-memory SQLite database
        _dbConnection = new SqliteConnection("DataSource=:memory:");
        _dbConnection.Open();

        _factory = new WebApplicationFactory<Program>()
            .WithWebHostBuilder(builder =>
            {
                // Configure test services if needed
            });
    }

    public HttpClient CreateClient()
    {
        return _factory.CreateClient();
    }

    public T GetRequiredService<T>() where T : notnull
    {
        var scope = _factory.Services.CreateScope();
        return scope.ServiceProvider.GetRequiredService<T>();
    }

    public void Dispose()
    {
        Dispose(true);
        GC.SuppressFinalize(this);
    }

    protected virtual void Dispose(bool disposing)
    {
        if (!_disposed)
        {
            if (disposing)
            {
                _factory.Dispose();
                _dbConnection.Dispose();
            }
            _disposed = true;
        }
    }
}

/// <summary>
/// Test data for a single tenant
/// </summary>
public class TenantTestData
{
    public Guid TenantId { get; set; }
    public string TenantName { get; set; } = string.Empty;
    public string TenantSlug { get; set; } = string.Empty;
    public Guid UserId { get; set; }
    public string UserEmail { get; set; } = string.Empty;
    public string ApiKey { get; set; } = string.Empty;
    public Guid ApiKeyId { get; set; }
    public List<Guid> ProjectIds { get; set; } = new();
    public List<Guid> EpicIds { get; set; } = new();
    public List<Guid> StoryIds { get; set; } = new();
    public List<Guid> TaskIds { get; set; } = new();
}

/// <summary>
/// Multi-tenant test data generator
/// </summary>
public class MultiTenantDataGenerator
{
    /// <summary>
    /// Create test tenant with user and API key
    /// </summary>
    public static TenantTestData CreateTenantData(string tenantName)
    {
        var tenantId = Guid.NewGuid();
        var userId = Guid.NewGuid();
        var apiKeyId = Guid.NewGuid();

        return new TenantTestData
        {
            TenantId = tenantId,
            TenantName = tenantName,
            TenantSlug = tenantName.ToLower().Replace(" ", "-"),
            UserId = userId,
            UserEmail = $"{tenantName.ToLower().Replace(" ", "")}@test.com",
            ApiKey = $"cola_{Guid.NewGuid():N}",
            ApiKeyId = apiKeyId
        };
    }

    /// <summary>
    /// Create test project for tenant
    /// </summary>
    public static Guid CreateProjectId()
    {
        return Guid.NewGuid();
    }

    /// <summary>
    /// Create test epic for tenant
    /// </summary>
    public static Guid CreateEpicId()
    {
        return Guid.NewGuid();
    }

    /// <summary>
    /// Create test story for tenant
    /// </summary>
    public static Guid CreateStoryId()
    {
        return Guid.NewGuid();
    }

    /// <summary>
    /// Create test task for tenant
    /// </summary>
    public static Guid CreateTaskId()
    {
        return Guid.NewGuid();
    }
}
