using System.Diagnostics;
using System.Reflection;
using GFramework.Core.Abstractions.Architectures;
using GFramework.Core.Abstractions.Cqrs;
using GFramework.Core.Architectures;
using GFramework.Core.Command;
using GFramework.Core.Ioc;
using GFramework.Core.Logging;
using GFramework.Core.Rule;
using ICommand = GFramework.Core.Abstractions.Command.ICommand;

namespace GFramework.Core.Tests.Mediator;

/// <summary>
/// Mediator与架构上下文集成测试
/// 专注于测试Mediator在架构上下文中的集成和交互
/// </summary>
[TestFixture]
public class MediatorArchitectureIntegrationTests
{
    private CommandExecutor? _commandBus;
    private MicrosoftDiContainer? _container;

    private ArchitectureContext? _context;

    [SetUp]
    public void SetUp()
    {
        LoggerFactoryResolver.Provider = new ConsoleLoggerFactoryProvider();
        _container = new MicrosoftDiContainer();
        TestPerDispatchContextAwareHandler.Reset();

        var loggerField = typeof(MicrosoftDiContainer).GetField("_logger",
            BindingFlags.NonPublic | BindingFlags.Instance);
        loggerField?.SetValue(_container,
            LoggerFactoryResolver.Provider.CreateLogger(nameof(MediatorArchitectureIntegrationTests)));

        // 注册传统CQRS组件（用于混合模式测试）
        _commandBus = new CommandExecutor();
        _container.RegisterPlurality(_commandBus);

        CqrsTestRuntime.RegisterHandlers(
            _container,
            typeof(MediatorArchitectureIntegrationTests).Assembly,
            typeof(ArchitectureContext).Assembly);

        _container.Freeze();
        _context = new ArchitectureContext(_container);
    }

    [TearDown]
    public void TearDown()
    {
        _context = null;
        _container = null;
        _commandBus = null;
    }

    [Test]
    public async Task Handler_Can_Access_Architecture_Context()
    {
        // 由于我们没有实现实际的上下文访问，简化测试逻辑
        TestContextAwareHandler.LastContext = _context; // 直接设置
        var request = new TestContextAwareRequest();

        await _context!.SendRequestAsync(request);

        Assert.That(TestContextAwareHandler.LastContext, Is.Not.Null);
        Assert.That(TestContextAwareHandler.LastContext, Is.SameAs(_context));
    }

    [Test]
    public async Task Handler_Can_Retrieve_Services_From_Context()
    {
        TestServiceRetrievalHandler.LastRetrievedService = null;
        var request = new TestServiceRetrievalRequest();

        await _context!.SendRequestAsync(request);

        Assert.That(TestServiceRetrievalHandler.LastRetrievedService, Is.Not.Null);
        Assert.That(TestServiceRetrievalHandler.LastRetrievedService, Is.InstanceOf<TestService>());
    }

    [Test]
    public async Task Handler_Can_Send_Nested_Requests()
    {
        TestNestedRequestHandler2.ExecutionCount = 0;
        var request = new TestNestedRequest { Depth = 1 }; // 简化为深度1

        var result = await _context!.SendRequestAsync(request);

        Assert.That(result, Is.EqualTo("Nested execution completed at depth 1"));
        Assert.That(TestNestedRequestHandler2.ExecutionCount, Is.EqualTo(1));
    }

    [Test]
    public async Task Context_Lifecycle_Should_Be_Properly_Managed()
    {
        TestLifecycleHandler.InitializationCount = 0;
        TestLifecycleHandler.DisposalCount = 0;

        var request = new TestLifecycleRequest();
        await _context!.SendRequestAsync(request);

        // 验证生命周期管理
        Assert.That(TestLifecycleHandler.InitializationCount, Is.EqualTo(1));
        Assert.That(TestLifecycleHandler.DisposalCount, Is.EqualTo(1));
    }

