using System;
using System.Threading;
using System.Threading.Tasks;
using GmRelay.Bot.Features.Sessions.CreateSession;
using GmRelay.Shared.Features.Sessions.CreateSession.Wizard;
using Microsoft.Extensions.Logging.Abstractions;
using static GmRelay.Bot.Tests.Features.Sessions.CreateSession.Wizard.WizardTestFakes;

namespace GmRelay.Bot.Tests.Features.Sessions.CreateSession.Wizard;

/// <summary>
/// Verifies that <see cref="CreateSessionHandler.SubmitDraftAsync"/> bails
/// out gracefully when the wizard payload is missing required fields. The
/// missing-fields path returns before the shared handler is ever called,
/// so we pass <c>null!</c> for the shared dependency — a NRE on that
/// branch would itself prove the validation did not fire.
/// </summary>
public sealed class CreateSessionHandlerSubmitMissingFieldsTests
{
    [Fact]
    public async Task SubmitDraftAsync_EmptyPayload_EditsMessageWithMissingFields()
    {
        var drafts = new FakeWizardDraftRepository();
        var messenger = new FakeWizardMessenger();

        var sut = new CreateSessionHandler(
            drafts,
            shared: null!,  // missing-fields path returns before touching the shared handler
            messenger,
            NullLogger<CreateSessionHandler>.Instance);

        // Empty payload → every required field is missing.
        var draft = NewDraft(WizardStepNames.Confirm, new WizardPayload());
        drafts.Seed(draft);

        await sut.SubmitDraftAsync(draft, CancellationToken.None);

        // The wizard message is edited to surface the missing-field error.
        Assert.Single(messenger.Edits);
        var edit = messenger.Edits[0];
        Assert.Equal(long.Parse(draft.ChatId, System.Globalization.CultureInfo.InvariantCulture), edit.ChatId);
        Assert.Contains("Не заполнены", edit.Text, StringComparison.OrdinalIgnoreCase);
    }

    [Fact]
    public async Task SubmitDraftAsync_MissingTitleOnly_EditsMessageNamingTitle()
    {
        var drafts = new FakeWizardDraftRepository();
        var messenger = new FakeWizardMessenger();

        var sut = new CreateSessionHandler(
            drafts,
            shared: null!,
            messenger,
            NullLogger<CreateSessionHandler>.Instance);

        // All required fields set except Title.
        var payload = new WizardPayload
        {
            Type = WizardCreationType.Single,
            System = "Dnd5e",
            DurationMinutes = 240,
            Visibility = WizardVisibility.Public,
            Single = new WizardSingleInput
            {
                ScheduledAt = DateTimeOffset.UtcNow.AddDays(7),
                MaxPlayers = 4,
            },
        };
        var draft = NewDraft(WizardStepNames.Confirm, payload);
        drafts.Seed(draft);

        await sut.SubmitDraftAsync(draft, CancellationToken.None);

        Assert.Single(messenger.Edits);
        Assert.Contains("название", messenger.Edits[0].Text, StringComparison.OrdinalIgnoreCase);
    }
}
