using GmRelay.Shared.Domain;
using GmRelay.Shared.Rendering;

namespace GmRelay.Bot.Tests.Rendering;

public sealed class SessionBatchRendererTests
{
    [Fact]
    public void Render_ShouldOrderSessionsAndSkipButtonsForCancelledSessions()
    {
        var firstSessionId = Guid.NewGuid();
        var secondSessionId = Guid.NewGuid();
        var cancelledSessionId = Guid.NewGuid();

        var sessions = new[]
        {
            new SessionBatchDto(secondSessionId, new DateTime(2026, 4, 27, 18, 0, 0, DateTimeKind.Utc), SessionStatus.Planned, 4),
            new SessionBatchDto(cancelledSessionId, new DateTime(2026, 4, 28, 18, 0, 0, DateTimeKind.Utc), SessionStatus.Cancelled, null),
            new SessionBatchDto(firstSessionId, new DateTime(2026, 4, 26, 18, 0, 0, DateTimeKind.Utc), SessionStatus.Planned, 2)
        };
        var participants = new[]
        {
            new ParticipantBatchDto(secondSessionId, "Alice", "alice", ParticipantRegistrationStatus.Active),
            new ParticipantBatchDto(secondSessionId, "Charlie", null, ParticipantRegistrationStatus.Waitlisted),
            new ParticipantBatchDto(cancelledSessionId, "Bob", null, ParticipantRegistrationStatus.Active)
        };

        var result = SessionBatchRenderer.Render("Campaign", sessions, participants);
        var text = result.Text;
        var buttons = result.Markup.InlineKeyboard.SelectMany(row => row).ToList();

        var firstIndex = text.IndexOf(sessions[2].ScheduledAt.FormatMoscow(), StringComparison.Ordinal);
        var secondIndex = text.IndexOf(sessions[0].ScheduledAt.FormatMoscow(), StringComparison.Ordinal);
        var thirdIndex = text.IndexOf(sessions[1].ScheduledAt.FormatMoscow(), StringComparison.Ordinal);

        Assert.Contains("Campaign", text);
        Assert.True(firstIndex < secondIndex);
        Assert.True(secondIndex < thirdIndex);
        Assert.Contains("Места: 0/2", text);
        Assert.Contains("Места: 1/4", text);
        Assert.Contains("@alice", text);
        Assert.Contains("Лист ожидания (1)", text);
        Assert.Contains("Charlie", text);
        Assert.Contains("Bob", text);
        Assert.Equal(2, result.Markup.InlineKeyboard.Count());
        Assert.Collection(
            buttons.Select(button => button.CallbackData),
            callbackData => Assert.Equal($"join_session:{firstSessionId}", callbackData),
            callbackData => Assert.Equal($"leave_session:{firstSessionId}", callbackData),
            callbackData => Assert.Equal($"join_session:{secondSessionId}", callbackData),
            callbackData => Assert.Equal($"leave_session:{secondSessionId}", callbackData));
        Assert.DoesNotContain(buttons, button => button.CallbackData?.StartsWith("cancel_session:", StringComparison.Ordinal) == true);
        Assert.DoesNotContain(buttons, button => button.CallbackData?.StartsWith("reschedule_session:", StringComparison.Ordinal) == true);
        Assert.DoesNotContain(buttons, button => button.CallbackData?.StartsWith("promote_waitlist:", StringComparison.Ordinal) == true);
    }
}
