import { Command } from 'commander';
import chalk from 'chalk';
import { join } from 'path';
import { getFeature } from '../../core/state/state-manager.js';
import { orchestrateTeam } from '../../lib/orchestration/team-orchestrator.js';
import { spawnParallel } from '../../lib/execution/parallel-executor.js';
import { renderHOP } from '../../lib/hops/hop-composer.js';

/**
 * Spawn Team Command - Generate agent team configurations
 *
 * Reads active agents from feature state and generates ready-to-use
 * Task tool configurations for spawning agent teams.
 */

const program = new Command();

/**
 * Spawn team action function
 */
/**
 * Spawn team in parallel mode
 * --parallel backend,frontend,infra
 */
export async function spawnTeamParallelCommand(featureName, squads, options = {}) {
  const squadList = squads.split(',').map(s => s.trim());
  const maxConcurrent = parseInt(options.maxConcurrent || '3', 10);

  console.log(chalk.cyan(`\n  Spawning ${squadList.length} parallel squads for: ${featureName}\n`));

  const threadConfigs = squadList.map(squad => ({
    agent: squad,
    mission: `Implement ${squad} domain for ${featureName}`,
    meta: { squad }
  }));

  try {
    const threads = await spawnParallel({ feature: featureName, threadConfigs, maxConcurrent });
    console.log(chalk.green(`  ✓ ${threads.length} threads spawned in parallel`));
    for (const t of threads) {
      console.log(`    ${chalk.gray(t.id.substring(0, 8))} — ${t.agent} (${t.status})`);
    }
    console.log(`\n  Monitor with: morph-spec threads wait-all ${featureName}\n`);
  } catch (err) {
    console.error(chalk.red(`  Error: ${err.message}`));
    process.exit(1);
  }
}

