#!/usr/bin/env node

import * as fs from 'fs';
import * as path from 'path';
import { execSync } from 'child_process';

interface CleanupPlan {
  directories: string[];
  files: string[];
  backupPath?: string;
  totalSize: number;
}

class LegacyCleanup {
  private repoRoot: string;
  private vezaDocsRoot: string;
  private reportsDir: string;

  constructor(repoRoot: string) {
    this.repoRoot = repoRoot;
    this.vezaDocsRoot = path.join(repoRoot, 'veza-docs');
    this.reportsDir = path.join(this.vezaDocsRoot, '_reports');
    console.log(`Repo root: ${this.repoRoot}`);
    console.log(`Veza docs root: ${this.vezaDocsRoot}`);
    console.log(`Reports dir: ${this.reportsDir}`);
  }

  async createCleanupPlan(): Promise<CleanupPlan> {
    console.log('📋 Création du plan de nettoyage...');

    // Lire la liste des dossiers legacy
    const legacyDirsPath = path.join(this.reportsDir, 'legacy_doc_dirs.json');
    console.log(`Recherche du fichier: ${legacyDirsPath}`);
    if (!fs.existsSync(legacyDirsPath)) {
      throw new Error(`Fichier legacy_doc_dirs.json manquant à ${legacyDirsPath}. Exécutez d'abord le scan global.`);
    }

    const legacyData = JSON.parse(fs.readFileSync(legacyDirsPath, 'utf-8'));
    
    // Filtrer les dossiers à nettoyer (exclure veza-docs-backup pour l'instant)
    const directoriesToClean = legacyData.legacyDirs.filter((dir: string) => 
      !dir.includes('veza-docs-backup') && 
      !dir.includes('node_modules') &&
      !dir.includes('.git') &&
      !dir.includes('dist') &&
      !dir.includes('build')
    );

    // Calculer la taille totale
    let totalSize = 0;
    const filesToClean: string[] = [];

    for (const dir of directoriesToClean) {
      const fullPath = path.join(this.repoRoot, dir);
      if (fs.existsSync(fullPath)) {
        const stats = this.getDirSize(fullPath);
        totalSize += stats.size;
        filesToClean.push(...stats.files);
      }
    }

    const plan: CleanupPlan = {
      directories: directoriesToClean,
      files: filesToClean,
      totalSize
    };

    // Créer un backup si demandé
    if (process.argv.includes('--backup')) {
      plan.backupPath = await this.createBackup(plan);
    }

    return plan;
  }

  private getDirSize(dirPath: string): { size: number; files: string[] } {
    let totalSize = 0;
    const files: string[] = [];

    const walkDir = (currentPath: string) => {
      const items = fs.readdirSync(currentPath);
      
      for (const item of items) {
        const itemPath = path.join(currentPath, item);
        const stats = fs.statSync(itemPath);
        
        if (stats.isDirectory()) {
          walkDir(itemPath);
        } else {
          totalSize += stats.size;
          files.push(itemPath);
        }
      }
    };

    walkDir(dirPath);
    return { size: totalSize, files };
  }

  private async createBackup(plan: CleanupPlan): Promise<string> {
    console.log('💾 Création du backup...');

    const backupPath = path.join(this.reportsDir, 'legacy_docs_backup.tar.gz');
    
    try {
      // Créer un tar.gz des dossiers à nettoyer
      const dirsToBackup = plan.directories.join(' ');
      const command = `cd "${this.repoRoot}" && tar -czf "${backupPath}" ${dirsToBackup}`;
      
      execSync(command, { stdio: 'pipe' });
      
      console.log(`✅ Backup créé: ${backupPath}`);
      return backupPath;
    } catch (error) {
      console.warn('⚠️ Impossible de créer le backup:', error);
      return '';
    }
  }

