// Supervisor agent: routes user requests to the best agent via a cheap LLM
// classification call. Activated when session.agent_id === 'supervisor'.

import type { Agent } from '../../types/api.js';
import { taskModelCompletion } from '../task-model.js';

export interface SupervisorRoute {
  agent_id: string;
  confidence: number;
  reasoning: string;
}

const SUPERVISOR_SYSTEM_PROMPT = `You are a router. Given the user's request and the available agents, choose the best agent to handle the request.

Rules:
- Match the request to the agent whose description and toolset best fits the task.
- For code review / bug finding requests → code-reviewer
- For debugging / diagnosing failures → debugger
- For refactoring / simplifying code → refactorer
- For architecture / design / planning → architect or planner
- For security audits → security-auditor
- For building prompts for other agents → prompt-builder
- For exploring / understanding unfamiliar code → recon
- For implementing / writing code changes → builder
- Respond with ONLY the agent id (e.g. "builder") or "none" if no agent fits.
- Do not include any other text, punctuation, or explanation.`;

const MAX_ROUTING_TOKENS = 30;

/**
 * Given the user's latest message and available agents, classifies which agent
 * should handle this turn. Returns null to fall through to default (no agent).
 */
export async function resolveSupervisorTurn(
  latestUserMessage: string,
  agents: Agent[],
  fallbackModel?: string,
): Promise<SupervisorRoute | null> {
  // Build agent listing — skip the supervisor itself to avoid self-routing.
  const agentList = agents
    .filter((a) => a.id !== 'supervisor')
    .map((a) => `- ${a.id}: ${a.description} (${a.tools.length} tools)`)
    .join('\n');

  if (!agentList) {
    return null;
  }

  const userPrompt = `Available agents:\n${agentList}\n\nUser request: ${latestUserMessage.slice(0, 2000)}`;

  const response = await taskModelCompletion({
    system: SUPERVISOR_SYSTEM_PROMPT,
    user: userPrompt,
    maxTokens: MAX_ROUTING_TOKENS,
    temperature: 0.1,
    fallbackModel,
  });

  const agentId = response.trim().toLowerCase();
  if (!agentId || agentId === 'none') {
    return null;
  }

  // Map back to a real agent to validate the id.
  const matched = agents.find((a) => a.id === agentId);
  if (!matched) {
    return null;
  }

  return {
    agent_id: matched.id,
    confidence: 1,
    reasoning: `supervisor routed to "${matched.name}" based on request classification`,
  };
}
