#!/usr/bin/env node

import * as fs from 'fs';
import * as path from 'path';
import { glob } from 'glob';

interface DocFile {
  path: string;
  size: number;
  track: 'current' | 'vision' | 'unknown';
  domain: 'backend' | 'frontend' | 'rust' | 'infra' | 'security' | 'ops' | 'product' | 'legal' | 'misc';
  status: 'in_veza_docs' | 'legacy' | 'excluded';
  relativePath: string;
  isImage: boolean;
  linkedImages?: string[];
}

class GlobalDocScanner {
  private repoRoot: string;
  private vezaDocsRoot: string;
  private results: DocFile[] = [];

  constructor(repoRoot: string) {
    this.repoRoot = repoRoot;
    this.vezaDocsRoot = path.join(repoRoot, 'veza-docs');
  }

  async scanAll(): Promise<void> {
    console.log('🔍 Scan global de tous les fichiers de documentation...');

    // Patterns à scanner
    const patterns = [
      '**/*.md',
      '**/*.mdx',
      '**/*.png',
      '**/*.jpg',
      '**/*.jpeg',
      '**/*.svg',
      '**/*.gif',
      '**/*.webp'
    ];

    // Dossiers à exclure
    const excludePatterns = [
      'node_modules/**',
      'dist/**',
      'build/**',
      'vendor/**',
      'target/**',
      '.git/**',
      '.docusaurus/**',
      'coverage/**',
      '.nyc_output/**',
      '*.log',
      '*.pid',
      '.env*',
      '*.key',
      '*.pem',
      '*.p12',
      '*.pfx'
    ];

    const allFiles: string[] = [];
    
    for (const pattern of patterns) {
      const files = await glob(pattern, { 
        cwd: this.repoRoot,
        ignore: excludePatterns
      });
      allFiles.push(...files);
    }

    console.log(`📄 ${allFiles.length} fichiers trouvés`);

    for (const file of allFiles) {
      const fullPath = path.join(this.repoRoot, file);
      const stats = fs.statSync(fullPath);
      
      const docFile: DocFile = {
        path: file,
        size: stats.size,
        track: 'unknown',
        domain: 'misc',
        status: 'legacy',
        relativePath: file,
        isImage: this.isImageFile(file)
      };

      // Déterminer si le fichier est dans veza-docs
      if (file.startsWith('veza-docs/')) {
        docFile.status = 'in_veza_docs';
        docFile.track = this.determineTrack(file);
        docFile.domain = this.determineDomain(file);
      } else if (this.isExcluded(file)) {
        docFile.status = 'excluded';
      }

      // Pour les fichiers Markdown, chercher les images liées
      if (!docFile.isImage && (file.endsWith('.md') || file.endsWith('.mdx'))) {
        docFile.linkedImages = this.findLinkedImages(fullPath);
      }

      this.results.push(docFile);
    }

    console.log(`✅ Scan terminé: ${this.results.length} fichiers analysés`);
  }

  private isImageFile(filePath: string): boolean {
    const ext = path.extname(filePath).toLowerCase();
    return ['.png', '.jpg', '.jpeg', '.svg', '.gif', '.webp'].includes(ext);
  }

  private isExcluded(filePath: string): boolean {
    const excludeDirs = [
      'node_modules',
      'dist',
      'build',
      'vendor',
      'target',
      '.git',
      '.docusaurus',
      'coverage',
      '.nyc_output'
    ];
    
    return excludeDirs.some(dir => filePath.includes(`/${dir}/`) || filePath.startsWith(`${dir}/`));
  }

  private determineTrack(filePath: string): 'current' | 'vision' | 'unknown' {
    if (filePath.includes('/current/')) return 'current';
    if (filePath.includes('/vision/')) return 'vision';
    return 'unknown';
  }

