namespace GmRelay.Bot.Tests.Web;

public sealed class AuthorizedMembershipServiceTests
{
    [Fact]
    public async Task AuthorizedMembershipService_ShouldRequireAuthenticationForApply()
    {
        var service = await ReadRepositoryFileAsync("src/GmRelay.Web/Services/AuthorizedMembershipService.cs");

        Assert.Contains("ApplyForCurrentUserAsync", service, StringComparison.Ordinal);
        Assert.Contains("User is not authenticated", service, StringComparison.Ordinal);
        Assert.Contains("GetPlayerIdByPlatformIdentityAsync", service, StringComparison.Ordinal);
    }

    [Fact]
    public async Task AuthorizedMembershipService_ShouldValidateMessageLength()
    {
        var service = await ReadRepositoryFileAsync("src/GmRelay.Web/Services/AuthorizedMembershipService.cs");

        Assert.Contains("1000", service, StringComparison.Ordinal);
        Assert.Contains("н", service, StringComparison.Ordinal); // Russian message length
    }

    [Fact]
    public async Task AuthorizedMembershipService_ShouldRestrictGmActionsToGroupManagers()
    {
        var service = await ReadRepositoryFileAsync("src/GmRelay.Web/Services/AuthorizedMembershipService.cs");

        Assert.Contains("ApproveForCurrentGmAsync", service, StringComparison.Ordinal);
        Assert.Contains("RejectForCurrentGmAsync", service, StringComparison.Ordinal);
        Assert.Contains("ResolveMembershipContextForGmAsync", service, StringComparison.Ordinal);
        Assert.Contains("GetGroupIdForMembershipAsync", service, StringComparison.Ordinal);
    }

    [Fact]
    public async Task AuthorizedMembershipService_ShouldExposePendingApplications()
    {
        var service = await ReadRepositoryFileAsync("src/GmRelay.Web/Services/AuthorizedMembershipService.cs");

        Assert.Contains("GetPendingApplicationsAsync", service, StringComparison.Ordinal);
        Assert.Contains("GetPendingApplicationsCountForCurrentGmAsync", service, StringComparison.Ordinal);
        Assert.Contains("GetMineAsync", service, StringComparison.Ordinal);
        Assert.Contains("LeaveClubForCurrentUserAsync", service, 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}'.");
    }
}
