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

namespace ClaudeDo.Worker.Tests.Hub;

public sealed class AgentSettingsHubTests : IDisposable
{
    private readonly DbFixture _db = new();
    private readonly ClaudeDo.Data.ClaudeDoDbContext _ctx;
    private readonly ListRepository _repo;

    public AgentSettingsHubTests()
    {
        _ctx = _db.CreateContext();
        _repo = new ListRepository(_ctx);
    }

    public void Dispose()
    {
        _ctx.Dispose();
        _db.Dispose();
    }

    [Fact]
    public async Task UpdateListConfig_AllNull_DeletesRow()
    {
        var listId = Guid.NewGuid().ToString();
        await _repo.AddAsync(new ListEntity { Id = listId, Name = "L", CreatedAt = DateTime.UtcNow });
        await _repo.SetConfigAsync(new ListConfigEntity
        {
            ListId = listId, Model = "opus", SystemPrompt = null, AgentPath = null,
        });

        string? model = null, sp = null, ap = null;
        if (model is null && sp is null && ap is null)
            await _repo.DeleteConfigAsync(listId);
        else
            await _repo.SetConfigAsync(new ListConfigEntity
            {
                ListId = listId, Model = model, SystemPrompt = sp, AgentPath = ap,
            });

        Assert.Null(await _repo.GetConfigAsync(listId));
    }

    [Fact]
    public async Task RestoreDefaultAgents_CopiesMissingBundledFiles()
    {
        var root = Path.Combine(Path.GetTempPath(), $"claudedo_hub_restore_{Guid.NewGuid():N}");
        var bundleDir = Path.Combine(root, "bundle");
        var targetDir = Path.Combine(root, "target");
        try
        {
            Directory.CreateDirectory(bundleDir);
            Directory.CreateDirectory(targetDir);
            await File.WriteAllTextAsync(Path.Combine(bundleDir, "code-reviewer.md"), "body");

            var seeder = new ClaudeDo.Worker.Agents.DefaultAgentSeeder(bundleDir, targetDir);
            var result = await seeder.SeedMissingAsync();

            Assert.Equal(1, result.Copied);
            Assert.Equal(0, result.Skipped);
            Assert.True(File.Exists(Path.Combine(targetDir, "code-reviewer.md")));
        }
        finally
        {
            try { Directory.Delete(root, true); } catch { }
        }
    }
}