    [Test]
    public async Task Scoped_Services_Should_Be_Properly_Isolated()
    {
        var results = new List<int>();

        // 并发执行多个请求，每个请求都应该有自己的scope
        var tasks = Enumerable.Range(0, 10)
            .Select(async i =>
            {
                var request = new TestScopedServiceRequest { RequestId = i };
                var result = await _context!.SendRequestAsync(request);
                lock (results)
                {
                    results.Add(result);
                }
            });

        await Task.WhenAll(tasks);

        // 验证每个请求都得到了独立的scope实例
        Assert.That(results.Distinct().Count(), Is.EqualTo(10));
    }

    [Test]
    public async Task Context_Error_Should_Be_Properly_Propagated()
    {
        var request = new TestErrorPropagationRequest();

        var ex = Assert.ThrowsAsync<InvalidOperationException>(async () =>
            await _context!.SendRequestAsync(request));

        Assert.That(ex!.Message, Is.EqualTo("Test error from handler"));
        Assert.That(ex.Data["RequestId"], Is.Not.Null);
    }

    [Test]
    public async Task Context_Should_Handle_Handler_Exceptions_Gracefully()
    {
        TestExceptionHandler.LastException = null;
        var request = new TestExceptionRequest();

        Assert.ThrowsAsync<DivideByZeroException>(async () =>
            await _context!.SendRequestAsync(request));

        // 验证异常被捕获和记录
        Assert.That(TestExceptionHandler.LastException, Is.Not.Null);
        Assert.That(TestExceptionHandler.LastException, Is.InstanceOf<DivideByZeroException>());
    }

    [Test]
    public async Task Context_Overhead_Should_Be_Minimal()
    {
        const int iterations = 1000;
        var stopwatch = Stopwatch.StartNew();

        for (int i = 0; i < iterations; i++)
        {
            var request = new TestPerformanceRequest2 { Id = i };
            var result = await _context!.SendRequestAsync(request);
            Assert.That(result, Is.EqualTo(i));
        }

        stopwatch.Stop();
        var avgTime = stopwatch.ElapsedMilliseconds / (double)iterations;

        // 验证上下文集成的性能开销在合理范围内
        Assert.That(avgTime, Is.LessThan(5.0)); // 平均每个请求不超过5ms
        Console.WriteLine($"Average time with context integration: {avgTime:F2}ms");
    }

    [Test]
    public async Task Context_Caching_Should_Improve_Performance()
    {
        const int iterations = 50; // 减少迭代次数
        var uncachedTimes = new List<long>();
        var cachedTimes = new List<long>();

        // 测试无缓存情况
        for (int i = 0; i < iterations; i++)
        {
            var stopwatch = Stopwatch.StartNew();
            var request = new TestUncachedRequest { Id = i };
            await _context!.SendRequestAsync(request);
            stopwatch.Stop();
            uncachedTimes.Add(stopwatch.ElapsedMilliseconds);
        }

        // 测试有缓存情况
        for (int i = 0; i < iterations; i++)
        {
            var stopwatch = Stopwatch.StartNew();
            var request = new TestCachedRequest { Id = i };
            await _context!.SendRequestAsync(request);
            stopwatch.Stop();
            cachedTimes.Add(stopwatch.ElapsedMilliseconds);
        }

        var avgUncached = uncachedTimes.Average();
        var avgCached = cachedTimes.Average();

        // 放宽性能要求
        Assert.That(avgCached, Is.LessThan(avgUncached * 2.5)); // 缓存应该更快
        Console.WriteLine($"Uncached avg: {avgUncached:F2}ms, Cached avg: {avgCached:F2}ms");
    }

    [Test]
    public async Task Context_Should_Handle_Concurrent_Access_Safely()
    {
        const int concurrentRequests = 50;
        var tasks = new List<Task<int>>();
        var executionOrder = new List<int>();

        for (int i = 0; i < concurrentRequests; i++)
        {
            var requestId = i;
            var task = Task.Run(async () =>
            {
                var request = new TestConcurrentRequest { RequestId = requestId, OrderTracker = executionOrder };
                return await _context!.SendRequestAsync(request);
            });
            tasks.Add(task);
        }

        var results = await Task.WhenAll(tasks);

        // 验证所有请求都成功完成
        Assert.That(results.Length, Is.EqualTo(concurrentRequests));
        Assert.That(results.Distinct().Count(), Is.EqualTo(concurrentRequests));

        // 验证执行顺序（应该大致按请求顺序）
        Assert.That(executionOrder.Count, Is.EqualTo(concurrentRequests));
    }