  private determineDomain(filePath: string): 'backend' | 'frontend' | 'rust' | 'infra' | 'security' | 'ops' | 'product' | 'legal' | 'misc' {
    const pathLower = filePath.toLowerCase();
    
    if (pathLower.includes('/backend/')) return 'backend';
    if (pathLower.includes('/frontend/')) return 'frontend';
    if (pathLower.includes('/rust/')) return 'rust';
    if (pathLower.includes('/infra/')) return 'infra';
    if (pathLower.includes('/security/')) return 'security';
    if (pathLower.includes('/ops/')) return 'ops';
    if (pathLower.includes('/product/')) return 'product';
    if (pathLower.includes('/legal/')) return 'legal';
    
    return 'misc';
  }

  private findLinkedImages(filePath: string): string[] {
    try {
      const content = fs.readFileSync(filePath, 'utf-8');
      const imageRegex = /!\[.*?\]\((.*?)\)/g;
      const images: string[] = [];
      let match;
      
      while ((match = imageRegex.exec(content)) !== null) {
        const imagePath = match[1];
        if (imagePath && !imagePath.startsWith('http')) {
          images.push(imagePath);
        }
      }
      
      return images;
    } catch (error) {
      return [];
    }
  }

  async generateReports(): Promise<void> {
    console.log('📊 Génération des rapports...');

    // Rapport JSON
    const jsonReport = {
      scanDate: new Date().toISOString(),
      totalFiles: this.results.length,
      inVezaDocs: this.results.filter(f => f.status === 'in_veza_docs').length,
      legacy: this.results.filter(f => f.status === 'legacy').length,
      excluded: this.results.filter(f => f.status === 'excluded').length,
      byTrack: {
        current: this.results.filter(f => f.track === 'current').length,
        vision: this.results.filter(f => f.track === 'vision').length,
        unknown: this.results.filter(f => f.track === 'unknown').length
      },
      byDomain: {
        backend: this.results.filter(f => f.domain === 'backend').length,
        frontend: this.results.filter(f => f.domain === 'frontend').length,
        rust: this.results.filter(f => f.domain === 'rust').length,
        infra: this.results.filter(f => f.domain === 'infra').length,
        security: this.results.filter(f => f.domain === 'security').length,
        ops: this.results.filter(f => f.domain === 'ops').length,
        product: this.results.filter(f => f.domain === 'product').length,
        legal: this.results.filter(f => f.domain === 'legal').length,
        misc: this.results.filter(f => f.domain === 'misc').length
      },
      files: this.results
    };

    const reportsDir = path.join(this.vezaDocsRoot, '_reports');
    if (!fs.existsSync(reportsDir)) {
      fs.mkdirSync(reportsDir, { recursive: true });
    }

    fs.writeFileSync(
      path.join(reportsDir, 'global_scan.json'),
      JSON.stringify(jsonReport, null, 2)
    );

    // Rapport Markdown
    const mdReport = this.generateMarkdownReport(jsonReport);
    fs.writeFileSync(
      path.join(reportsDir, 'global_scan.md'),
      mdReport
    );

    // Rapport des dossiers legacy
    await this.generateLegacyDirsReport();

    console.log('✅ Rapports générés dans veza-docs/_reports/');
  }

