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

namespace TakeoutSaaS.Integration.Tests.App.Tenants;

public sealed class AnnouncementRegressionTests
{
    [Fact]
    public async Task GivenPublishedAnnouncement_WhenSearchByIsActive_ThenReturns()
    {
        // Arrange
        using var database = new SqliteTestDatabase();
        using var context = database.CreateContext(tenantId: 600, userId: 12);

        var legacy = CreateAnnouncement(tenantId: 600, id: 9100);
        legacy.Status = AnnouncementStatus.Published;

        context.TenantAnnouncements.Add(legacy);
        await context.SaveChangesAsync();
        context.ChangeTracker.Clear();

        var repository = new EfTenantAnnouncementRepository(context);

        // Act
        var results = await repository.SearchAsync(
            tenantId: 600,
            keyword: null,
            status: null,
            type: null,
            isActive: true,
            effectiveFrom: null,
            effectiveTo: null,
            effectiveAt: null,
            cancellationToken: CancellationToken.None);

        // Assert
        results.Should().ContainSingle(x => x.Id == legacy.Id);
    }

    [Fact]
    public async Task GivenDraftAnnouncement_WhenUpdate_ThenUpdatesFieldsAndKeepsInactive()
    {
        // Arrange
        using var database = new SqliteTestDatabase();
        using var context = database.CreateContext(tenantId: 700, userId: 12);

        var announcement = CreateAnnouncement(tenantId: 700, id: 9101);
        announcement.Status = AnnouncementStatus.Draft;
        context.TenantAnnouncements.Add(announcement);
        await context.SaveChangesAsync();
        context.ChangeTracker.Clear();

        var repository = new EfTenantAnnouncementRepository(context);
        var handler = new UpdateTenantAnnouncementCommandHandler(repository);

        var command = new UpdateTenantAnnouncementCommand
        {
            TenantId = 700,
            AnnouncementId = announcement.Id,
            Title = "更新后的标题",
            Content = "更新后的内容",
            TargetType = "ALL_TENANTS",
            RowVersion = announcement.RowVersion
        };

        // Act
        var result = await handler.Handle(command, CancellationToken.None);

        // Assert
        result.Should().NotBeNull();
        result!.Title.Should().Be("更新后的标题");
        result.Content.Should().Be("更新后的内容");
        result.IsActive.Should().BeFalse();
    }

    private static TenantAnnouncement CreateAnnouncement(long tenantId, long id)
        => new()
        {
            Id = id,
            TenantId = tenantId,
            Title = "旧公告",
            Content = "内容",
            AnnouncementType = TenantAnnouncementType.System,
            Priority = 1,
            EffectiveFrom = DateTime.UtcNow.AddMinutes(-5),
            EffectiveTo = null,
            PublisherScope = PublisherScope.Tenant,
            Status = AnnouncementStatus.Draft,
            TargetType = "ALL_TENANTS",
            TargetParameters = null,
            RowVersion = new byte[] { 1 }
        };
}