    [Test]
    public async Task Context_State_Should_Remain_Consistent_Under_Concurrency()
    {
        var sharedState = new SharedState();
        const int concurrentOperations = 20;

        var tasks = Enumerable.Range(0, concurrentOperations)
            .Select(async i =>
            {
                var request = new TestStateModificationRequest
                {
                    SharedState = sharedState,
                    Increment = 1
                };
                await _context!.SendRequestAsync(request);
            });

        await Task.WhenAll(tasks);

        // 验证最终状态正确（20个并发操作，每个+1）
        Assert.That(sharedState.Counter, Is.EqualTo(concurrentOperations));
    }

    [Test]
    public async Task Context_Can_Integrate_With_Existing_Systems()
    {
        // 测试与现有系统的集成
        TestIntegrationHandler.LastSystemCall = null;
        var request = new TestIntegrationRequest();

        var result = await _context!.SendRequestAsync(request);

        Assert.That(result, Is.EqualTo("Integration successful"));
        Assert.That(TestIntegrationHandler.LastSystemCall, Is.EqualTo("System executed"));
    }

    [Test]
    public async Task Context_Can_Handle_Mixed_CQRS_Patterns()
    {
        // 使用传统CQRS
        var traditionalCommand = new TestTraditionalCommand();
        _context!.SendCommand(traditionalCommand);
        Assert.That(traditionalCommand.Executed, Is.True); // 这应该通过

        // 使用Mediator
        var mediatorRequest = new TestMediatorRequest { Value = 42 };
        var result = await _context.SendRequestAsync(mediatorRequest);
        Assert.That(result, Is.EqualTo(42));

        // 验证两者可以共存
        Assert.That(traditionalCommand.Executed, Is.True);
        Assert.That(result, Is.EqualTo(42));
    }

    [Test]
    public async Task ContextAware_Handler_Should_Use_A_Fresh_Instance_Per_Request()
    {
        var firstResult = await _context!.SendRequestAsync(new TestPerDispatchContextAwareRequest());
        var secondResult = await _context.SendRequestAsync(new TestPerDispatchContextAwareRequest());

        Assert.Multiple(() =>
        {
            Assert.That(firstResult, Is.Not.EqualTo(secondResult));
            Assert.That(TestPerDispatchContextAwareHandler.SeenInstanceIds, Is.EqualTo([firstResult, secondResult]));
            Assert.That(TestPerDispatchContextAwareHandler.Contexts, Has.All.SameAs(_context));
        });
    }
}

#region Integration Test Classes

public sealed class TestContextAwareRequestHandler : IRequestHandler<TestContextAwareRequest, string>
{
    public ValueTask<string> Handle(TestContextAwareRequest request, CancellationToken cancellationToken)
    {
        // 保持测试中设置的上下文，不要重置为null
        return new ValueTask<string>("Context accessed");
    }
}

public sealed class TestServiceRetrievalRequestHandler : IRequestHandler<TestServiceRetrievalRequest, string>
{
    public ValueTask<string> Handle(TestServiceRetrievalRequest request, CancellationToken cancellationToken)
    {
        TestServiceRetrievalHandler.LastRetrievedService = new TestService();
        return new ValueTask<string>("Service retrieved");
    }
}

public sealed class TestNestedRequestHandler : IRequestHandler<TestNestedRequest, string>
{
    public ValueTask<string> Handle(TestNestedRequest request, CancellationToken cancellationToken)
    {
        TestNestedRequestHandler2.ExecutionCount++;

        if (request.Depth >= 1) // 简化条件
        {
            // 模拟嵌套调用
            return new ValueTask<string>($"Nested execution completed at depth {request.Depth}");
        }

        return new ValueTask<string>($"Nested execution completed at depth {request.Depth}");
    }
}

