#!/usr/bin/env node

/**
 * MORPH-SPEC Semantic Agent Detection (LLM-based)
 *
 * Uses LLM analysis to detect which agents should be activated based on user request.
 * More accurate than keyword matching - understands context and implicit needs.
 *
 * Usage:
 *   export ANTHROPIC_API_KEY=sk-...
 *   node bin/semantic-detect-agents.js "user request here"
 *
 * Falls back to keyword-based detection if API key not available.
 */

import fs from 'fs';
import path from 'path';
import { fileURLToPath } from 'url';
import { execSync } from 'child_process';

const __filename = fileURLToPath(import.meta.url);
const __dirname = path.dirname(__filename);

// ANSI colors
const colors = {
  green: '\x1b[32m',
  red: '\x1b[31m',
  yellow: '\x1b[33m',
  cyan: '\x1b[36m',
  gray: '\x1b[90m',
  reset: '\x1b[0m'
};

/**
 * Call Anthropic Claude API for semantic analysis
 */
async function callClaudeAPI(userRequest, agentDescriptions) {
  const apiKey = process.env.ANTHROPIC_API_KEY;

  if (!apiKey) {
    return null; // Will fall back to keyword detection
  }

  const prompt = `You are an expert at analyzing software development requests and determining which specialist agents are needed.

Given this user request:
"${userRequest}"

And these available specialist agents:
${agentDescriptions}

Analyze the request and determine which specialist agents should be activated. Consider:
- Explicit mentions (e.g., "create a dashboard" → UI/UX Designer)
- Implicit needs (e.g., "show data to users" → UI/UX Designer)
- Technical requirements (e.g., "scheduled tasks" → Hangfire Orchestrator)
- Architecture patterns (e.g., "RAG pipeline" → AI System Architect)

Respond with ONLY a JSON array of agent IDs, like:
["uiux-designer", "hangfire-orchestrator"]

If no specialists are needed, respond with: []
Do not include core agents (they are always active).`;

  try {
    const response = await fetch('https://api.anthropic.com/v1/messages', {
      method: 'POST',
      headers: {
        'Content-Type': 'application/json',
        'x-api-key': apiKey,
        'anthropic-version': '2023-06-01'
      },
      body: JSON.stringify({
        model: 'claude-3-haiku-20240307',
        max_tokens: 200,
        messages: [{
          role: 'user',
          content: prompt
        }]
      })
    });

    if (!response.ok) {
      const error = await response.text();
      console.error(`${colors.yellow}⚠ Claude API error: ${error}${colors.reset}`);
      return null;
    }

    const data = await response.json();
    const content = data.content[0].text.trim();

    // Parse JSON response
    const agentIds = JSON.parse(content);
    return agentIds;
  } catch (error) {
    console.error(`${colors.yellow}⚠ Claude API failed: ${error.message}${colors.reset}`);
    return null;
  }
}

/**
 * Fallback: keyword-based detection (existing behavior)
 */
function keywordBasedDetection(userRequest) {
  console.log(`${colors.yellow}ℹ Using keyword-based detection (fallback)${colors.reset}`);

  try {
    const result = execSync(`node bin/detect-agents.js "${userRequest}" --json`, {
      encoding: 'utf-8',
      cwd: process.cwd()
    });

    const parsed = JSON.parse(result);
    return parsed.specialists || [];
  } catch (error) {
    console.error(`${colors.red}✗ Fallback detection failed: ${error.message}${colors.reset}`);
    return [];
  }
}

/**
 * Load agent descriptions for LLM context
 */
function loadAgentDescriptions() {
  const agentsPath = path.join(process.cwd(), 'content/.morph/config/agents.json');

  if (!fs.existsSync(agentsPath)) {
    throw new Error('agents.json not found');
  }

  const agents = JSON.parse(fs.readFileSync(agentsPath, 'utf-8'));
  const specialists = agents.agents.specialists || [];

  return specialists.map(agent =>
    `- ${agent.id}: ${agent.description}`
  ).join('\n');
}

/**
 * Print detection results
 */
function printResults(agentIds, method, userRequest) {
  console.log(`\n${colors.cyan}╔════════════════════════════════════════════════╗${colors.reset}`);
  console.log(`${colors.cyan}║     MORPH-SPEC SEMANTIC AGENT DETECTION        ║${colors.reset}`);
  console.log(`${colors.cyan}╚════════════════════════════════════════════════╝${colors.reset}\n`);

  console.log(`${colors.gray}Request:${colors.reset} "${userRequest}"`);
  console.log(`${colors.gray}Method:${colors.reset} ${method}`);
  console.log(`${colors.gray}Agents Detected:${colors.reset} ${agentIds.length}`);

  if (agentIds.length > 0) {
    console.log('');
    agentIds.forEach(id => {
      console.log(`  ${colors.green}✓${colors.reset} ${id}`);
    });
  } else {
    console.log(`\n  ${colors.gray}(No specialist agents needed)${colors.reset}`);
  }

  console.log('');
}

/**
 * Print help
 */
function printHelp() {
  console.log(`
${colors.cyan}MORPH-SPEC Semantic Agent Detection${colors.reset}

Uses LLM analysis to detect which agents should be activated.
More accurate than keyword matching - understands context.

${colors.green}Setup:${colors.reset}
  export ANTHROPIC_API_KEY=sk-ant-...

${colors.green}Usage:${colors.reset}
  node bin/semantic-detect-agents.js "user request here"

${colors.green}Examples:${colors.reset}
  # Detects UI/UX Designer (implicit need)
  node bin/semantic-detect-agents.js "sistema que mostra dados ao usuário"

  # Detects Hangfire Orchestrator
  node bin/semantic-detect-agents.js "processar arquivos todo dia às 3h"

  # Detects AI System Architect
  node bin/semantic-detect-agents.js "pipeline de RAG com chunking"

${colors.green}Fallback:${colors.reset}
  If ANTHROPIC_API_KEY is not set, falls back to keyword-based detection.

${colors.green}Benefits:${colors.reset}
  ✓ Understands context ("show data to users" → UI)
  ✓ Works in any language (not just keywords)
  ✓ Eliminates false positives/negatives
  ✓ Detects implicit needs

${colors.green}Output:${colors.reset}
  Prints detected agent IDs, one per line, for use in scripts.
  `);
}

/**
 * Main function
 */
async function main() {
  const args = process.argv.slice(2);

  if (args.includes('--help') || args.includes('-h') || args.length === 0) {
    printHelp();
    process.exit(args.length === 0 ? 1 : 0);
  }

  const userRequest = args.join(' ');
  const hasApiKey = !!process.env.ANTHROPIC_API_KEY;

  let agentIds;
  let method;

  if (hasApiKey) {
    method = `${colors.green}LLM-based (Claude Haiku)${colors.reset}`;
    const agentDescriptions = loadAgentDescriptions();
    agentIds = await callClaudeAPI(userRequest, agentDescriptions);

    if (!agentIds) {
      // API failed, fall back
      method = `${colors.yellow}Keyword-based (API fallback)${colors.reset}`;
      agentIds = keywordBasedDetection(userRequest);
    }
  } else {
    method = `${colors.yellow}Keyword-based (no API key)${colors.reset}`;
    agentIds = keywordBasedDetection(userRequest);
  }

  printResults(agentIds, method, userRequest);

  // Output for scripting (one ID per line)
  if (args.includes('--quiet') || args.includes('-q')) {
    console.clear();
    agentIds.forEach(id => console.log(id));
  }
}

main().catch(error => {
  console.error(`${colors.red}✗ Error: ${error.message}${colors.reset}`);
  process.exit(1);
});
