#!/usr/bin/env node

const fs = require('fs');
const path = require('path');
const yaml = require('js-yaml');

// Colors for console output
const colors = {
  reset: '\x1b[0m',
  bright: '\x1b[1m',
  green: '\x1b[32m',
  red: '\x1b[31m',
  yellow: '\x1b[33m',
  blue: '\x1b[34m',
  cyan: '\x1b[36m'
};

function log(message, color = 'reset') {
  console.log(`${colors[color]}${message}${colors.reset}`);
}

function error(message) {
  console.error(`${colors.red}❌ Error: ${message}${colors.reset}`);
}

function success(message) {
  console.log(`${colors.green}✅ ${message}${colors.reset}`);
}

function info(message) {
  console.log(`${colors.blue}ℹ️  ${message}${colors.reset}`);
}

async function installExpansionPack(packName) {
  const expansionPackPath = path.join(__dirname, '..', 'expansion-packs', packName);
  const manifestPath = path.join(expansionPackPath, 'manifest.yml');

  // Check if expansion pack exists
  if (!fs.existsSync(expansionPackPath)) {
    error(`Expansion pack '${packName}' not found`);
    log('\nAvailable expansion packs:', 'cyan');
    const packsDir = path.join(__dirname, '..', 'expansion-packs');
    const packs = fs.readdirSync(packsDir)
      .filter(f => fs.statSync(path.join(packsDir, f)).isDirectory())
      .filter(f => f !== 'README.md');
    packs.forEach(pack => log(`  - ${pack}`, 'cyan'));
    process.exit(1);
  }

  // Load manifest
  if (!fs.existsSync(manifestPath)) {
    error(`Manifest file not found for expansion pack '${packName}'`);
    process.exit(1);
  }

  let manifest;
  try {
    const manifestContent = fs.readFileSync(manifestPath, 'utf8');
    manifest = yaml.load(manifestContent);
  } catch (e) {
    error(`Failed to parse manifest: ${e.message}`);
    process.exit(1);
  }

  log(`\n${colors.bright}Installing ${manifest.name} v${manifest.version}${colors.reset}`, 'bright');
  log(`${manifest.description}\n`, 'cyan');

  // Create directories if needed
  const projectRoot = path.join(__dirname, '..');
  const bmadCore = path.join(projectRoot, 'bmad-core');

  // Install files
  let installedCount = 0;
  let skippedCount = 0;

  for (const fileMapping of manifest.files) {
    const sourcePath = path.join(expansionPackPath, fileMapping.source);
    const destPath = path.join(projectRoot, fileMapping.destination);
    const destDir = path.dirname(destPath);

    // Create destination directory if it doesn't exist
    if (!fs.existsSync(destDir)) {
      fs.mkdirSync(destDir, { recursive: true });
      info(`Created directory: ${path.relative(projectRoot, destDir)}`);
    }

    // Check if file already exists
    if (fs.existsSync(destPath)) {
      const response = await promptUser(`File ${path.relative(projectRoot, destPath)} already exists. Overwrite? (y/N): `);
      if (response.toLowerCase() !== 'y') {
        info(`Skipped: ${fileMapping.source}`);
        skippedCount++;
        continue;
      }
    }

    // Copy file
    try {
      fs.copyFileSync(sourcePath, destPath);
      success(`Installed: ${fileMapping.source} → ${path.relative(projectRoot, destPath)}`);
      installedCount++;
    } catch (e) {
      error(`Failed to install ${fileMapping.source}: ${e.message}`);
    }
  }

  // Update team configurations
  if (manifest.team_updates && manifest.team_updates.length > 0) {
    log('\nUpdating team configurations...', 'yellow');
    
    for (const update of manifest.team_updates) {
      // Try new location first (agent-teams), then fallback to old location (agents)
      let teamPath = path.join(projectRoot, 'agent-teams', update.team);
      if (!fs.existsSync(teamPath)) {
        teamPath = path.join(projectRoot, 'agents', update.team);
      }
      
      if (fs.existsSync(teamPath)) {
        try {
          let teamConfig = yaml.load(fs.readFileSync(teamPath, 'utf8'));
          
          if (!teamConfig.agents) {
            teamConfig.agents = [];
          }
          
          if (!teamConfig.agents.includes(update.add_agent)) {
            teamConfig.agents.push(update.add_agent);
            fs.writeFileSync(teamPath, yaml.dump(teamConfig));
            success(`Updated ${update.team} with ${update.add_agent} agent`);
          } else {
            info(`${update.team} already includes ${update.add_agent} agent`);
          }
        } catch (e) {
          error(`Failed to update ${update.team}: ${e.message}`);
        }
      }
    }
  }

  // Show summary
  log(`\n${colors.bright}Installation Summary${colors.reset}`, 'bright');
  log(`Files installed: ${installedCount}`, 'green');
  if (skippedCount > 0) {
    log(`Files skipped: ${skippedCount}`, 'yellow');
  }

  // Show post-install message
  if (manifest.post_install_message) {
    log(`\n${colors.bright}Next Steps:${colors.reset}`, 'bright');
    log(manifest.post_install_message, 'cyan');
  }

  // Remind to rebuild
  log('\nRemember to rebuild bundles:', 'yellow');
  log('  npm run build', 'yellow');
}

function promptUser(question) {
  const readline = require('readline');
  const rl = readline.createInterface({
    input: process.stdin,
    output: process.stdout
  });

  return new Promise(resolve => {
    rl.question(question, answer => {
      rl.close();
      resolve(answer);
    });
  });
}

// Main execution
const packName = process.argv[2];

if (!packName) {
  log(`${colors.bright}BMAD Method Expansion Pack Installer${colors.reset}\n`, 'bright');
  log('Usage: node install-expansion-pack.js <pack-name>', 'yellow');
  log('\nExample:', 'cyan');
  log('  node install-expansion-pack.js infrastructure', 'cyan');
  
  log('\nAvailable expansion packs:', 'cyan');
  const packsDir = path.join(__dirname, '..', 'expansion-packs');
  if (fs.existsSync(packsDir)) {
    const packs = fs.readdirSync(packsDir)
      .filter(f => fs.statSync(path.join(packsDir, f)).isDirectory())
      .filter(f => f !== 'README.md');
    packs.forEach(pack => {
      const manifestPath = path.join(packsDir, pack, 'manifest.yml');
      if (fs.existsSync(manifestPath)) {
        try {
          const manifest = yaml.load(fs.readFileSync(manifestPath, 'utf8'));
          log(`  - ${pack}: ${manifest.description}`, 'cyan');
        } catch (e) {
          log(`  - ${pack}`, 'cyan');
        }
      }
    });
  }
  process.exit(0);
}

installExpansionPack(packName).catch(err => {
  error(`Installation failed: ${err.message}`);
  process.exit(1);
});