#!/usr/bin/env node

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

interface VerificationResult {
  check: string;
  status: 'PASS' | 'FAIL' | 'WARN';
  message: string;
  details?: any;
}

class IntegrityVerifier {
  private vezaDocsRoot: string;
  private results: VerificationResult[] = [];

  constructor(vezaDocsRoot: string) {
    this.vezaDocsRoot = vezaDocsRoot;
  }

  async verifyAll(): Promise<void> {
    console.log('🔍 Vérification de l\'intégrité de la documentation...');

    await this.verifyBuild();
    await this.verifySidebars();
    await this.verifyLinks();
    await this.verifySearch();
    await this.verifySitemap();

    this.generateReport();
  }

  private async verifyBuild(): Promise<void> {
    console.log('📦 Vérification du build...');
    
    try {
      const buildDir = path.join(this.vezaDocsRoot, 'build');
      if (fs.existsSync(buildDir)) {
        this.results.push({
          check: 'Build Docusaurus',
          status: 'PASS',
          message: 'Build réussi, dossier build/ existe'
        });
      } else {
        this.results.push({
          check: 'Build Docusaurus',
          status: 'FAIL',
          message: 'Build échoué, dossier build/ manquant'
        });
      }
    } catch (error) {
      this.results.push({
        check: 'Build Docusaurus',
        status: 'FAIL',
        message: `Erreur lors de la vérification du build: ${error}`
      });
    }
  }

  private async verifySidebars(): Promise<void> {
    console.log('📋 Vérification des sidebars...');

    const tracks = ['current', 'vision'];
    let allPagesReferenced = true;
    const unreferencedPages: string[] = [];

    for (const track of tracks) {
      const sidebarPath = path.join(this.vezaDocsRoot, track, 'sidebars.js');
      
      if (!fs.existsSync(sidebarPath)) {
        this.results.push({
          check: `Sidebar ${track}`,
          status: 'FAIL',
          message: `Fichier sidebars.js manquant pour ${track}`
        });
        continue;
      }

      // Lire le contenu du sidebar
      const sidebarContent = fs.readFileSync(sidebarPath, 'utf-8');
      
      // Trouver toutes les pages dans le track
      const pagesPattern = `${track}/**/*.md`;
      const pages = await glob(pagesPattern, { cwd: this.vezaDocsRoot });
      
      // Vérifier que chaque page est référencée dans le sidebar
      for (const page of pages) {
        const pageId = path.basename(page, '.md');
        if (!sidebarContent.includes(`'${pageId}'`) && !sidebarContent.includes(`"${pageId}"`)) {
          unreferencedPages.push(page);
          allPagesReferenced = false;
        }
      }
    }

    if (allPagesReferenced) {
      this.results.push({
        check: 'Couverture des sidebars',
        status: 'PASS',
        message: 'Toutes les pages sont référencées dans les sidebars'
      });
    } else {
      this.results.push({
        check: 'Couverture des sidebars',
        status: 'WARN',
        message: `${unreferencedPages.length} pages non référencées dans les sidebars`,
        details: unreferencedPages
      });
    }
  }

  private async verifyLinks(): Promise<void> {
    console.log('🔗 Vérification des liens...');

    const buildDir = path.join(this.vezaDocsRoot, 'build');
    if (!fs.existsSync(buildDir)) {
      this.results.push({
        check: 'Vérification des liens',
        status: 'FAIL',
        message: 'Impossible de vérifier les liens, build manquant'
      });
      return;
    }

    // Compter les fichiers HTML générés
    const htmlFiles = await glob('**/*.html', { cwd: buildDir });
    
    this.results.push({
      check: 'Génération des pages',
      status: 'PASS',
      message: `${htmlFiles.length} pages HTML générées`,
      details: { htmlFiles: htmlFiles.length }
    });

    // Vérifier la présence des pages principales
    const mainPages = [
      'current/overview/index.html',
      'vision/overview/index.html'
    ];

    const missingPages = mainPages.filter(page => !fs.existsSync(path.join(buildDir, page)));
    
    if (missingPages.length === 0) {
      this.results.push({
        check: 'Pages principales',
        status: 'PASS',
        message: 'Toutes les pages principales sont présentes'
      });
    } else {
      this.results.push({
        check: 'Pages principales',
        status: 'FAIL',
        message: `Pages manquantes: ${missingPages.join(', ')}`
      });
    }
  }