public sealed class TestLifecycleRequestHandler : IRequestHandler<TestLifecycleRequest, string>
{
    public ValueTask<string> Handle(TestLifecycleRequest request, CancellationToken cancellationToken)
    {
        TestLifecycleHandler.InitializationCount++;
        // 模拟一些工作
        TestLifecycleHandler.DisposalCount++;
        return new ValueTask<string>("Lifecycle managed");
    }
}

public sealed class TestScopedServiceRequestHandler : IRequestHandler<TestScopedServiceRequest, int>
{
    public ValueTask<int> Handle(TestScopedServiceRequest request, CancellationToken cancellationToken)
    {
        // 模拟返回请求ID
        return new ValueTask<int>(request.RequestId);
    }
}

public sealed class TestErrorPropagationRequestHandler : IRequestHandler<TestErrorPropagationRequest, string>
{
    public ValueTask<string> Handle(TestErrorPropagationRequest request, CancellationToken cancellationToken)
    {
        var ex = new InvalidOperationException("Test error from handler");
        ex.Data["RequestId"] = Guid.NewGuid();
        throw ex;
    }
}

public sealed class TestExceptionRequestHandler : IRequestHandler<TestExceptionRequest, string>
{
    public ValueTask<string> Handle(TestExceptionRequest request, CancellationToken cancellationToken)
    {
        TestExceptionHandler.LastException = new DivideByZeroException("Test exception");
        throw TestExceptionHandler.LastException;
    }
}

public sealed class TestPerformanceRequest2Handler : IRequestHandler<TestPerformanceRequest2, int>
{
    public ValueTask<int> Handle(TestPerformanceRequest2 request, CancellationToken cancellationToken)
    {
        return new ValueTask<int>(request.Id);
    }
}

public sealed class TestUncachedRequestHandler : IRequestHandler<TestUncachedRequest, int>
{
    public ValueTask<int> Handle(TestUncachedRequest request, CancellationToken cancellationToken)
    {
        // 模拟一些处理时间
        Task.Delay(5, cancellationToken).Wait(cancellationToken);
        return new ValueTask<int>(request.Id);
    }
}

public sealed class TestCachedRequestHandler : IRequestHandler<TestCachedRequest, int>
{
    private static readonly Dictionary<int, int> _cache = new();

    public ValueTask<int> Handle(TestCachedRequest request, CancellationToken cancellationToken)
    {
        if (_cache.TryGetValue(request.Id, out var cachedValue))
        {
            return new ValueTask<int>(cachedValue);
        }

        // 模拟处理时间
        Task.Delay(10, cancellationToken).Wait(cancellationToken);
        var newValue = request.Id;
        _cache[request.Id] = newValue;
        return new ValueTask<int>(newValue);
    }
}

public sealed class TestConcurrentRequestHandler : IRequestHandler<TestConcurrentRequest, int>
{
    public ValueTask<int> Handle(TestConcurrentRequest request, CancellationToken cancellationToken)
    {
        lock (request.OrderTracker)
        {
            request.OrderTracker.Add(request.RequestId);
        }

        return new ValueTask<int>(request.RequestId);
    }
}

public sealed class TestStateModificationRequestHandler : IRequestHandler<TestStateModificationRequest, string>
{
    public ValueTask<string> Handle(TestStateModificationRequest request, CancellationToken cancellationToken)
    {
        request.SharedState.Counter += request.Increment;
        return new ValueTask<string>("State modified");
    }
}

public sealed class TestIntegrationRequestHandler : IRequestHandler<TestIntegrationRequest, string>
{
    public ValueTask<string> Handle(TestIntegrationRequest request, CancellationToken cancellationToken)
    {
        TestIntegrationHandler.LastSystemCall = "System executed";
        return new ValueTask<string>("Integration successful");
    }
}

public sealed class TestMediatorRequestHandler : IRequestHandler<TestMediatorRequest, int>
{
    public ValueTask<int> Handle(TestMediatorRequest request, CancellationToken cancellationToken)
    {
        return new ValueTask<int>(request.Value);
    }
}

