import type { Command } from '../commands.js'

/**
 * `/bestof N <task>` — dispatch N parallel subagents to independently
 * plan the same task, then pick the strongest proposal.
 *
 * v0 scope (this file): N agents each return a *plan*, not an applied
 * change. The primary agent compares and either presents the slate or
 * applies the winner. This avoids the parallel-write collision that
 * would require worktree isolation to solve safely.
 *
 * v1 (future, not in scope here): each candidate runs in its own
 * worktree, its tests are measured, and the winner is chosen by
 * trust-delta (successes minus failures weighted by category). That
 * is the full "six-line idea no competitor can copy" framing from the
 * best-on-market review — it depends on taskQueue's worktree executor
 * being wired, which is currently a TODO in services/taskQueue/index.ts.
 */
const ALLOWED_TOOLS = ['Agent']

function parseArgs(rawArgs: string): { n: number; task: string } | { error: string } {
  const trimmed = rawArgs.trim()
  if (!trimmed) {
    return { error: 'Usage: /bestof <N> <task>  (N between 2 and 5)' }
  }
  const match = trimmed.match(/^(\d+)\s+([\s\S]+)$/)
  if (!match) {
    return { error: 'Usage: /bestof <N> <task>  (N between 2 and 5)' }
  }
  const n = parseInt(match[1]!, 10)
  const task = match[2]!.trim()
  if (!Number.isFinite(n) || n < 2 || n > 5) {
    return { error: 'N must be between 2 and 5' }
  }
  if (!task) {
    return { error: 'Task description required after N' }
  }
  return { n, task }
}

function buildPrompt(n: number, task: string): string {
  return `## /bestof — parallel best-of-${n} planning race

The user has asked you to produce the strongest solution to a task by
racing ${n} independent subagents.

**Your instructions — follow exactly:**

1. In a SINGLE message, dispatch ${n} parallel Agent tool calls with
   \`subagent_type: "general-purpose"\`. Each Agent call must receive
   this exact same prompt body:

   > Plan (do not apply) how you would solve this task:
   >
   > ${task}
   >
   > Respond with:
   > - **Approach**: 3–5 sentences describing your plan.
   > - **Risks**: anything that could go wrong.
   > - **Effort**: small / medium / large, with a reason.
   > - **First three steps**: concrete and ordered.
   >
   > Do NOT edit files, run tests, or make network calls. Plan only.

   To encourage diversity, vary the \`description\` between agents with
   different framings (e.g. "conservative plan", "aggressive refactor",
   "minimal-change plan"). Optionally vary the \`model\` field across
   calls (\`sonnet\`, \`haiku\`, or omit for default).

2. Wait for all ${n} results.

3. Present a compact comparison table: each candidate's Effort,
   key Risks, and a one-line distillation of the Approach.

4. Recommend a single winner. Justify the pick in ≤3 sentences,
   grounded in the candidates' Risks and Effort — not vibes.

5. Ask the user: "Apply [winner], show full plan for [N], or stop?"

**Important:**
- Do not begin implementing. /bestof is a planning race only. The
  user chooses whether to apply the winner.
- If any subagent fails or times out, note it in the comparison and
  proceed with the remaining candidates.
- Do not repeat the task text back to the user at the top of your
  response — go straight to dispatching the agents.
`
}

const bestof = {
  type: 'prompt',
  name: 'bestof',
  description: 'Race N parallel subagents on a task, compare proposals, pick the winner',
  allowedTools: ALLOWED_TOOLS,
  contentLength: 0,
  progressMessage: 'racing subagents',
  source: 'builtin',
  async getPromptForCommand(args) {
    const parsed = parseArgs(args)
    if ('error' in parsed) {
      return [{ type: 'text', text: parsed.error }]
    }
    return [{ type: 'text', text: buildPrompt(parsed.n, parsed.task) }]
  },
} satisfies Command

// Exported pure helpers for testing the parser and prompt shape.
export const __testing = { parseArgs, buildPrompt }

export default bestof