  private generateMarkdownReport(data: any): string {
    let md = `# 📊 Rapport de Scan Global - Documentation Veza\n\n`;
    md += `**Date** : ${new Date().toLocaleDateString('fr-FR')}\n\n`;

    // Résumé
    md += `## 📈 Résumé\n\n`;
    md += `- **Total fichiers** : ${data.totalFiles}\n`;
    md += `- **Dans veza-docs** : ${data.inVezaDocs} (${Math.round(data.inVezaDocs / data.totalFiles * 100)}%)\n`;
    md += `- **Legacy** : ${data.legacy} (${Math.round(data.legacy / data.totalFiles * 100)}%)\n`;
    md += `- **Exclus** : ${data.excluded} (${Math.round(data.excluded / data.totalFiles * 100)}%)\n\n`;

    // Par track
    md += `## 🎯 Répartition par Track\n\n`;
    md += `| Track | Fichiers | Pourcentage |\n`;
    md += `|-------|----------|-------------|\n`;
    md += `| Current | ${data.byTrack.current} | ${Math.round(data.byTrack.current / data.totalFiles * 100)}% |\n`;
    md += `| Vision | ${data.byTrack.vision} | ${Math.round(data.byTrack.vision / data.totalFiles * 100)}% |\n`;
    md += `| Unknown | ${data.byTrack.unknown} | ${Math.round(data.byTrack.unknown / data.totalFiles * 100)}% |\n\n`;

    // Par domaine
    md += `## 🏗️ Répartition par Domaine\n\n`;
    md += `| Domaine | Fichiers | Pourcentage |\n`;
    md += `|---------|----------|-------------|\n`;
    Object.entries(data.byDomain).forEach(([domain, count]) => {
      md += `| ${domain} | ${count} | ${Math.round(count as number / data.totalFiles * 100)}% |\n`;
    });
    md += `\n`;

    // Détail des fichiers
    md += `## 📄 Détail des Fichiers\n\n`;
    md += `| Chemin | Taille | Track | Domaine | Statut |\n`;
    md += `|--------|--------|-------|---------|--------|\n`;
    
    this.results.forEach(file => {
      const sizeKB = Math.round(file.size / 1024 * 100) / 100;
      md += `| \`${file.path}\` | ${sizeKB} KB | ${file.track} | ${file.domain} | ${file.status} |\n`;
    });

    return md;
  }

  private async generateLegacyDirsReport(): Promise<void> {
    const legacyDirs = new Set<string>();
    
    this.results
      .filter(f => f.status === 'legacy' && !f.isImage)
      .forEach(f => {
        const dir = path.dirname(f.path);
        if (dir !== '.' && !dir.startsWith('veza-docs/')) {
          legacyDirs.add(dir);
        }
      });

    const legacyData = {
      scanDate: new Date().toISOString(),
      totalLegacyDirs: legacyDirs.size,
      legacyDirs: Array.from(legacyDirs).sort(),
      filesInLegacyDirs: this.results.filter(f => f.status === 'legacy').length
    };

    const reportsDir = path.join(this.vezaDocsRoot, '_reports');
    
    fs.writeFileSync(
      path.join(reportsDir, 'legacy_doc_dirs.json'),
      JSON.stringify(legacyData, null, 2)
    );

    let md = `# 🗂️ Rapport des Dossiers Legacy - Documentation Veza\n\n`;
    md += `**Date** : ${new Date().toLocaleDateString('fr-FR')}\n\n`;
    md += `## 📊 Résumé\n\n`;
    md += `- **Dossiers legacy** : ${legacyData.totalLegacyDirs}\n`;
    md += `- **Fichiers dans dossiers legacy** : ${legacyData.filesInLegacyDirs}\n\n`;
    md += `## 📁 Dossiers à Nettoyer\n\n`;
    md += `| Dossier | Fichiers |\n`;
    md += `|---------|----------|\n`;
    
    legacyDirs.forEach(dir => {
      const fileCount = this.results.filter(f => f.path.startsWith(dir + '/')).length;
      md += `| \`${dir}\` | ${fileCount} |\n`;
    });

    fs.writeFileSync(
      path.join(reportsDir, 'legacy_doc_dirs.md'),
      md
    );
  }

  async run(): Promise<void> {
    console.log('🚀 Démarrage du scan global...');
    
    try {
      await this.scanAll();
      await this.generateReports();
      console.log('✅ Scan global terminé avec succès!');
    } catch (error) {
      console.error('❌ Erreur lors du scan global:', error);
      process.exit(1);
    }
  }
}

// Exécution du script
if (require.main === module) {
  const repoRoot = process.argv[2] || path.join(__dirname, '../..');
  const scanner = new GlobalDocScanner(repoRoot);
  scanner.run();
}

export { GlobalDocScanner };
