#!/usr/bin/env node

/**
 * Script de déploiement production pour Veza V5 Ultra
 * Objectif: Déploiement zéro downtime avec rollback automatique
 */

const { execSync } = require('child_process');
const fs = require('fs');
const path = require('path');

console.log('🚀 VEZA V5 ULTRA - Production Deployment');
console.log('========================================\n');

// Configuration de déploiement
const deployConfig = {
  staging: {
    url: 'https://staging.veza.app',
    branch: 'staging',
    healthCheck: '/api/health',
  },
  production: {
    url: 'https://veza.app',
    branch: 'main',
    healthCheck: '/api/health',
  },
  backup: {
    enabled: true,
    maxBackups: 5,
    retentionDays: 30,
  },
  monitoring: {
    sentry: process.env.SENTRY_DSN,
    analytics: process.env.GA_ID,
  },
};

// Fonction pour exécuter une commande avec logging
function execCommand(command, description) {
  console.log(`\n🔧 ${description}...`);
  try {
    const result = execSync(command, { 
      encoding: 'utf8',
      stdio: 'pipe'
    });
    console.log(`✅ ${description} completed`);
    return { success: true, result };
  } catch (error) {
    console.log(`❌ ${description} failed:`, error.message);
    return { success: false, error: error.message };
  }
}

// Fonction pour vérifier la santé de l'application
function healthCheck(url, maxRetries = 5) {
  console.log(`\n🏥 Health check: ${url}`);
  
  for (let i = 0; i < maxRetries; i++) {
    try {
      const result = execSync(`curl -f -s ${url}${deployConfig.staging.healthCheck}`, { 
        encoding: 'utf8',
        timeout: 10000 
      });
      
      if (result.includes('ok') || result.includes('healthy')) {
        console.log(`✅ Health check passed (attempt ${i + 1})`);
        return true;
      }
    } catch (error) {
      console.log(`⚠️  Health check failed (attempt ${i + 1}/${maxRetries})`);
      if (i < maxRetries - 1) {
        console.log('⏳ Waiting 10s before retry...');
        execSync('sleep 10');
      }
    }
  }
  
  console.log('❌ Health check failed after all retries');
  return false;
}

// Fonction pour créer un backup
function createBackup() {
  if (!deployConfig.backup.enabled) return true;
  
  console.log('\n💾 Creating backup...');
  
  const timestamp = new Date().toISOString().replace(/[:.]/g, '-');
  const backupDir = path.join(__dirname, '..', 'backups', timestamp);
  
  try {
    execSync(`mkdir -p ${backupDir}`, { stdio: 'pipe' });
    execSync(`cp -r dist ${backupDir}/`, { stdio: 'pipe' });
    execSync(`cp package.json ${backupDir}/`, { stdio: 'pipe' });
    execSync(`cp package-lock.json ${backupDir}/`, { stdio: 'pipe' });
    
    console.log(`✅ Backup created: ${backupDir}`);
    return true;
  } catch (error) {
    console.log(`❌ Backup failed:`, error.message);
    return false;
  }
}

// Fonction pour nettoyer les anciens backups
function cleanupBackups() {
  if (!deployConfig.backup.enabled) return;
  
  console.log('\n🧹 Cleaning up old backups...');
  
  const backupsDir = path.join(__dirname, '..', 'backups');
  if (!fs.existsSync(backupsDir)) return;
  
  try {
    const backups = fs.readdirSync(backupsDir)
      .map(name => ({
        name,
        path: path.join(backupsDir, name),
        mtime: fs.statSync(path.join(backupsDir, name)).mtime
      }))
      .sort((a, b) => b.mtime - a.mtime);
    
    // Garder seulement les 5 derniers backups
    const toDelete = backups.slice(deployConfig.backup.maxBackups);
    
    toDelete.forEach(backup => {
      execSync(`rm -rf ${backup.path}`, { stdio: 'pipe' });
      console.log(`🗑️  Deleted old backup: ${backup.name}`);
    });
    
    console.log(`✅ Cleanup completed`);
  } catch (error) {
    console.log(`⚠️  Cleanup failed:`, error.message);
  }
}

// Fonction pour déployer sur staging
function deployStaging() {
  console.log('\n🚀 DEPLOYING TO STAGING');
  console.log('=======================');
  
  // 1. Préparation
  console.log('\n📋 Step 1: Preparation');
  execCommand('git fetch origin', 'Fetching latest changes');
  execCommand('git checkout staging', 'Switching to staging branch');
  execCommand('git pull origin staging', 'Pulling latest staging changes');
  
  // 2. Build
  console.log('\n🔨 Step 2: Build');
  execCommand('npm ci', 'Installing dependencies');
  execCommand('npm run build:optimized', 'Building optimized bundle');
  
  // 3. Tests
  console.log('\n🧪 Step 3: Tests');
  execCommand('npm run prod:test', 'Running production tests');
  
  // 4. Backup
  console.log('\n💾 Step 4: Backup');
  createBackup();
  
  // 5. Deploy
  console.log('\n🚀 Step 5: Deploy');
  execCommand('npm run deploy:staging', 'Deploying to staging');
  
  // 6. Health Check
  console.log('\n🏥 Step 6: Health Check');
  if (healthCheck(deployConfig.staging.url)) {
    console.log('✅ Staging deployment successful!');
    return true;
  } else {
    console.log('❌ Staging deployment failed!');
    return false;
  }
}