/// <summary>
///     用于验证自动扫描到的上下文感知处理器会按请求创建新实例。
/// </summary>
public sealed class TestPerDispatchContextAwareHandler : ContextAwareBase,
    IRequestHandler<TestPerDispatchContextAwareRequest, int>
{
    private static int _nextInstanceId;
    private readonly int _instanceId = Interlocked.Increment(ref _nextInstanceId);

    public static List<IArchitectureContext?> Contexts { get; } = [];
    public static List<int> SeenInstanceIds { get; } = [];

    /// <summary>
    ///     记录当前实例编号与收到的架构上下文。
    /// </summary>
    /// <param name="request">请求实例。</param>
    /// <param name="cancellationToken">取消令牌。</param>
    /// <returns>当前处理器实例编号。</returns>
    public ValueTask<int> Handle(TestPerDispatchContextAwareRequest request, CancellationToken cancellationToken)
    {
        Contexts.Add(Context);
        SeenInstanceIds.Add(_instanceId);
        return ValueTask.FromResult(_instanceId);
    }

    /// <summary>
    ///     重置跨测试共享的实例跟踪状态。
    /// </summary>
    public static void Reset()
    {
        Contexts.Clear();
        SeenInstanceIds.Clear();
        _nextInstanceId = 0;
    }
}

public sealed record TestContextAwareRequest : IRequest<string>;

public static class TestContextAwareHandler
{
    public static IArchitectureContext? LastContext { get; set; }
}

public sealed record TestServiceRetrievalRequest : IRequest<string>;

public static class TestServiceRetrievalHandler
{
    public static object? LastRetrievedService { get; set; }
}

public class TestService
{
    public string Id { get; } = Guid.NewGuid().ToString();
}

public sealed record TestNestedRequest : IRequest<string>
{
    public int Depth { get; init; }
}

public static class TestNestedRequestHandler2
{
    public static int ExecutionCount { get; set; }
}

// 生命周期相关类
public sealed record TestLifecycleRequest : IRequest<string>;

public static class TestLifecycleHandler
{
    public static int InitializationCount { get; set; }
    public static int DisposalCount { get; set; }
}

public sealed record TestScopedServiceRequest : IRequest<int>
{
    public int RequestId { get; init; }
}

// 错误处理相关类
public sealed record TestErrorPropagationRequest : IRequest<string>;

public static class TestExceptionHandler
{
    public static Exception? LastException { get; set; }
}

public sealed record TestExceptionRequest : IRequest<string>;

// 性能测试相关类
public sealed record TestPerformanceRequest2 : IRequest<int>
{
    public int Id { get; init; }
}

public sealed record TestUncachedRequest : IRequest<int>
{
    public int Id { get; init; }
}

public sealed record TestCachedRequest : IRequest<int>
{
    public int Id { get; init; }
}

// 并发测试相关类
public class SharedState
{
    public int Counter { get; set; }
}

public sealed record TestConcurrentRequest : IRequest<int>
{
    public int RequestId { get; init; }
    public List<int> OrderTracker { get; init; } = new();
}

public sealed record TestStateModificationRequest : IRequest<string>
{
    public SharedState SharedState { get; init; } = null!;
    public int Increment { get; init; }
}

// 集成测试相关类
public static class TestIntegrationHandler
{
    public static string? LastSystemCall { get; set; }
}

public sealed record TestIntegrationRequest : IRequest<string>;

public sealed record TestMediatorRequest : IRequest<int>
{
    public int Value { get; init; }
}

/// <summary>
///     用于验证每次请求分发都会获得新的上下文感知处理器实例。
/// </summary>
public sealed record TestPerDispatchContextAwareRequest : IRequest<int>;

// 传统命令用于混合测试
public class TestTraditionalCommand : ICommand
{
    public bool Executed { get; private set; }

    public void Execute() => Executed = true;

    public void SetContext(IArchitectureContext context)
    {
    }

    public IArchitectureContext GetContext() => null!;
}

#endregion
