using ClaudeDo.Data;
using ClaudeDo.Data.Models;
using ClaudeDo.Data.Repositories;
using ClaudeDo.Worker.Tests.Infrastructure;
using TaskStatus = ClaudeDo.Data.Models.TaskStatus;

namespace ClaudeDo.Worker.Tests.Runner;

public sealed class TaskRunnerParentCompletionTests : IDisposable
{
    private readonly DbFixture _db = new();
    private readonly ClaudeDoDbContext _ctx;
    private readonly TaskRepository _tasks;
    private readonly ListRepository _lists;

    public TaskRunnerParentCompletionTests()
    {
        _ctx = _db.CreateContext();
        _tasks = new TaskRepository(_ctx);
        _lists = new ListRepository(_ctx);
    }

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

    [Fact]
    public async Task ChildMarkedDone_LastOne_ParentFinalized()
    {
        var listId = Guid.NewGuid().ToString();
        await _lists.AddAsync(new ListEntity { Id = listId, Name = "L", CreatedAt = DateTime.UtcNow });

        var parent = new TaskEntity
        {
            Id = Guid.NewGuid().ToString(),
            ListId = listId,
            Title = "p",
            Status = TaskStatus.Idle,
            PlanningPhase = PlanningPhase.Finalized,
            CreatedAt = DateTime.UtcNow,
            CommitType = "chore",
        };
        await _tasks.AddAsync(parent);

        var c1 = new TaskEntity
        {
            Id = Guid.NewGuid().ToString(),
            ListId = listId,
            Title = "c1",
            Status = TaskStatus.Done,
            CreatedAt = DateTime.UtcNow,
            CommitType = "chore",
            ParentTaskId = parent.Id,
        };
        var c2 = new TaskEntity
        {
            Id = Guid.NewGuid().ToString(),
            ListId = listId,
            Title = "c2",
            Status = TaskStatus.Running,
            CreatedAt = DateTime.UtcNow,
            CommitType = "chore",
            ParentTaskId = parent.Id,
        };
        await _tasks.AddAsync(c1);
        await _tasks.AddAsync(c2);

        // Simulate the runner finishing the second child:
        await _tasks.MarkDoneAsync(c2.Id, DateTime.UtcNow, "done");
        if (c2.ParentTaskId is not null)
            await _tasks.TryCompleteParentAsync(c2.ParentTaskId);

        var parentLoaded = await _tasks.GetByIdAsync(parent.Id);
        Assert.Equal(TaskStatus.Done, parentLoaded!.Status);
        Assert.NotNull(parentLoaded.FinishedAt);
    }
}
