import fs from 'fs';
import path from 'path';
import crypto from 'crypto';
import { execSync } from 'child_process';
import { getTemplateDir, getAssetsDir } from '../utils/config.js';
function getDefaultTemplate(file) {
    if (file === 'company.md') {
        return `<!-- NOT CONFIGURED -->
# Company Profile

## Company
- **Name:**
- **Website:**
- **Sector:**
- **Description:**

## Target Audience
- **Primary:**
- **Secondary:**

## Tone of Voice
- **Style:**
- **Keywords:**

## Social Media
- **Instagram:**
- **LinkedIn:**
- **Twitter:**
- **YouTube:**

## Products/Services
-
`;
    }
    if (file === 'preferences.md') {
        return `# ExpxAgents Preferences

- **User Name:**
- **Language:** Portugues (Brasil)
- **IDE:** claude-code
- **Date Format:** DD/MM/YYYY
`;
    }
    if (file === 'memories.md') {
        return `# Squad Memories

> Updated automatically after each pipeline execution.
> Contains learnings, user preferences, and decisions from past runs.

## Execution History

(No runs yet)

## User Preferences

(No preferences recorded yet)

## Key Learnings

(No learnings recorded yet)
`;
    }
    return '';
}
/**
 * Recursively copy a directory, skipping .DS_Store files.
 * Returns stats about how many files were copied and how many actually changed.
 */
