using ClaudeDo.Data.Models;
using ClaudeDo.Data.Repositories;
using ClaudeDo.Worker.Hub;
using ClaudeDo.Worker.Tests.Infrastructure;
using Xunit;

namespace ClaudeDo.Worker.Tests.Hub;

public sealed class RepoImportFoldersHubTests : IDisposable
{
    private readonly DbFixture _db = new();

    public void Dispose() => _db.Dispose();

    private WorkerHub CreateHub()
    {
        var broadcaster = new HubBroadcaster(new CapturingHubContext());
        var hub = new WorkerHub(
            null!, null!, null!, null!, broadcaster, _db.CreateFactory(),
            null!, null!, null!, null!, null!, null!, null!, null!, null!, null!, null!, null!, null!,
            null!, new ClaudeDo.Worker.Online.OnlineInboxConfig(), new ClaudeDo.Worker.OnlineRefreshTokenStore(new ClaudeDo.Worker.DpapiTokenStore("unused.token")),
            new ClaudeDo.Worker.Runner.PendingQuestionRegistry(), null!);
        hub.Clients = new FakeHubCallerClients(new RecordingClientProxy());
        hub.Context = new FakeHubCallerContext();
        return hub;
    }

    [Fact]
    public async Task GetRepoImportFolders_NoRow_ReturnsEmptyList()
    {
        var hub = CreateHub();

        var folders = await hub.GetRepoImportFolders();

        Assert.Empty(folders);
    }

    [Fact]
    public async Task SetRepoImportFolders_then_GetRepoImportFolders_RoundTrips()
    {
        var hub = CreateHub();

        await hub.SetRepoImportFolders(new List<string> { @"C:\src\repo-a", @"C:\src\repo-b" });
        var folders = await hub.GetRepoImportFolders();

        Assert.Equal(new List<string> { @"C:\src\repo-a", @"C:\src\repo-b" }, folders);
    }

    [Fact]
    public async Task SetRepoImportFolders_PersistsSameJsonShapeAsRepository()
    {
        var hub = CreateHub();

        await hub.SetRepoImportFolders(new List<string> { @"C:\src\repo-a" });

        using var ctx = _db.CreateContext();
        var viaRepository = await new AppSettingsRepository(ctx).GetRepoImportFoldersAsync();
        Assert.Equal(new List<string> { @"C:\src\repo-a" }, viaRepository);
    }

    [Fact]
    public async Task SetRepoImportFolders_DoesNotClearOtherAppSettings()
    {
        var hub = CreateHub();
        var before = await hub.GetAppSettings();

        await hub.SetRepoImportFolders(new List<string> { @"C:\src\repo-a" });
        var after = await hub.GetAppSettings();

        Assert.Equal(before.DefaultModel, after.DefaultModel);
        Assert.Equal(before.DefaultMaxTurns, after.DefaultMaxTurns);
    }
}
