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

namespace ClaudeDo.Worker.Tests.Repositories;

public sealed class TaskRepositoryAgentSettingsTests : IDisposable
{
    private readonly DbFixture _db = new();
    private readonly ClaudeDoDbContext _ctx;
    private readonly TaskRepository _repo;

    public TaskRepositoryAgentSettingsTests()
    {
        _ctx = _db.CreateContext();
        _repo = new TaskRepository(_ctx);
    }

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

    private async Task<string> SeedTaskAsync()
    {
        using var ctx = _db.CreateContext();
        var listId = Guid.NewGuid().ToString();
        var taskId = Guid.NewGuid().ToString();
        await new ListRepository(ctx).AddAsync(new ListEntity
        {
            Id = listId, Name = "L", CreatedAt = DateTime.UtcNow,
        });
        await new TaskRepository(ctx).AddAsync(new TaskEntity
        {
            Id = taskId, ListId = listId, Title = "T", CreatedAt = DateTime.UtcNow,
        });
        return taskId;
    }

    [Fact]
    public async Task UpdateAgentSettingsAsync_SetsAllThreeFields()
    {
        var taskId = await SeedTaskAsync();

        await _repo.UpdateAgentSettingsAsync(taskId, "opus", "system!", "/tmp/a.md");

        var entity = await _repo.GetByIdAsync(taskId);
        Assert.NotNull(entity);
        Assert.Equal("opus", entity!.Model);
        Assert.Equal("system!", entity.SystemPrompt);
        Assert.Equal("/tmp/a.md", entity.AgentPath);
    }

    [Fact]
    public async Task UpdateAgentSettingsAsync_NullsClearColumns()
    {
        var taskId = await SeedTaskAsync();

        using (var ctx = _db.CreateContext())
        {
            await new TaskRepository(ctx).UpdateAgentSettingsAsync(taskId, "opus", "s", "/a.md");
        }

        await _repo.UpdateAgentSettingsAsync(taskId, null, null, null);

        var entity = await _repo.GetByIdAsync(taskId);
        Assert.NotNull(entity);
        Assert.Null(entity!.Model);
        Assert.Null(entity.SystemPrompt);
        Assert.Null(entity.AgentPath);
    }

    [Fact]
    public async Task UpdateAgentSettingsAsync_Persists_SessionSkills()
    {
        var taskId = await SeedTaskAsync();

        await _repo.UpdateAgentSettingsAsync(taskId, null, null, null, sessionSkills: "[\"ponytail\",\"ponytail-help\"]");

        var entity = await _repo.GetByIdAsync(taskId);
        Assert.NotNull(entity);
        Assert.Equal("[\"ponytail\",\"ponytail-help\"]", entity!.SessionSkills);
    }

    [Fact]
    public async Task UpdateAgentSettingsAsync_Null_SessionSkills_ClearsColumn()
    {
        var taskId = await SeedTaskAsync();

        using (var ctx = _db.CreateContext())
        {
            await new TaskRepository(ctx).UpdateAgentSettingsAsync(taskId, null, null, null, sessionSkills: "[\"a\"]");
        }

        await _repo.UpdateAgentSettingsAsync(taskId, null, null, null, sessionSkills: null);

        var entity = await _repo.GetByIdAsync(taskId);
        Assert.NotNull(entity);
        Assert.Null(entity!.SessionSkills);
    }
}
