using System.ComponentModel;
using ClaudeDo.Data.Models;
using ClaudeDo.Data.Repositories;
using ClaudeDo.Worker.Agents;
using ClaudeDo.Worker.Lifecycle;
using ModelContextProtocol.Server;
using TaskStatus = ClaudeDo.Data.Models.TaskStatus;

namespace ClaudeDo.Worker.External;

[McpServerToolType]
public sealed class AgentMcpTools
{
    private readonly AgentFileService _agents;

    public AgentMcpTools(AgentFileService agents) => _agents = agents;

    [McpServerTool, Description("List available agent definition files (name, description, path) for use as a task's agent path.")]
    public async Task<IReadOnlyList<AgentInfo>> ListAgents(CancellationToken cancellationToken)
        => await _agents.ScanAsync(cancellationToken);
}

[McpServerToolType]
public sealed class LifecycleMcpTools
{
    private readonly TaskRepository _tasks;
    private readonly TaskResetService _reset;

    public LifecycleMcpTools(TaskRepository tasks, TaskResetService reset)
    {
        _tasks = tasks;
        _reset = reset;
    }

    [McpServerTool, Description("Reset a failed task: discards its worktree and returns it to Idle so it can be run again. Only Failed tasks are accepted.")]
    public async Task ResetFailedTask(string taskId, CancellationToken cancellationToken)
    {
        var task = await _tasks.GetByIdAsync(taskId, cancellationToken)
            ?? throw new InvalidOperationException($"Task {taskId} not found.");
        if (task.Status != TaskStatus.Failed)
            throw new InvalidOperationException($"Task {taskId} is {task.Status}, not Failed. Only failed tasks can be reset via this tool.");

        await _reset.ResetAsync(taskId, cancellationToken);
    }
}