export async function spawnTeamCommand(featureName, options = {}) {
    try {
      // Get feature state
      const feature = getFeature(featureName);
      if (!feature) {
        console.error(chalk.red(`\n❌ Feature not found: ${featureName}\n`));
        process.exit(1);
      }

      if (!feature.activeAgents || feature.activeAgents.length === 0) {
        console.error(chalk.yellow(`\n⚠️  No active agents found for feature: ${featureName}`));
        console.log(chalk.gray('Run "morph-spec detect-agents" first to identify agents.\n'));
        process.exit(1);
      }

      // Determine if multi-domain
      const domains = new Set();
      feature.activeAgents.forEach(agentId => {
        if (agentId.includes('dotnet') || agentId.includes('ef') || agentId.includes('api')) {
          domains.add('backend');
        }
        if (agentId.includes('blazor') || agentId.includes('nextjs') || agentId.includes('ui')) {
          domains.add('frontend');
        }
        if (agentId.includes('azure') || agentId.includes('bicep') || agentId.includes('container')) {
          domains.add('infrastructure');
        }
      });

      const multiDomain = domains.size > 1;

      // Orchestrate team
      const teamConfig = orchestrateTeam({
        activeAgents: feature.activeAgents,
        complexity: options.complexity,
        estimatedFiles: parseInt(options.estimatedFiles, 10),
        multiDomain
      });

      if (options.json) {
        // Output as JSON for programmatic use
        console.log(JSON.stringify(teamConfig, null, 2));
        return;
      }

      // Pretty output for human reading
      console.log(chalk.bold(`\n🤖 Agent Team Configuration for: ${featureName}`));
      console.log('━'.repeat(60));

      console.log(chalk.cyan(`\nShould Spawn Agents: ${teamConfig.useAgentTeams ? chalk.green('YES') : chalk.yellow('NO')}`));
      console.log(chalk.gray(`Reason: ${teamConfig.useAgentTeams ? 'Meets spawn threshold' : 'Below threshold - implement directly'}`));

      if (!teamConfig.useAgentTeams) {
        console.log(chalk.yellow('\n⚠️  Team spawning not recommended for this feature.'));
        console.log(chalk.gray('Implement directly in main session.\n'));
        return;
      }

      console.log(chalk.cyan(`\nDisplay Mode: ${teamConfig.displayMode}`));
      console.log(chalk.cyan(`Total Teammates: ${teamConfig.teamHierarchy.totalTeammates}`));

      // Show team hierarchy
      console.log(chalk.bold('\nTeam Hierarchy:'));
      console.log(chalk.green(`  Team Lead: ${teamConfig.teamHierarchy.teamLead}`));

      if (teamConfig.teamHierarchy.squads && teamConfig.teamHierarchy.squads.length > 0) {
        console.log(chalk.cyan('\n  Squad Leaders:'));
        teamConfig.teamHierarchy.squads.forEach(squad => {
          console.log(chalk.cyan(`    • ${squad}`));
        });
      }

      if (teamConfig.teamHierarchy.validators && teamConfig.teamHierarchy.validators.length > 0) {
        console.log(chalk.gray('\n  Validators (run in hooks):'));
        teamConfig.teamHierarchy.validators.forEach(validator => {
          console.log(chalk.gray(`    • ${validator}`));
        });
      }

      // Show Task tool usage (with HOP rendering)
      console.log(chalk.bold('\n📝 Task Tool Usage:'));
      console.log(chalk.gray('\nUse the following pattern to spawn the team:\n'));

      // Try to render backend squad HOP if applicable
      let hopPrompt = null;
      const hasBackend = teamConfig.teammates.some(t => t.id.includes('dotnet') || t.id.includes('api') || t.id.includes('ef'));
      if (hasBackend && options.useHop !== false) {
        try {
          const frameworkRoot = join(process.cwd(), 'framework');
          const domainLeaders = teamConfig.teammates
            .filter(t => t.tier === 2)
            .map(t => `- ${t.id}: ${t.role}`)
            .join('\n');
          hopPrompt = renderHOP('hop-backend-squad', {
            AGENT_ID: teamConfig.teamHierarchy.teamLead,
            MISSION: `Implement ${featureName}`,
            SPEC_SUMMARY: `Feature: ${featureName}. See spec.md for full details.`,
            ADDITIONAL_LEADERS: domainLeaders,
            TASKS: teamConfig.teammates.filter(t => t.tier === 3).map((t, i) => `- T${String(i+1).padStart(3,'0')}: ${t.role}`).join('\n'),
            DELIVERABLES: 'See spec.md deliverables section',
            CONSTRAINTS: 'Follow all architecture and security standards',
            FEATURE_NAME: featureName
          }, { frameworkRoot });
        } catch {
          hopPrompt = null;
        }
      }

      if (hopPrompt) {
        console.log(chalk.cyan('HOP-rendered prompt (backend squad):'));
        console.log(chalk.gray('─'.repeat(60)));
        console.log(chalk.white(hopPrompt.substring(0, 800) + (hopPrompt.length > 800 ? '\n...[truncated]' : '')));
        console.log(chalk.gray('─'.repeat(60)));
        console.log(chalk.dim('\nFull HOP: morph-spec hop render hop-backend-squad output.md \'{...}\''));
      } else {
        console.log(chalk.cyan('```typescript'));
        console.log(chalk.white(`{
  subagent_type: "general-purpose",
  description: "Implement ${featureName}",
  prompt: \`You are the Team Lead (${teamConfig.teamHierarchy.teamLead})...

Your Mission: Implement ${featureName}

Your Domain Leaders:
${teamConfig.teammates
  .filter(t => t.tier === 2)
  .map(t => `- ${t.id}: ${t.role}`)
  .join('\n')}

Your Specialists:
${teamConfig.teammates
  .filter(t => t.tier === 3)
  .map(t => `- ${t.id}: ${t.role}`)
  .join('\n')}

Standards to follow: [coding.md, architecture.md]

Deliverables: [list specific outputs]
\`
}`));
        console.log(chalk.cyan('```\n'));
      }

      // Show individual teammates
      console.log(chalk.bold('Individual Teammates:'));
      teamConfig.teammates.forEach(teammate => {
        console.log(chalk.cyan(`\n  ${teammate.icon} ${teammate.id} (Tier ${teammate.tier})`));
        console.log(chalk.gray(`     Role: ${teammate.role}`));

        if (teammate.spawnPrompt && teammate.spawnPrompt.length < 200) {
          console.log(chalk.gray(`     Prompt: ${teammate.spawnPrompt.substring(0, 100)}...`));
        }
      });

      console.log('\n' + '━'.repeat(60));
      console.log(chalk.green('\n✅ Team configuration generated successfully\n'));

    } catch (error) {
      console.error(chalk.red(`\n❌ Error generating team configuration: ${error.message}\n`));
      if (error.stack) {
        console.error(chalk.gray(error.stack));
      }
      process.exit(1);
    }
  }

/**
 * Commander program command
 */
program
  .name('spawn-team')
  .description('Generate agent team configuration for Task tool spawning')
  .argument('<feature>', 'Feature name')
  .option('--json', 'Output as JSON')
  .option('--complexity <level>', 'Override complexity level (low/medium/high/critical)', 'high')
  .option('--estimated-files <count>', 'Override estimated file count', '20')
  .action(spawnTeamCommand);

// Only parse if run directly (not imported as module)
if (import.meta.url === `file://${process.argv[1]}`) {
  if (process.argv.length > 2) {
    program.parse(process.argv);
  } else {
    program.help();
  }
}

export default program;
