using GmRelay.Shared.Platform;
using GmRelay.Shared.Rendering;

namespace GmRelay.Bot.Tests.Platform;

public sealed class PlatformContractsTests
{
    [Fact]
    public void PlatformKind_ShouldDefineTelegramDiscordAndMaxSentinel()
    {
        Assert.Equal(0, (int)PlatformKind.Telegram);
        Assert.Equal(1, (int)PlatformKind.Discord);
        Assert.Equal(2, (int)PlatformKind.Max);
    }

    [Fact]
    public void PlatformContracts_ShouldBeTelegramAssemblyFree()
    {
        var contractTypes = new[]
        {
            typeof(PlatformUser),
            typeof(PlatformGroup),
            typeof(PlatformMessageRef),
            typeof(PlatformMessageAction),
            typeof(PlatformScheduleMessage),
            typeof(PlatformPrivateMessage),
            typeof(PlatformInteractionReply),
            typeof(PlatformCalendarFile),
            typeof(IPlatformMessenger)
        };

        Assert.All(contractTypes, type =>
            Assert.DoesNotContain(
                "Telegram",
                string.Join(" ", type.Assembly.GetReferencedAssemblies().Select(value => value.Name)),
                StringComparison.OrdinalIgnoreCase));
    }

    [Fact]
    public void PlatformScheduleMessage_ShouldCarrySharedViewModelWithoutPlatformTypes()
    {
        var sessionId = Guid.Parse("aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaa");
        var view = SessionBatchViewBuilder.Build(
            "Campaign",
            [new SessionBatchDto(sessionId, new DateTime(2026, 5, 15, 16, 0, 0, DateTimeKind.Utc), "Planned", 4, "https://example.test/game")],
            []);
        var group = new PlatformGroup(PlatformKind.Discord, "guild-1", "Guild", "channel-1", "thread-1");

        var message = new PlatformScheduleMessage(group, view, ExistingMessage: null);

        Assert.Equal(PlatformKind.Discord, message.Group.Platform);
        Assert.Same(view, message.View);
    }

    [Fact]
    public void PlatformNotificationContracts_ShouldBeSdkAssemblyFree()
    {
        var contractTypes = new[]
        {
            typeof(PlatformSessionParticipant),
            typeof(PlatformConfirmationRequest),
            typeof(PlatformJoinLinkNotification),
            typeof(PlatformDirectSessionNotification),
            typeof(PlatformRsvpMessageUpdate),
            typeof(PlatformRsvpOutcomeNotification),
            typeof(PlatformRescheduleVoteUpdate)
        };

        Assert.All(contractTypes, type =>
        {
            var refs = string.Join(" ", type.Assembly.GetReferencedAssemblies().Select(value => value.Name));
            Assert.DoesNotContain("Telegram", refs, StringComparison.OrdinalIgnoreCase);
            Assert.DoesNotContain("NetCord", refs, StringComparison.OrdinalIgnoreCase);
        });
    }

    [Fact]
    public void PlatformMessenger_ShouldExposeSchedulerNotificationOperations()
    {
        var methods = typeof(IPlatformMessenger)
            .GetMethods()
            .Select(method => method.Name)
            .ToHashSet(StringComparer.Ordinal);

        Assert.Contains("SendConfirmationRequestAsync", methods);
        Assert.Contains("UpdateConfirmationRequestAsync", methods);
        Assert.Contains("SendJoinLinkNotificationAsync", methods);
        Assert.Contains("SendDirectSessionNotificationAsync", methods);
        Assert.Contains("SendRsvpOutcomeAsync", methods);
        Assert.Contains("UpdateRescheduleVoteAsync", methods);
    }
}
