using System.Diagnostics;
using FluentAssertions;
using TakeoutSaaS.Application.App.Tenants.Handlers;
using TakeoutSaaS.Application.App.Tenants.Queries;
using TakeoutSaaS.Domain.Tenants.Entities;
using TakeoutSaaS.Domain.Tenants.Enums;
using TakeoutSaaS.Infrastructure.App.Repositories;
using TakeoutSaaS.Integration.Tests.Fixtures;

namespace TakeoutSaaS.Integration.Tests.Performance;

public sealed class AnnouncementQueryPerformanceTests
{
    [Fact]
    public async Task GivenLargeDataset_WhenQueryingAnnouncements_ThenCompletesWithinThreshold()
    {
        // Arrange
        using var database = new SqliteTestDatabase();
        using var context = database.CreateContext(tenantId: 900);

        var announcements = new List<TenantAnnouncement>();
        for (var i = 0; i < 1000; i++)
        {
            var tenantId = i % 2 == 0 ? 900 : 0;
            var targetType = i % 10 == 0 ? "ROLES" : "ALL_TENANTS";
            var targetParameters = i % 10 == 0 ? "{\"roles\":[\"ops\"]}" : null;

            announcements.Add(new TenantAnnouncement
            {
                Id = 10000 + i,
                TenantId = tenantId,
                Title = "公告",
                Content = "内容",
                AnnouncementType = TenantAnnouncementType.System,
                Priority = i % 5,
                EffectiveFrom = DateTime.UtcNow.AddDays(-1),
                PublisherScope = tenantId == 0 ? PublisherScope.Platform : PublisherScope.Tenant,
                Status = AnnouncementStatus.Published,
                TargetType = targetType,
                TargetParameters = targetParameters,
                RowVersion = new byte[] { 1 }
            });
        }

        context.TenantAnnouncements.AddRange(announcements);
        await context.SaveChangesAsync();
        context.ChangeTracker.Clear();

        var announcementRepository = new EfTenantAnnouncementRepository(context);
        var readRepository = new EfTenantAnnouncementReadRepository(context);
        var tenantProvider = new TestTenantProvider(900);
        var handler = new GetTenantsAnnouncementsQueryHandler(
            announcementRepository,
            readRepository,
            tenantProvider);

        var query = new GetTenantsAnnouncementsQuery
        {
            Page = 1,
            PageSize = 50
        };

        // Act
        var stopwatch = Stopwatch.StartNew();
        var result = await handler.Handle(query, CancellationToken.None);
        stopwatch.Stop();

        // Assert
        // 注意：由于性能优化，TotalCount 不再是精确的全局总数，
        // 而是基于估算查询限制（page * size * 3）过滤后的结果数
        // 这是性能优化的权衡：牺牲精确性换取性能
        result.Items.Count.Should().Be(50);  // 请求的页大小
        result.TotalCount.Should().BeLessThanOrEqualTo(150);  // 最多是 estimatedLimit
        result.TotalCount.Should().BeGreaterThan(0);  // 至少有一些结果
        stopwatch.Elapsed.Should().BeLessThan(TimeSpan.FromSeconds(5));
    }
}