  async generateCleanupReport(plan: CleanupPlan): Promise<void> {
    console.log('📊 Génération du rapport de nettoyage...');

    const sizeMB = Math.round(plan.totalSize / (1024 * 1024) * 100) / 100;

    let md = `# 🧹 Plan de Nettoyage - Documentation Veza\n\n`;
    md += `**Date** : ${new Date().toLocaleDateString('fr-FR')}\n\n`;

    md += `## 📊 Résumé\n\n`;
    md += `- **Dossiers à nettoyer** : ${plan.directories.length}\n`;
    md += `- **Fichiers à supprimer** : ${plan.files.length}\n`;
    md += `- **Taille totale** : ${sizeMB} MB\n`;
    if (plan.backupPath) {
      md += `- **Backup créé** : \`${plan.backupPath}\`\n`;
    }
    md += `\n`;

    md += `## 📁 Dossiers à Supprimer\n\n`;
    md += `| Dossier | Taille | Fichiers |\n`;
    md += `|---------|--------|----------|\n`;

    for (const dir of plan.directories) {
      const fullPath = path.join(this.repoRoot, dir);
      if (fs.existsSync(fullPath)) {
        const stats = this.getDirSize(fullPath);
        const dirSizeMB = Math.round(stats.size / (1024 * 1024) * 100) / 100;
        md += `| \`${dir}\` | ${dirSizeMB} MB | ${stats.files.length} |\n`;
      }
    }

    md += `\n## ⚠️ Avertissements\n\n`;
    md += `- **Vérifiez** que tous les fichiers importants ont été migrés vers \`veza-docs/\`\n`;
    md += `- **Sauvegardez** vos données avant d'appliquer le nettoyage\n`;
    md += `- **Testez** le build après nettoyage : \`npm run build\`\n\n`;

    md += `## 🚀 Commandes de Nettoyage\n\n`;
    md += `\`\`\`bash\n`;
    md += `# Dry-run (simulation)\n`;
    md += `npx ts-node scripts/cleanup_legacy.ts --dry-run\n\n`;
    md += `# Application réelle\n`;
    md += `npx ts-node scripts/cleanup_legacy.ts --apply\n`;
    md += `\`\`\`\n`;

    fs.writeFileSync(
      path.join(this.reportsDir, 'cleanup_plan.md'),
      md
    );

    // Sauvegarder le plan en JSON
    fs.writeFileSync(
      path.join(this.reportsDir, 'cleanup_plan.json'),
      JSON.stringify(plan, null, 2)
    );

    console.log('✅ Rapport de nettoyage généré');
  }

  async dryRun(): Promise<void> {
    console.log('🔍 Simulation du nettoyage (dry-run)...');

    const plan = await this.createCleanupPlan();
    await this.generateCleanupReport(plan);

    console.log('📋 Plan de nettoyage créé:');
    console.log(`   - ${plan.directories.length} dossiers à supprimer`);
    console.log(`   - ${plan.files.length} fichiers à supprimer`);
    console.log(`   - ${Math.round(plan.totalSize / (1024 * 1024) * 100) / 100} MB à libérer`);
    
    if (plan.backupPath) {
      console.log(`   - Backup: ${plan.backupPath}`);
    }
  }

  async apply(): Promise<void> {
    console.log('🧹 Application du nettoyage...');

    // Vérifier que le plan existe
    const planPath = path.join(this.reportsDir, 'cleanup_plan.json');
    if (!fs.existsSync(planPath)) {
      throw new Error('Plan de nettoyage manquant. Exécutez d\'abord --dry-run');
    }

    const plan: CleanupPlan = JSON.parse(fs.readFileSync(planPath, 'utf-8'));

    console.log(`🗑️ Suppression de ${plan.directories.length} dossiers...`);

    let deletedCount = 0;
    let errorCount = 0;

    for (const dir of plan.directories) {
      const fullPath = path.join(this.repoRoot, dir);
      
      if (fs.existsSync(fullPath)) {
        try {
          fs.rmSync(fullPath, { recursive: true, force: true });
          console.log(`   ✅ Supprimé: ${dir}`);
          deletedCount++;
        } catch (error) {
          console.error(`   ❌ Erreur: ${dir} - ${error}`);
          errorCount++;
        }
      } else {
        console.log(`   ⚠️ Déjà supprimé: ${dir}`);
      }
    }

    console.log(`\n📊 Résultat:`);
    console.log(`   - Dossiers supprimés: ${deletedCount}`);
    console.log(`   - Erreurs: ${errorCount}`);

    // Vérifier le build après nettoyage
    console.log('\n🔍 Vérification du build après nettoyage...');
    try {
      execSync('npm run build', { cwd: this.vezaDocsRoot, stdio: 'pipe' });
      console.log('✅ Build réussi après nettoyage');
    } catch (error) {
      console.error('❌ Build échoué après nettoyage:', error);
      throw new Error('Le build a échoué après nettoyage. Vérifiez les fichiers supprimés.');
    }
  }

  async run(): Promise<void> {
    const args = process.argv.slice(2);
    
    if (args.includes('--dry-run')) {
      await this.dryRun();
    } else if (args.includes('--apply')) {
      await this.apply();
    } else {
      console.log('Usage:');
      console.log('  --dry-run  : Simulation du nettoyage');
      console.log('  --apply    : Application du nettoyage');
      console.log('  --backup   : Créer un backup (avec --dry-run)');
    }
  }
}

// Exécution du script
if (require.main === module) {
  // Trouver le premier argument qui n'est pas un flag et qui n'est pas ts-node
  const args = process.argv.slice(2); // Ignorer 'ts-node' et le nom du script
  const repoRoot = args.find(arg => !arg.startsWith('--')) || path.join(__dirname, '../..');
  const cleanup = new LegacyCleanup(repoRoot);
  cleanup.run();
}

export { LegacyCleanup };