function copyDirRecursive(src, dest, stats = { total: 0, changed: 0 }) {
    if (!fs.existsSync(src))
        return stats;
    fs.mkdirSync(dest, { recursive: true });
    for (const entry of fs.readdirSync(src, { withFileTypes: true })) {
        if (entry.name === '.DS_Store')
            continue;
        const srcPath = path.join(src, entry.name);
        const destPath = path.join(dest, entry.name);
        if (entry.isDirectory()) {
            copyDirRecursive(srcPath, destPath, stats);
        }
        else {
            stats.total++;
            const srcContent = fs.readFileSync(srcPath);
            const destExists = fs.existsSync(destPath);
            if (!destExists || !srcContent.equals(fs.readFileSync(destPath))) {
                fs.copyFileSync(srcPath, destPath);
                stats.changed++;
            }
        }
    }
    return stats;
}
const SKILL_MD = `---
name: expxagents
description: "ExpxAgents \u2014 Multi-agent orchestration platform. Create and run AI squads with 93 specialized agents across 16 sectors."
---

# ExpxAgents \u2014 Multi-Agent Orchestration

You are now operating as the ExpxAgents system. Your primary role is to help users create, manage, and run AI agent squads.

## Initialization

On activation, perform these steps IN ORDER:

1. Read the company context: \`_expxagents/_memory/company.md\`
2. Read preferences: \`_expxagents/_memory/preferences.md\`
3. If company.md contains \`<!-- NOT CONFIGURED -->\` \u2192 trigger ONBOARDING
4. Otherwise \u2192 display MAIN MENU

## Onboarding Flow (first time only)

If company.md is not configured:

1. Welcome the user to ExpxAgents
2. Ask their name and preferred language
3. Ask company name, website URL, sector, description
4. If URL provided, use WebFetch + WebSearch to research the company
5. Present findings for confirmation
6. Save to \`_expxagents/_memory/company.md\` and \`_expxagents/_memory/preferences.md\`
7. Show main menu

## Main Menu

Present using AskUserQuestion with 2-4 options:

**Primary menu:**
- **Create a new squad** \u2014 Describe what you need and I'll design a squad
- **Run a squad** \u2014 Execute an existing squad's pipeline
- **My squads** \u2014 List, edit, or delete squads
- **More options** \u2014 Skills, company profile, settings

**More options submenu:**
- **Skills** \u2014 Browse, install, or create skills
- **Company profile** \u2014 View or edit company info
- **Settings** \u2014 Language, IDE, preferences

## Command Routing

| Command | Action |
|---------|--------|
| \`/expxagents\` | Show main menu |
| \`/expxagents create [description]\` | Load Solution Architect \u2192 Design squad |
| \`/expxagents run <name>\` | Load Release Manager \u2192 Execute pipeline |
| \`/expxagents list\` | List squads from \`squads/\` directory |
| \`/expxagents edit <name>\` | Load Solution Architect \u2192 Edit mode |
| \`/expxagents skills\` | Load Skills Engine \u2192 Show menu |
| \`/expxagents install <name>\` | Install skill from catalog |
| \`/expxagents uninstall <name>\` | Remove installed skill |
| \`/expxagents delete <name>\` | Confirm and delete squad |
| \`/expxagents sync-templates [squad]\` | Sync Pencil .pen visual templates to .md specs |
| \`/expxagents dashboard\` | Run CLI to start server + open dashboard |
| \`/expxagents virtual-office\` | Run CLI to start server + open virtual office in browser |
| \`/expxagents help\` | Show help text |

## Virtual Office / Dashboard

When the user requests \`/expxagents virtual-office\` or \`/expxagents dashboard\`:

1. **ALWAYS run the CLI command** — do NOT generate HTML files or static pages
2. Execute: \`npx expxagents virtual-office\` via the Bash tool
3. This starts the Fastify server with the Pixi.js animated office dashboard and opens the browser
4. The server runs on port 3001 (or PORT env var) and serves the React SPA with WebSocket support
5. NEVER create static HTML files for the virtual office — the office is a full server-side application

## Loading Agents

When a core agent needs to be activated:

1. **Solution Architect:** Read \`_expxagents/core/solution-architect.agent.md\`
2. **Release Manager:** Read \`_expxagents/core/runner.pipeline.md\`
3. **Skills Engine:** Read \`_expxagents/core/skills.engine.md\`
4. **Insight Hunter:** Read \`_expxagents/core/prompts/insight-hunter.prompt.md\`

Adopt the agent's persona and follow its instructions completely.

## Agent Catalog

The full agent catalog is at \`agents/_catalog.yaml\`. Read it to see all available agents organized by sector:

- **Core (4):** solution-architect, release-manager, platform-engineer, insight-hunter
- **Development (18):** tech-lead, qa-engineer, devops-engineer, code-reviewer, backend-developer, frontend-developer, ux-design-expert, product-manager, ux-designer, business-analyst, scrum-master, dba, security-analyst, tech-writer, desktop-developer, ios-developer, android-developer, cross-platform-mobile
- **Implantation (5):** deployment-manager, environment-specialist, migration-specialist, integration-specialist, go-live-coordinator
- **Support (5):** l1-support, l2-support, l3-support, knowledge-base-manager, sla-monitor
- **Training (4):** training-designer, onboarding-coach, assessment-creator, workshop-facilitator
- **Finance (4):** billing-analyst, financial-controller, accounts-manager, budget-planner
- **HR (6):** recruiter, interview-coordinator, hr-onboarding, performance-analyst, benefits-manager, people-culture
- **Customer Success (5):** csm, churn-prevention, expansion-manager, nps-analyst, renewal-manager
- **Administrative (4):** procurement-specialist, document-controller, office-manager, process-documentation-officer
- **Marketing (8):** content-creator, seo-specialist, social-media-manager, email-marketing, paid-ads-manager, marketing-analyst, brand-guardian, landing-page-builder
- **Commercial (5):** sdr, account-executive, proposal-writer, crm-manager, pricing-strategist
- **R&D (5):** market-researcher, innovation-scout, prototype-builder, benchmark-analyst, product-analyst
- **Board (6):** strategic-advisor, okr-manager, board-report-writer, risk-analyst, governance-officer, business-intelligence
- **Accounting (6):** accountant, tax-compliance, fiscal-analyst, payroll-specialist, audit-analyst, financial-reporting
- **Legal (4):** contract-manager, legal-counsel, ip-specialist, labor-attorney
- **Compliance (4):** compliance-officer, data-privacy-specialist, regulatory-monitor, internal-auditor

When creating squads, use these agent templates as base for squad agents.

## Best Practices

Best-practice guides are at \`_expxagents/core/best-practices/\`. Read the catalog at \`_expxagents/core/best-practices/_catalog.yaml\` for available formats (landing-page, blog-post, email-sales, etc.).

## Running a Squad

1. Read \`squads/<name>/squad.yaml\`
2. Read \`squads/<name>/squad-party.csv\` (if exists)
3. Load company context from \`_expxagents/_memory/company.md\`
4. Load squad memory from \`squads/<name>/_memory/memories.md\`
5. Read runner instructions from \`_expxagents/core/runner.pipeline.md\`
6. Execute pipeline step by step

## Language

- Read preferences for user's language
- All output in user's language
- File names and code in English

## Help Text

\`\`\`
ExpxAgents \u2014 Multi-Agent Orchestration

SQUADS
  /expxagents create       Design a new squad
  /expxagents run <name>   Execute a squad pipeline
  /expxagents list         List all squads
  /expxagents edit <name>  Modify a squad
  /expxagents delete <name> Delete a squad

TEMPLATES
  /expxagents sync-templates  Sync Pencil visual templates

SKILLS
  /expxagents skills       Browse skills
  /expxagents install      Install a skill
  /expxagents uninstall    Remove a skill

SETTINGS
  /expxagents dashboard       Open virtual office
  /expxagents virtual-office  Open virtual office in browser
  /expxagents help            Show this help
\`\`\`

## Critical Rules

- NEVER use the names "Leticia" or "Rafael" for agents, squads, personas, or any generated content — these names are permanently banned
- NEVER skip onboarding if company.md is not configured
- ALWAYS load company context before squad operations
- ALWAYS present checkpoints to user \u2014 never skip them
- ALWAYS save outputs and update squad memories
- When switching agent personas, indicate who is speaking
- AskUserQuestion must always have 2-4 options
`;
export async function initCommand(options = {}) {
    const cwd = process.cwd();
    const update = options.update ?? false;
    if (update) {
        console.log('Updating ExpxAgents assets...\n');
    }
    else {
        console.log('Initializing ExpxAgents project...\n');
    }
    // Create squads directory
    const squadsDir = path.join(cwd, 'squads');
    if (!fs.existsSync(squadsDir)) {
        fs.mkdirSync(squadsDir, { recursive: true });
        console.log('  Created squads/');
    }
    else {
        console.log('  squads/ already exists');
    }
    // Create _expxagents/_memory/ directory
    const memoryDir = path.join(cwd, '_expxagents', '_memory');
    if (!fs.existsSync(memoryDir)) {
        fs.mkdirSync(memoryDir, { recursive: true });
        console.log('  Created _expxagents/_memory/');
    }
    else {
        console.log('  _expxagents/_memory/ already exists');
    }
    // Copy template files from package assets
    const templateDir = getTemplateDir();
    const templateMemoryDir = path.join(templateDir, '_expxagents', '_memory');
    const memoryFiles = ['company.md', 'preferences.md'];
    for (const file of memoryFiles) {
        const destPath = path.join(memoryDir, file);
        if (!fs.existsSync(destPath)) {
            const templateSrc = path.join(templateMemoryDir, file);
            if (fs.existsSync(templateSrc)) {
                fs.copyFileSync(templateSrc, destPath);
            }
            else {
                fs.writeFileSync(destPath, getDefaultTemplate(file), 'utf-8');
            }
            console.log(`  Created _expxagents/_memory/${file}`);
        }
        else {
            console.log(`  _expxagents/_memory/${file} already exists`);
        }
    }
    // Copy core agents from package assets
    const assetsDir = getAssetsDir();
    const coreSrc = path.join(assetsDir, 'core');
    const coreDest = path.join(cwd, '_expxagents', 'core');
    if (update || !fs.existsSync(coreDest)) {
        const coreStats = copyDirRecursive(coreSrc, coreDest);
        if (update) {
            console.log(`  Updated _expxagents/core/ — ${coreStats.changed}/${coreStats.total} files changed`);
        }
        else {
            console.log(`  Copied _expxagents/core/ (${coreStats.total} files)`);
        }
    }
    else {
        console.log('  _expxagents/core/ already exists (use --update to refresh)');
    }
    // Copy agent catalog from package assets
    const agentsSrc = path.join(assetsDir, 'agents');
    const agentsDest = path.join(cwd, 'agents');
    if (update || !fs.existsSync(agentsDest)) {
        const agentStats = copyDirRecursive(agentsSrc, agentsDest);
        if (update) {
            console.log(`  Updated agents/ — ${agentStats.changed}/${agentStats.total} files changed`);
        }
        else {
            console.log(`  Copied agents/ (${agentStats.total} files)`);
        }
    }
    else {
        console.log('  agents/ already exists (use --update to refresh)');
    }
    // Copy MCP catalog
    const mcpsSrc = path.join(assetsDir, 'mcps');
    if (fs.existsSync(mcpsSrc)) {
        const mcpsResult = copyDirRecursive(mcpsSrc, path.resolve('mcps'));
        console.log(`  📡 MCP catalog: ${mcpsResult.changed}/${mcpsResult.total} files`);
    }
    // Create/update Claude Code skill (.claude/skills/expxagents/SKILL.md)
    const skillDir = path.join(cwd, '.claude', 'skills', 'expxagents');
    const skillPath = path.join(skillDir, 'SKILL.md');
    if (update || !fs.existsSync(skillPath)) {
        fs.mkdirSync(skillDir, { recursive: true });
        fs.writeFileSync(skillPath, SKILL_MD, 'utf-8');
        console.log(update
            ? '  Updated .claude/skills/expxagents/SKILL.md'
            : '  Created .claude/skills/expxagents/SKILL.md (enables /expxagents command)');
    }
    else {
        console.log('  .claude/skills/expxagents/SKILL.md already exists (use --update to refresh)');
    }
    // Create squads/_memory/ subdirectory
    const squadsMemoryDir = path.join(cwd, 'squads', '_memory');
    if (!fs.existsSync(squadsMemoryDir)) {
        fs.mkdirSync(squadsMemoryDir, { recursive: true });
        console.log('  Created squads/_memory/');
    }
    else {
        console.log('  squads/_memory/ already exists');
    }
    const memoriesTemplateSrc = path.join(templateDir, 'squads', '_memory', 'memories.md');
    const memoriesTemplateDest = path.join(squadsMemoryDir, 'memories.md');
    if (!fs.existsSync(memoriesTemplateDest)) {
        if (fs.existsSync(memoriesTemplateSrc)) {
            fs.copyFileSync(memoriesTemplateSrc, memoriesTemplateDest);
        }
        else {
            fs.writeFileSync(memoriesTemplateDest, getDefaultTemplate('memories.md'), 'utf-8');
        }
        console.log('  Created squads/_memory/memories.md');
    }
    // Create .env if it doesn't exist
    const envPath = path.join(cwd, '.env');
    if (!fs.existsSync(envPath)) {
        const jwtSecret = crypto.randomBytes(32).toString('hex');
        const envContent = `JWT_SECRET=${jwtSecret}
PORT=3001
CORS_ORIGIN=http://localhost:3001
NODE_ENV=development
BRIDGE_TIMEOUT_MS=300000
`;
        fs.writeFileSync(envPath, envContent, 'utf-8');
        console.log('  Created .env with generated JWT_SECRET');
    }
    else {
        console.log('  .env already exists');
    }
    // Create .gitignore additions
    const gitignorePath = path.join(cwd, '.gitignore');
    const gitignoreEntries = [
        'node_modules/',
        '.env',
        '.mcp.json',
        '*.tmp',
        'squads/*/state.json',
        'squads/*/state.json.tmp',
        'squads/*/output/',
    ];
    if (fs.existsSync(gitignorePath)) {
        const existing = fs.readFileSync(gitignorePath, 'utf-8');
        const toAdd = gitignoreEntries.filter(e => !existing.includes(e));
        if (toAdd.length > 0) {
            fs.appendFileSync(gitignorePath, '\n# ExpxAgents\n' + toAdd.join('\n') + '\n');
            console.log('  Updated .gitignore');
        }
    }
    else {
        fs.writeFileSync(gitignorePath, gitignoreEntries.join('\n') + '\n', 'utf-8');
        console.log('  Created .gitignore');
    }
    // MCP Setup
    const mcpsDir = path.resolve('mcps');
    if (fs.existsSync(mcpsDir)) {
        const { listAllMcpIds, loadMcpDefinition } = await import('../mcp/catalog.js');
        const { detectMcp, detectExtension, resolvePlatformBinary } = await import('../mcp/detect.js');
        const { writeMcpConfig } = await import('../mcp/setup.js');
        const ids = listAllMcpIds(mcpsDir);
        const results = ids.map(id => {
            const def = loadMcpDefinition(mcpsDir, id);
            return def ? { def, detection: detectMcp(def) } : null;
        }).filter((r) => r !== null);
        console.log('\n🔍 Detecting available MCP integrations...\n');
        for (const { def, detection } of results) {
            const icon = detection.status === 'detected' ? '✅' : detection.status === 'available' ? '⬜' : '⛔';
            console.log(`  ${icon} ${def.id.padEnd(14)} — ${detection.detail}`);
        }
        // Auto-configure extension-based MCPs (like Pencil) that need no auth
        for (const { def, detection } of results) {
            if (detection.status === 'detected' && def.detection.method === 'extension' && def.auth.length === 0) {
                if (def.detection.extension) {
                    const ext = detectExtension(def.detection.extension.prefix);
                    if (ext) {
                        const binary = resolvePlatformBinary();
                        const resolvedCmd = path.join(ext.extensionPath, def.detection.extension.binary_dir, binary);
                        writeMcpConfig(process.cwd(), def, {}, resolvedCmd);
                        console.log(`  → ${def.name} auto-configured`);
                    }
                }
            }
        }
        console.log('\n  Run: expxagents mcp setup <id> to configure additional MCPs\n');
    }
    // Install Python dependencies
    const pythonDeps = ['aiohttp', 'aiofiles', 'python-dotenv'];
    console.log(`\n  Installing Python dependencies (${pythonDeps.join(', ')})...`);
    try {
        execSync(`pip3 install ${pythonDeps.join(' ')}`, { stdio: 'inherit' });
        console.log('  Python dependencies installed.');
    }
    catch {
        try {
            execSync(`pip install ${pythonDeps.join(' ')}`, { stdio: 'inherit' });
            console.log('  Python dependencies installed.');
        }
        catch {
            console.warn('  Warning: Could not install Python dependencies. Make sure pip3/pip is available and run:');
            console.warn(`    pip3 install ${pythonDeps.join(' ')}`);
        }
    }
    if (update) {
        console.log('\nUpdate complete! Assets refreshed to latest version.');
    }
    else {
        console.log('\nProject initialized! Run `expxagents onboarding` to configure your profile.');
        console.log('Use /expxagents in Claude Code to get started.');
    }
}
