import { Command } from 'commander';
import fs from 'fs';
import path from 'path';
import yaml from 'js-yaml';
import { loadMcpDefinition, listAllMcpIds } from '../mcp/catalog.js';
import { detectMcp, detectExtension, resolvePlatformBinary } from '../mcp/detect.js';
import { writeMcpConfig, removeMcpConfig } from '../mcp/setup.js';
import { getConfiguredMcpIds } from '../mcp/validate.js';
import { getAssetsDir } from '../utils/config.js';
function getMcpsDir() {
    const local = path.resolve('mcps');
    if (fs.existsSync(local))
        return local;
    return path.join(getAssetsDir(), 'mcps');
}
export function mcpCommand() {
    const mcp = new Command('mcp')
        .description('Manage MCP integrations');
    mcp
        .command('list')
        .description('List all MCPs: configured, available, unavailable')
        .action(() => {
        const mcpsDir = getMcpsDir();
        const ids = listAllMcpIds(mcpsDir);
        const configured = getConfiguredMcpIds(process.cwd());
        const results = [];
        for (const id of ids) {
            const def = loadMcpDefinition(mcpsDir, id);
            if (def)
                results.push(detectMcp(def));
        }
        console.log('\nMCP Integrations:\n');
        const configuredResults = results.filter(r => configured.includes(r.id));
        if (configuredResults.length > 0) {
            console.log('  CONFIGURED');
            for (const r of configuredResults) {
                console.log(`  \u2705 ${r.id.padEnd(14)} \u2014 ${r.detail}`);
            }
            console.log('');
        }
        const available = results.filter(r => !configured.includes(r.id) && r.status !== 'unavailable');
        if (available.length > 0) {
            console.log('  AVAILABLE');
            for (const r of available) {
                console.log(`  \u2b1c ${r.id.padEnd(14)} \u2014 ${r.detail}`);
            }
            console.log('');
        }
        const unavailable = results.filter(r => r.status === 'unavailable' && !configured.includes(r.id));
        if (unavailable.length > 0) {
            console.log('  UNAVAILABLE');
            for (const r of unavailable) {
                console.log(`  \u26d4 ${r.id.padEnd(14)} \u2014 ${r.detail}`);
            }
            console.log('');
        }
        console.log('Run: expxagents mcp setup <id> to configure\n');
    });
    mcp
        .command('setup <ids...>')
        .description('Configure one or more MCPs')
        .action(async (ids) => {
        const mcpsDir = getMcpsDir();
        const readline = await import('readline');
        const rl = readline.createInterface({ input: process.stdin, output: process.stdout });
        const ask = (q) => new Promise(r => rl.question(q, r));
        for (const id of ids) {
            const def = loadMcpDefinition(mcpsDir, id);
            if (!def) {
                console.log(`\u274c Unknown MCP: ${id}`);
                continue;
            }
            console.log(`\n\ud83d\udce6 Setting up ${def.name} MCP...\n`);
            let resolvedCommand;
            if (def.detection.method === 'extension' && def.detection.extension) {
                const ext = detectExtension(def.detection.extension.prefix);
                if (!ext) {
                    console.log(`\u274c ${def.name} VSCode extension not found`);
                    continue;
                }
                const binary = resolvePlatformBinary();
                resolvedCommand = path.join(ext.extensionPath, def.detection.extension.binary_dir, binary);
            }
            const authValues = {};
            for (const auth of def.auth) {
                console.log(`  ${auth.hint}`);
                const value = await ask(`? ${auth.label}: `);
                authValues[auth.key] = value.trim();
            }
            writeMcpConfig(process.cwd(), def, authValues, resolvedCommand);
            console.log(`\n\u2705 ${def.name} MCP configured\n`);
        }
        rl.close();
    });
    mcp
        .command('remove <id>')
        .description('Remove an MCP from .mcp.json and .env')
        .option('-f, --force', 'Skip squad dependency check')
        .action((id, options) => {
        const configured = getConfiguredMcpIds(process.cwd());
        if (!configured.includes(id)) {
            console.log(`\u274c MCP "${id}" is not configured`);
            return;
        }
        if (!options.force) {
            const squadsDir = path.resolve('squads');
            if (fs.existsSync(squadsDir)) {
                const dependentSquads = [];
                for (const entry of fs.readdirSync(squadsDir)) {
                    const yamlPath = path.join(squadsDir, entry, 'squad.yaml');
                    if (!fs.existsSync(yamlPath))
                        continue;
                    try {
                        const raw = yaml.load(fs.readFileSync(yamlPath, 'utf-8'));
                        const mcps = raw.squad?.mcps;
                        if (mcps?.includes(id))
                            dependentSquads.push(entry);
                    }
                    catch { /* skip */ }
                }
                if (dependentSquads.length > 0) {
                    console.log(`\u26a0\ufe0f  Squads that depend on "${id}": ${dependentSquads.join(', ')}`);
                    console.log(`   Use --force to remove anyway`);
                    return;
                }
            }
        }
        removeMcpConfig(process.cwd(), id);
        console.log(`\u2705 Removed MCP: ${id}`);
    });
    mcp
        .command('check [id]')
        .description('Validate configured MCP connections')
        .action((id) => {
        const configured = getConfiguredMcpIds(process.cwd());
        const toCheck = id ? [id] : configured;
        let issues = 0;
        console.log('\nChecking MCP connections...\n');
        for (const mcpId of toCheck) {
            if (!configured.includes(mcpId)) {
                console.log(`  \u274c ${mcpId.padEnd(14)} \u2014 Not configured`);
                issues++;
                continue;
            }
            console.log(`  \u2705 ${mcpId.padEnd(14)} \u2014 Configured`);
        }
        if (issues > 0) {
            console.log(`\n${issues} issue(s) found.\n`);
        }
        else {
            console.log(`\nAll MCPs OK.\n`);
        }
    });
    return mcp;
}
