using System.ComponentModel;
using ClaudeDo.Worker.Findings;
using ClaudeDo.Worker.Git;
using ModelContextProtocol.Server;

namespace ClaudeDo.Worker.External;

public sealed record SaveFindingResult(
    bool Saved, string Slug, string List, string Path, int TotalFindings, bool NearCapacity);

[McpServerToolType]
public sealed class FindingsMcpTools
{
    private readonly FindingsStore _store;
    private readonly FindingsStoreLocator _locator;

    public FindingsMcpTools(FindingsStore store, FindingsStoreLocator locator)
    {
        _store = store;
        _locator = locator;
    }

    [McpServerTool, Description(
        "Record a durable trap you just learned about this codebase, so future sessions read it " +
        "instead of rediscovering it. Save only what is lasting, non-obvious and behaviour-changing " +
        "(\"X looks like Y but is Z — do W instead\"); a bug you fixed is git history, not a finding. " +
        "When unsure, don't. Re-using a slug overwrites it. nearCapacity=true means the index is " +
        "getting too long to stay cheap — prune before adding more.")]
    public async Task<SaveFindingResult> SaveFinding(
        [Description("Stable lowercase kebab-case id, max 60 chars, e.g. 'conpty-arg-quoting'. Same slug overwrites.")] string slug,
        [Description("One full sentence stating the trap itself — this is the index line other agents scan.")] string title,
        [Description("2-6 sentences: what happens, why it does not look like that, what to do instead.")] string body,
        [Description("Repo-relative path or subsystem the finding applies to, e.g. 'src/ClaudeDo.Worker/Planning'.")] string scope = "",
        [Description("List id or name. Optional when exactly one list has a working directory.")] string list = "",
        CancellationToken cancellationToken = default)
    {
        var target = await _locator.ResolveForListAsync(list, cancellationToken);
        var head = await GitHead.ShortAsync(target.WorkingDir, cancellationToken);

        var outcome = await _store.SaveAsync(
            target.WorkingDir,
            new FindingInput(slug, title, body, scope, SourceTaskId: "", VerifiedAgainst: head),
            cancellationToken,
            target.Tracked);

        return new SaveFindingResult(
            true, outcome.Slug, target.ListName, outcome.Path, outcome.TotalFindings, outcome.NearCapacity);
    }
}
