using GmRelay.Bot.Infrastructure.Telegram;
using GmRelay.Shared.Domain;
using GmRelay.Shared.Rendering;
using Telegram.Bot.Types.ReplyMarkups;

namespace GmRelay.Bot.Tests.Rendering;

public sealed class TelegramSessionBatchRendererTests
{
    [Fact]
    public void Render_ShouldProduceCorrectHtmlAndButtons()
    {
        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, "https://example.com/game2"),
            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, "https://example.com/game1")
        };
        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 view = SessionBatchViewBuilder.Build("Campaign", sessions, participants);
        var (text, markup) = TelegramSessionBatchRenderer.Render(view);

        Assert.Contains("Campaign", text);
        Assert.Contains("@alice", text);
        Assert.Contains("Charlie", text);
        Assert.Contains("Bob", text);
        Assert.Contains("Сессия отменена", text);
        Assert.Contains("Ссылка на игру", text);
        Assert.Contains("https://example.com/game1", text);
        Assert.Contains("https://example.com/game2", text);

        var buttons = markup.InlineKeyboard.SelectMany(row => row).ToList();
        Assert.Equal(4, buttons.Count); // 2 sessions x 2 buttons each

        Assert.Contains(buttons, b => b.CallbackData == $"join_session:{firstSessionId}");
        Assert.Contains(buttons, b => b.CallbackData == $"leave_session:{firstSessionId}");
        Assert.Contains(buttons, b => b.CallbackData == $"join_session:{secondSessionId}");
        Assert.Contains(buttons, b => b.CallbackData == $"leave_session:{secondSessionId}");
        Assert.DoesNotContain(buttons, b => b.CallbackData?.StartsWith("cancel") == true);
        Assert.DoesNotContain(buttons, b => b.CallbackData?.StartsWith("reschedule") == true);
    }

    [Fact]
    public void Render_ShouldSkipButtonsForCancelledSessions()
    {
        var cancelledSessionId = Guid.NewGuid();
        var sessions = new[] { new SessionBatchDto(cancelledSessionId, DateTime.UtcNow, SessionStatus.Cancelled, null, "") };
        var participants = Array.Empty<ParticipantBatchDto>();

        var view = SessionBatchViewBuilder.Build("Test", sessions, participants);
        var (_, markup) = TelegramSessionBatchRenderer.Render(view);

        Assert.Empty(markup.InlineKeyboard);
    }

    [Fact]
    public void Render_ShouldShowWaitlistButtonWhenFull()
    {
        var sessionId = Guid.NewGuid();
        var sessions = new[] { new SessionBatchDto(sessionId, DateTime.UtcNow, SessionStatus.Planned, 1, "https://example.com/game") };
        var participants = new[] { new ParticipantBatchDto(sessionId, "Alice", "alice", ParticipantRegistrationStatus.Active) };

        var view = SessionBatchViewBuilder.Build("Test", sessions, participants);
        var (_, markup) = TelegramSessionBatchRenderer.Render(view);
        var buttons = markup.InlineKeyboard.SelectMany(row => row).ToList();
        var joinButton = buttons.First(b => b.CallbackData?.StartsWith("join_session:") == true);

        Assert.Contains("ожидания", joinButton.Text);
    }
}
