namespace GmRelay.Bot.Tests.Infrastructure.Scheduling;

public sealed class SchedulerNotificationSourceTests
{
    [Theory]
    [InlineData("src/GmRelay.Shared/Features/Confirmation/SendConfirmation/SendConfirmationHandler.cs")]
    [InlineData("src/GmRelay.Shared/Features/Confirmation/HandleRsvp/HandleRsvpHandler.cs")]
    [InlineData("src/GmRelay.Shared/Features/Reminders/SendOneHourReminder/SendOneHourReminderHandler.cs")]
    [InlineData("src/GmRelay.Shared/Features/Reminders/SendJoinLink/SendJoinLinkHandler.cs")]
    public async Task SchedulerNotificationHandlers_ShouldUsePlatformMessengerWithoutSdkClients(string relativePath)
    {
        var source = await ReadRepositoryFileAsync(relativePath);

        Assert.True(
            source.Contains("IPlatformMessenger", StringComparison.Ordinal) ||
            source.Contains("PlatformDirectNotificationSender", StringComparison.Ordinal),
            "Handler should use IPlatformMessenger directly or through PlatformDirectNotificationSender.");
        Assert.DoesNotContain("Telegram.Bot", source, StringComparison.Ordinal);
        Assert.DoesNotContain("ITelegramBotClient", source, StringComparison.Ordinal);
        Assert.DoesNotContain("NetCord", source, StringComparison.Ordinal);
        Assert.DoesNotContain("RestClient", source, StringComparison.Ordinal);
    }

    [Fact]
    public async Task DiscordProgram_ShouldRegisterSharedSchedulerForDiscordPlatform()
    {
        var program = await ReadRepositoryFileAsync("src/GmRelay.DiscordBot/Program.cs");

        Assert.Contains("PlatformSchedulerOptions(PlatformKind.Discord)", program, StringComparison.Ordinal);
        Assert.Contains("AddHostedService<SessionSchedulerService>", program, StringComparison.Ordinal);
        Assert.Contains("DbSessionTriggerStore", program, StringComparison.Ordinal);
        Assert.Contains("SendConfirmationHandler", program, StringComparison.Ordinal);
        Assert.Contains("SendJoinLinkHandler", program, StringComparison.Ordinal);
        Assert.Contains("SendOneHourReminderHandler", program, StringComparison.Ordinal);
    }

    private static async Task<string> ReadRepositoryFileAsync(string relativePath)
    {
        var directory = new DirectoryInfo(AppContext.BaseDirectory);
        while (directory is not null)
        {
            var candidate = Path.Combine(directory.FullName, relativePath);
            if (File.Exists(candidate))
            {
                return await File.ReadAllTextAsync(candidate);
            }

            directory = directory.Parent;
        }

        throw new FileNotFoundException($"Could not locate repository file '{relativePath}'.");
    }
}
