using GmRelay.DiscordBot.Features.Sessions.Wizard;
using GmRelay.Shared.Features.Sessions.CreateSession.Wizard;
using NetCord.Rest;
using Xunit;

namespace GmRelay.Bot.Tests.Discord.Wizard;

/// <summary>
/// Renderer tests for the Discord wizard's Capacity / PoolSlotCapacity steps.
/// Locks in the presence of the "♾ Без лимита" button so the user can pick
/// a session with no player cap (null in <c>sessions.max_players</c>), the
/// same affordance the Telegram wizard provides.
/// </summary>
public sealed class DiscordWizardStepCapacityRenderTests
{
    [Fact]
    public void RenderCapacity_ContainsNoLimitButton()
    {
        var draft = new WizardDraft { Step = WizardStepNames.Capacity };
        var render = DiscordWizardStep.Render(draft, new WizardPayload());

        var labels = ExtractButtonLabels(render);
        Assert.Contains(labels, l => l.Contains("Без лимита", System.StringComparison.Ordinal));
    }

    [Fact]
    public void RenderPoolSlotCapacity_ContainsNoLimitButton()
    {
        var draft = new WizardDraft { Step = WizardStepNames.PoolSlotCapacity };
        var render = DiscordWizardStep.Render(draft, new WizardPayload());

        var labels = ExtractButtonLabels(render);
        Assert.Contains(labels, l => l.Contains("Без лимита", System.StringComparison.Ordinal));
    }

    [Theory]
    [InlineData(WizardStepNames.Capacity, "wizard:btn:choice:Capacity:no_limit")]
    [InlineData(WizardStepNames.PoolSlotCapacity, "wizard:btn:choice:PoolSlotCapacity:no_limit")]
    public void Render_NoLimitButton_HasChoiceCustomIdForNoLimit(string step, string expectedCustomIdPrefix)
    {
        var draft = new WizardDraft { Step = step };
        var render = DiscordWizardStep.Render(draft, new WizardPayload());

        var buttons = ExtractButtons(render);
        var noLimit = buttons.SingleOrDefault(b => b.Label?.Contains("Без лимита", System.StringComparison.Ordinal) == true);
        Assert.NotNull(noLimit);
        Assert.StartsWith(expectedCustomIdPrefix, noLimit!.CustomId);
    }

    private static System.Collections.Generic.List<string> ExtractButtonLabels(
        DiscordWizardStep.DiscordWizardRender render) =>
        render.Components
            .OfType<ActionRowProperties>()
            .SelectMany(r => r.Components)
            .OfType<ButtonProperties>()
            .Select(b => b.Label ?? string.Empty)
            .ToList();

    private static System.Collections.Generic.List<ButtonProperties> ExtractButtons(
        DiscordWizardStep.DiscordWizardRender render) =>
        render.Components
            .OfType<ActionRowProperties>()
            .SelectMany(r => r.Components)
            .OfType<ButtonProperties>()
            .ToList();
}
