import chalk from 'chalk';
import Table from 'cli-table3';
import fs from 'node:fs/promises';
import path from 'node:path';
import { listAgents, findAgent } from '../utils/agents.js';
import { getAgentDir } from '../utils/paths.js';

function registerAgentList(agentCmd) {
  agentCmd
    .command('list')
    .description('List all available agents')
    .option('--json', 'Output as JSON')
    .action(async (opts) => {
      try {
        const agents = await listAgents();

        if (agents.length === 0) {
          if (opts.json) {
            console.log('[]');
          } else {
            console.log(chalk.yellow('No agents found.'));
          }
          return;
        }

        if (opts.json) {
          console.log(JSON.stringify(agents, null, 2));
          return;
        }

        const table = new Table({
          head: [
            chalk.cyan('Agent ID'),
            chalk.cyan('Version'),
            chalk.cyan('Description'),
          ],
          style: { head: [], border: [] },
        });

        for (const a of agents) {
          table.push([a.agent_id, a.version, a.description]);
        }

        console.log();
        console.log(table.toString());
        console.log();
        console.log(chalk.gray(`  Total: ${agents.length} agents`));
        console.log();
      } catch (err) {
        console.error(chalk.red(`Failed to list agents: ${err.message}`));
        process.exit(1);
      }
    });
}

function registerAgentDownload(agentCmd) {
  agentCmd
    .command('download')
    .description('Download an agent to a local directory')
    .argument('<agent-id>', 'Agent ID to download')
    .option('--path <dir>', 'Target directory (default: current directory)')
    .action(async (agentId, opts) => {
      try {
        const meta = await findAgent(agentId);
        if (!meta) {
          console.error(chalk.red(`\n  Agent "${agentId}" not found.\n`));
          console.error(chalk.gray('  Run "sophhub agent list" to see all available agents.'));
          process.exit(1);
        }

        const outputDir = path.resolve(opts.path || '.');
        await fs.mkdir(outputDir, { recursive: true });

        const destDir = path.join(outputDir, agentId);

        try {
          await fs.access(destDir);
          await fs.rm(destDir, { recursive: true, force: true });
        } catch {
          // dest does not exist
        }

        const srcDir = getAgentDir(agentId);
        try {
          await fs.access(srcDir);
        } catch {
          throw new Error(`Agent source directory not found in package: ${srcDir}`);
        }

        await fs.cp(srcDir, destDir, { recursive: true });

        console.log();
        console.log(
          chalk.green(`  ✓ ${meta.agent_id}`) +
            chalk.gray(` (${meta.version}) → ${destDir}`)
        );
        console.log();
      } catch (err) {
        console.error(chalk.red(`\n  Failed to download agent: ${err.message}\n`));
        process.exit(1);
      }
    });
}

export function registerAgentCommand(program) {
  const agentCmd = program
    .command('agent')
    .description('Manage AI Agents (list / download)');

  registerAgentList(agentCmd);
  registerAgentDownload(agentCmd);
}