  private async verifySearch(): Promise<void> {
    console.log('🔍 Vérification de la recherche...');

    const buildDir = path.join(this.vezaDocsRoot, 'build');
    const searchIndexPath = path.join(buildDir, 'search-index.json');
    
    if (fs.existsSync(searchIndexPath)) {
      const searchIndex = JSON.parse(fs.readFileSync(searchIndexPath, 'utf-8'));
      const indexedPages = searchIndex.length || 0;
      
      this.results.push({
        check: 'Index de recherche',
        status: 'PASS',
        message: `${indexedPages} pages indexées pour la recherche`,
        details: { indexedPages }
      });
    } else {
      this.results.push({
        check: 'Index de recherche',
        status: 'WARN',
        message: 'Index de recherche manquant (recherche locale non configurée)'
      });
    }
  }

  private async verifySitemap(): Promise<void> {
    console.log('🗺️ Vérification du sitemap...');

    const buildDir = path.join(this.vezaDocsRoot, 'build');
    const sitemapPath = path.join(buildDir, 'sitemap.xml');
    
    if (fs.existsSync(sitemapPath)) {
      const sitemapContent = fs.readFileSync(sitemapPath, 'utf-8');
      const urlCount = (sitemapContent.match(/<url>/g) || []).length;
      
      this.results.push({
        check: 'Sitemap',
        status: 'PASS',
        message: `Sitemap généré avec ${urlCount} URLs`,
        details: { urlCount }
      });
    } else {
      this.results.push({
        check: 'Sitemap',
        status: 'WARN',
        message: 'Sitemap manquant'
      });
    }
  }

  private generateReport(): void {
    console.log('📊 Génération du rapport de vérification...');

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

    // Rapport Markdown
    let md = `# 🔍 Rapport de Vérification - Documentation Veza\n\n`;
    md += `**Date** : ${new Date().toLocaleDateString('fr-FR')}\n\n`;

    // Résumé
    const passCount = this.results.filter(r => r.status === 'PASS').length;
    const failCount = this.results.filter(r => r.status === 'FAIL').length;
    const warnCount = this.results.filter(r => r.status === 'WARN').length;

    md += `## 📈 Résumé\n\n`;
    md += `- ✅ **Succès** : ${passCount}\n`;
    md += `- ❌ **Échecs** : ${failCount}\n`;
    md += `- ⚠️ **Avertissements** : ${warnCount}\n\n`;

    // Détail des vérifications
    md += `## 🔍 Détail des Vérifications\n\n`;
    md += `| Vérification | Statut | Message |\n`;
    md += `|--------------|--------|----------|\n`;

    this.results.forEach(result => {
      const statusIcon = result.status === 'PASS' ? '✅' : result.status === 'FAIL' ? '❌' : '⚠️';
      md += `| ${result.check} | ${statusIcon} ${result.status} | ${result.message} |\n`;
    });

    md += `\n## 📋 Critères de Prêt au Nettoyage\n\n`;
    
    const isReadyForCleanup = failCount === 0 && warnCount <= 2;
    md += `- **Build réussi** : ${this.results.find(r => r.check === 'Build Docusaurus')?.status === 'PASS' ? '✅' : '❌'}\n`;
    md += `- **Liens fonctionnels** : ${this.results.find(r => r.check === 'Vérification des liens')?.status === 'PASS' ? '✅' : '❌'}\n`;
    md += `- **Sidebars complets** : ${this.results.find(r => r.check === 'Couverture des sidebars')?.status === 'PASS' ? '✅' : '⚠️'}\n`;
    md += `- **Pages principales** : ${this.results.find(r => r.check === 'Pages principales')?.status === 'PASS' ? '✅' : '❌'}\n\n`;

    if (isReadyForCleanup) {
      md += `## ✅ **PRÊT POUR LE NETTOYAGE**\n\n`;
      md += `Tous les critères sont respectés. Le nettoyage des anciens dossiers peut être effectué en toute sécurité.\n`;
    } else {
      md += `## ❌ **NON PRÊT POUR LE NETTOYAGE**\n\n`;
      md += `Des problèmes doivent être résolus avant de procéder au nettoyage.\n`;
    }

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

    // Rapport JSON
    const jsonReport = {
      scanDate: new Date().toISOString(),
      summary: {
        pass: passCount,
        fail: failCount,
        warn: warnCount,
        total: this.results.length
      },
      isReadyForCleanup,
      results: this.results
    };

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

    console.log('✅ Rapport de vérification généré');
    console.log(`📊 Résumé: ${passCount} ✅, ${failCount} ❌, ${warnCount} ⚠️`);
    console.log(`🧹 Prêt pour le nettoyage: ${isReadyForCleanup ? 'OUI' : 'NON'}`);
  }

  async run(): Promise<void> {
    try {
      await this.verifyAll();
    } catch (error) {
      console.error('❌ Erreur lors de la vérification:', error);
      process.exit(1);
    }
  }
}

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

export { IntegrityVerifier };