// Fonction pour déployer sur production
function deployProduction() {
  console.log('\n🚀 DEPLOYING TO PRODUCTION');
  console.log('==========================');
  
  // 1. Préparation
  console.log('\n📋 Step 1: Preparation');
  execCommand('git checkout main', 'Switching to main branch');
  execCommand('git pull origin main', 'Pulling latest main changes');
  
  // 2. Build
  console.log('\n🔨 Step 2: Build');
  execCommand('npm ci', 'Installing dependencies');
  execCommand('npm run build:optimized', 'Building optimized bundle');
  
  // 3. Tests
  console.log('\n🧪 Step 3: Tests');
  execCommand('npm run prod:test', 'Running production tests');
  
  // 4. Backup
  console.log('\n💾 Step 4: Backup');
  createBackup();
  
  // 5. Deploy
  console.log('\n🚀 Step 5: Deploy');
  execCommand('npm run deploy:prod', 'Deploying to production');
  
  // 6. Health Check
  console.log('\n🏥 Step 6: Health Check');
  if (healthCheck(deployConfig.production.url)) {
    console.log('✅ Production deployment successful!');
    return true;
  } else {
    console.log('❌ Production deployment failed!');
    return false;
  }
}

// Fonction pour rollback
function rollback() {
  console.log('\n🔄 ROLLBACK');
  console.log('===========');
  
  const backupsDir = path.join(__dirname, '..', 'backups');
  if (!fs.existsSync(backupsDir)) {
    console.log('❌ No backups found for rollback');
    return false;
  }
  
  const backups = fs.readdirSync(backupsDir)
    .map(name => ({
      name,
      path: path.join(backupsDir, name),
      mtime: fs.statSync(path.join(backupsDir, name)).mtime
    }))
    .sort((a, b) => b.mtime - a.mtime);
  
  if (backups.length === 0) {
    console.log('❌ No backups available for rollback');
    return false;
  }
  
  const latestBackup = backups[0];
  console.log(`🔄 Rolling back to: ${latestBackup.name}`);
  
  try {
    execSync(`rm -rf dist`, { stdio: 'pipe' });
    execSync(`cp -r ${latestBackup.path}/dist .`, { stdio: 'pipe' });
    execSync(`npm run deploy:prod`, { stdio: 'pipe' });
    
    console.log('✅ Rollback completed');
    return true;
  } catch (error) {
    console.log('❌ Rollback failed:', error.message);
    return false;
  }
}

// Fonction pour monitoring post-deploy
function setupMonitoring() {
  console.log('\n📊 Setting up monitoring...');
  
  // Sentry
  if (deployConfig.monitoring.sentry) {
    console.log('✅ Sentry monitoring enabled');
  }
  
  // Analytics
  if (deployConfig.monitoring.analytics) {
    console.log('✅ Google Analytics enabled');
  }
  
  // Logs
  console.log('✅ Application logs configured');
  
  console.log('📊 Monitoring dashboard: https://dashboard.veza.app');
}

// Fonction principale
async function main() {
  const args = process.argv.slice(2);
  const command = args[0] || 'staging';
  
  console.log(`🎯 Deployment target: ${command}`);
  
  let success = false;
  
  switch (command) {
    case 'staging':
      success = deployStaging();
      break;
      
    case 'production':
      success = deployProduction();
      break;
      
    case 'rollback':
      success = rollback();
      break;
      
    default:
      console.log('❌ Unknown command. Use: staging, production, or rollback');
      process.exit(1);
  }
  
  if (success) {
    setupMonitoring();
    cleanupBackups();
    
    console.log('\n🎉 DEPLOYMENT SUCCESSFUL!');
    console.log('========================');
    console.log('✅ Application deployed');
    console.log('✅ Health checks passed');
    console.log('✅ Monitoring active');
    console.log('✅ Backup created');
    
    console.log('\n📱 Next steps:');
    console.log('- Monitor application metrics');
    console.log('- Check error logs');
    console.log('- Verify user feedback');
    console.log('- Update documentation');
    
  } else {
    console.log('\n❌ DEPLOYMENT FAILED!');
    console.log('====================');
    console.log('❌ Check logs for errors');
    console.log('❌ Consider rollback if needed');
    console.log('❌ Fix issues before retry');
    
    process.exit(1);
  }
}

// Exécuter le script
main().catch(error => {
  console.error('❌ Deployment script failed:', error);
  process.exit(1);
});
