import * as plugins from './mod.plugins.js';
import { logger } from '../gitzone.logging.js';

export interface IModuleStats {
  name: string;
  filesProcessed: number;
  executionTime: number;
  errors: number;
  successes: number;
  filesCreated: number;
  filesModified: number;
  filesDeleted: number;
}

export interface IFormatStats {
  totalExecutionTime: number;
  startTime: number;
  endTime: number;
  moduleStats: Map<string, IModuleStats>;
  overallStats: {
    totalFiles: number;
    totalCreated: number;
    totalModified: number;
    totalDeleted: number;
    totalErrors: number;
    cacheHits: number;
    cacheMisses: number;
  };
}

export class FormatStats {
  private stats: IFormatStats;
  
  constructor() {
    this.stats = {
      totalExecutionTime: 0,
      startTime: Date.now(),
      endTime: 0,
      moduleStats: new Map(),
      overallStats: {
        totalFiles: 0,
        totalCreated: 0,
        totalModified: 0,
        totalDeleted: 0,
        totalErrors: 0,
        cacheHits: 0,
        cacheMisses: 0
      }
    };
  }
  
  startModule(moduleName: string): void {
    this.stats.moduleStats.set(moduleName, {
      name: moduleName,
      filesProcessed: 0,
      executionTime: 0,
      errors: 0,
      successes: 0,
      filesCreated: 0,
      filesModified: 0,
      filesDeleted: 0
    });
  }
  
  moduleStartTime(moduleName: string): number {
    return Date.now();
  }
  
  endModule(moduleName: string, startTime: number): void {
    const moduleStats = this.stats.moduleStats.get(moduleName);
    if (moduleStats) {
      moduleStats.executionTime = Date.now() - startTime;
    }
  }
  
  recordFileOperation(moduleName: string, operation: 'create' | 'modify' | 'delete', success: boolean = true): void {
    const moduleStats = this.stats.moduleStats.get(moduleName);
    if (!moduleStats) return;
    
    moduleStats.filesProcessed++;
    
    if (success) {
      moduleStats.successes++;
      this.stats.overallStats.totalFiles++;
      
      switch (operation) {
        case 'create':
          moduleStats.filesCreated++;
          this.stats.overallStats.totalCreated++;
          break;
        case 'modify':
          moduleStats.filesModified++;
          this.stats.overallStats.totalModified++;
          break;
        case 'delete':
          moduleStats.filesDeleted++;
          this.stats.overallStats.totalDeleted++;
          break;
      }
    } else {
      moduleStats.errors++;
      this.stats.overallStats.totalErrors++;
    }
  }
  
  recordCacheHit(): void {
    this.stats.overallStats.cacheHits++;
  }
  
  recordCacheMiss(): void {
    this.stats.overallStats.cacheMisses++;
  }
  
  finish(): void {
    this.stats.endTime = Date.now();
    this.stats.totalExecutionTime = this.stats.endTime - this.stats.startTime;
  }
  
  displayStats(): void {
    console.log('\n📊 Format Operation Statistics:');
    console.log('═'.repeat(50));
    
    // Overall stats
    console.log('\nOverall Summary:');
    console.log(`  Total Execution Time: ${this.formatDuration(this.stats.totalExecutionTime)}`);
    console.log(`  Files Processed: ${this.stats.overallStats.totalFiles}`);
    console.log(`    • Created: ${this.stats.overallStats.totalCreated}`);
    console.log(`    • Modified: ${this.stats.overallStats.totalModified}`);
    console.log(`    • Deleted: ${this.stats.overallStats.totalDeleted}`);
    console.log(`  Errors: ${this.stats.overallStats.totalErrors}`);
    
    if (this.stats.overallStats.cacheHits > 0 || this.stats.overallStats.cacheMisses > 0) {
      const cacheHitRate = this.stats.overallStats.cacheHits / 
        (this.stats.overallStats.cacheHits + this.stats.overallStats.cacheMisses) * 100;
      console.log(`  Cache Hit Rate: ${cacheHitRate.toFixed(1)}%`);
      console.log(`    • Hits: ${this.stats.overallStats.cacheHits}`);
      console.log(`    • Misses: ${this.stats.overallStats.cacheMisses}`);
    }
    
    // Module stats
    console.log('\nModule Breakdown:');
    console.log('─'.repeat(50));
    
    const sortedModules = Array.from(this.stats.moduleStats.values())
      .sort((a, b) => b.filesProcessed - a.filesProcessed);
    
    for (const moduleStats of sortedModules) {
      console.log(`\n${this.getModuleIcon(moduleStats.name)} ${moduleStats.name}:`);
      console.log(`  Execution Time: ${this.formatDuration(moduleStats.executionTime)}`);
      console.log(`  Files Processed: ${moduleStats.filesProcessed}`);
      
      if (moduleStats.filesCreated > 0) {
        console.log(`    • Created: ${moduleStats.filesCreated}`);
      }
      if (moduleStats.filesModified > 0) {
        console.log(`    • Modified: ${moduleStats.filesModified}`);
      }
      if (moduleStats.filesDeleted > 0) {
        console.log(`    • Deleted: ${moduleStats.filesDeleted}`);
      }
      
      if (moduleStats.errors > 0) {
        console.log(`  ❌ Errors: ${moduleStats.errors}`);
      }
    }
    
    console.log('\n' + '═'.repeat(50));
  }
  
  async saveReport(outputPath: string): Promise<void> {
    const report = {
      timestamp: new Date().toISOString(),
      executionTime: this.stats.totalExecutionTime,
      overallStats: this.stats.overallStats,
      moduleStats: Array.from(this.stats.moduleStats.values())
    };
    
    await plugins.smartfile.memory.toFs(JSON.stringify(report, null, 2), outputPath);
    logger.log('info', `Statistics report saved to ${outputPath}`);
  }
  
  private formatDuration(ms: number): string {
    if (ms < 1000) {
      return `${ms}ms`;
    } else if (ms < 60000) {
      return `${(ms / 1000).toFixed(1)}s`;
    } else {
      const minutes = Math.floor(ms / 60000);
      const seconds = Math.floor((ms % 60000) / 1000);
      return `${minutes}m ${seconds}s`;
    }
  }
  
  private getModuleIcon(module: string): string {
    const icons: Record<string, string> = {
      'packagejson': '📦',
      'license': '📝',
      'tsconfig': '🔧',
      'cleanup': '🚮',
      'gitignore': '🔒',
      'prettier': '✨',
      'readme': '📖',
      'templates': '📄',
      'npmextra': '⚙️',
      'copy': '📋'
    };
    return icons[module] || '📁';
  }
}