// src/utils/auditService.ts 
import { config } from '../config/appConfig.js';
import { logger } from '../services/logger.js';

export interface AuditEntry {
  timestamp: number;
  phase: string;
  action: string;
  input: any;
  output: any;
  confidence: number;
  processingTimeMs: number;
  metadata: Record<string, any>;
}

export interface CompressedAuditEntry {
  timestamp: number;
  phase: string;
  action: string;
  inputSummary: string;
  outputSummary: string;
  confidence: number;
  processingTimeMs: number;
  metadata: Record<string, any>;
}

export interface ProcessedAuditTrail {
  totalTime: number;
  avgConfidence: number;
  stepCount: number;
  highConfidenceSteps: number;
  lowConfidenceSteps: number;
  phases: Array<{
    name: string;
    icon: string;
    displayName: string;
    avgConfidence: number;
    totalTime: number;
    entries: CompressedAuditEntry[];
  }>;
  summary: {
    analysisQuality: 'excellent' | 'good' | 'fair' | 'poor';
    keyInsights: string[];
    potentialIssues: string[];
  };
}

class AuditService {
  private readonly enabled: boolean;
  private readonly detailLevel: 'minimal' | 'standard' | 'verbose';
  private tempEntries: AuditEntry[] = [];
  
  private readonly phaseConfig = {
    'initialization': { icon: '🚀', displayName: 'Initialisierung' },
    'retrieval': { icon: '🔍', displayName: 'Datensuche' },
    'selection': { icon: '🎯', displayName: 'Tool-Auswahl' },
    'micro-task': { icon: '⚡', displayName: 'Detail-Analyse' },
    'validation': { icon: '✓', displayName: 'Validierung' },
    'completion': { icon: '✅', displayName: 'Finalisierung' }
  };

  private readonly actionTranslations = {
    'pipeline-start': 'Analyse gestartet',
    'embeddings-search': 'Ähnliche Tools gesucht', 
    'ai-tool-selection': 'Tools automatisch ausgewählt',
    'ai-analysis': 'KI-Analyse durchgeführt',
    'phase-tool-selection': 'Phasen-Tools evaluiert',
    'tool-evaluation': 'Tool-Bewertung erstellt',
    'background-knowledge-selection': 'Hintergrundwissen ausgewählt',
    'confidence-scoring': 'Vertrauenswertung berechnet',
    'pipeline-end': 'Analyse abgeschlossen'
  };

  constructor() {
    this.enabled = config.audit.enabled;
    this.detailLevel = config.audit.detailLevel;
    
    logger.info('audit-service', 'Audit service initialized', {
      enabled: this.enabled,
      detailLevel: this.detailLevel
    });
  }

  addEntry(
    phase: string,
    action: string,
    input: any,
    output: any,
    confidence: number,
    startTime: number,
    metadata: Record<string, any> = {}
  ): void {
    if (!this.enabled) return;

    const entry: AuditEntry = {
      timestamp: Date.now(),
      phase,
      action,
      input: this.compressData(input),
      output: this.compressData(output),
      confidence: Math.round(confidence),
      processingTimeMs: Date.now() - startTime,
      metadata
    };

    this.tempEntries.push(entry);
    logger.audit(phase, action, confidence, entry.processingTimeMs, metadata);
  }

  mergeAndClear(auditTrail: AuditEntry[]): void {
    if (!this.enabled || this.tempEntries.length === 0) return;

    auditTrail.unshift(...this.tempEntries);
    const entryCount = this.tempEntries.length;
    this.tempEntries = [];
    
    logger.debug('audit-service', `Merged audit entries`, { entryCount });
  }

  processAuditTrail(rawAuditTrail: AuditEntry[]): ProcessedAuditTrail | null {
    if (!this.enabled) {
      return null;
    }
    
    if (!rawAuditTrail || !Array.isArray(rawAuditTrail) || rawAuditTrail.length === 0) {
      logger.debug('audit-service', 'No audit trail data to process');
      return null;
    }

    try {
      logger.debug('audit-service', 'Processing audit trail', { entries: rawAuditTrail.length });

      const totalTime = rawAuditTrail.reduce((sum, entry) => sum + (entry.processingTimeMs || 0), 0);
      const validConfidenceEntries = rawAuditTrail.filter(entry => typeof entry.confidence === 'number');
      const avgConfidence = validConfidenceEntries.length > 0 
        ? Math.round(validConfidenceEntries.reduce((sum, entry) => sum + entry.confidence, 0) / validConfidenceEntries.length)
        : 0;
        
      const highConfidenceSteps = rawAuditTrail.filter(entry => (entry.confidence || 0) >= 80).length;
      const lowConfidenceSteps = rawAuditTrail.filter(entry => (entry.confidence || 0) < 60).length;

      const groupedEntries = rawAuditTrail.reduce((groups, entry) => {
        const phase = entry.phase || 'unknown';
        if (!groups[phase]) groups[phase] = [];
        groups[phase].push(entry);
        return groups;
      }, {} as Record<string, AuditEntry[]>);

      const phases = Object.entries(groupedEntries).map(([phase, entries]) => {
        const phaseConfig = this.phaseConfig[phase] || { icon: '📋', displayName: phase };
        const validEntries = entries.filter(entry => entry && typeof entry === 'object');
        
        const phaseAvgConfidence = validEntries.length > 0 
          ? Math.round(validEntries.reduce((sum, entry) => sum + (entry.confidence || 0), 0) / validEntries.length)
          : 0;
        
        const phaseTotalTime = validEntries.reduce((sum, entry) => sum + (entry.processingTimeMs || 0), 0);

        return {
          name: phase,
          icon: phaseConfig.icon,
          displayName: phaseConfig.displayName,
          avgConfidence: phaseAvgConfidence,
          totalTime: phaseTotalTime,
          entries: validEntries
            .map(e => this.compressEntry(e))
            .filter((e): e is CompressedAuditEntry => e !== null)
        };
      }).filter(phase => phase.entries.length > 0);

      const summary = this.generateSummary(rawAuditTrail, avgConfidence, lowConfidenceSteps);

      const result: ProcessedAuditTrail = {
        totalTime,
        avgConfidence,
        stepCount: rawAuditTrail.length,
        highConfidenceSteps,
        lowConfidenceSteps,
        phases,
        summary
      };

      logger.debug('audit-service', 'Audit trail processed successfully', {
        totalTime: `${totalTime}ms`,
        avgConfidence: `${avgConfidence}%`,
        phases: phases.length
      });
      
      return result;
        
    } catch (error) {
      logger.error('audit-service', 'Error processing audit trail', error as Error);
      return null;
    }
  }

  private compressEntry(entry: AuditEntry): CompressedAuditEntry | null {
    if (!entry || typeof entry !== 'object') {
      logger.warn('audit-service', 'Invalid audit entry', { entry });
      return null;
    }

    try {
      return {
        timestamp: entry.timestamp || Date.now(),
        phase: entry.phase || 'unknown',
        action: entry.action || 'unknown',
        inputSummary: this.summarizeData(entry.input),
        outputSummary: this.summarizeData(entry.output),
        confidence: entry.confidence || 0,
        processingTimeMs: entry.processingTimeMs || 0,
        metadata: entry.metadata || {}
      };
    } catch (error) {
      logger.error('audit-service', 'Error compressing audit entry', error as Error);
      return null;
    }
  }

  private compressData(data: any): any {
    if (this.detailLevel === 'verbose') {
      return data; 
    } else if (this.detailLevel === 'standard') {
      return this.summarizeForStorage(data);
    } else {
      return this.minimalSummary(data);
    }
  }

  private summarizeData(data: any): string {
    if (data === null || data === undefined) return 'null';
    if (typeof data === 'string') {
      return data.length > 100 ? data.slice(0, 100) + '...' : data;
    }
    if (typeof data === 'number' || typeof data === 'boolean') {
      return data.toString();
    }
    if (Array.isArray(data)) {
      if (data.length === 0) return '[]';
      if (data.length <= 3) return JSON.stringify(data);
      return `[${data.slice(0, 3).map(i => typeof i === 'string' ? i : JSON.stringify(i)).join(', ')}, ...+${data.length - 3}]`;
    }
    if (typeof data === 'object') {
      const keys = Object.keys(data);
      if (keys.length === 0) return '{}';
      if (keys.length <= 3) {
        return '{' + keys.map(k => `${k}: ${typeof data[k] === 'string' ? data[k].slice(0, 20) + (data[k].length > 20 ? '...' : '') : JSON.stringify(data[k])}`).join(', ') + '}';
      }
      return `{${keys.slice(0, 3).join(', ')}, ...+${keys.length - 3} keys}`;
    }
    return String(data);
  }

  private summarizeForStorage(data: any): any {
    if (typeof data === 'string' && data.length > 500) {
      return data.slice(0, 500) + '...[truncated]';
    }
    if (Array.isArray(data) && data.length > 10) {
      return [...data.slice(0, 10), `...[${data.length - 10} more items]`];
    }
    return data;
  }

  private minimalSummary(data: any): any {
    if (typeof data === 'string' && data.length > 100) {
      return data.slice(0, 100) + '...[truncated]';
    }
    if (Array.isArray(data) && data.length > 3) {
      return [...data.slice(0, 3), `...[${data.length - 3} more items]`];
    }
    return data;
  }

  private generateSummary(entries: AuditEntry[], avgConfidence: number, lowConfidenceSteps: number): {
    analysisQuality: 'excellent' | 'good' | 'fair' | 'poor';
    keyInsights: string[];
    potentialIssues: string[];
  } {
    let analysisQuality: 'excellent' | 'good' | 'fair' | 'poor';
    if (avgConfidence >= 85 && lowConfidenceSteps === 0) {
      analysisQuality = 'excellent';
    } else if (avgConfidence >= 70 && lowConfidenceSteps <= 1) {
      analysisQuality = 'good';
    } else if (avgConfidence >= 60 && lowConfidenceSteps <= 3) {
      analysisQuality = 'fair';
    } else {
      analysisQuality = 'poor';
    }

    const keyInsights: string[] = [];
    const embeddingsUsed = entries.some(e => e.action === 'embeddings-search');
    if (embeddingsUsed) {
      keyInsights.push('Semantische Suche wurde erfolgreich eingesetzt');
    }

    const toolSelectionEntries = entries.filter(e => e.action === 'ai-tool-selection');
    if (toolSelectionEntries.length > 0) {
      const avgSelectionConfidence = toolSelectionEntries.reduce((sum, e) => sum + e.confidence, 0) / toolSelectionEntries.length;
      if (avgSelectionConfidence >= 80) {
        keyInsights.push('Hohe Konfidenz bei der Tool-Auswahl');
      }
    }

    const potentialIssues: string[] = [];
    if (lowConfidenceSteps > 2) {
      potentialIssues.push(`${lowConfidenceSteps} Analyseschritte mit niedriger Konfidenz`);
    }

    const longSteps = entries.filter(e => e.processingTimeMs > 5000);
    if (longSteps.length > 0) {
      potentialIssues.push(`${longSteps.length} Schritte benötigten mehr als 5 Sekunden`);
    }

    return {
      analysisQuality,
      keyInsights,
      potentialIssues
    };
  }

  getActionDisplayName(action: string): string {
    return this.actionTranslations[action] || action;
  }

  formatDuration(ms: number): string {
    if (ms < 1000) return '< 1s';
    if (ms < 60000) return `${Math.ceil(ms / 1000)}s`;
    const minutes = Math.floor(ms / 60000);
    const seconds = Math.ceil((ms % 60000) / 1000);
    return seconds > 0 ? `${minutes}m ${seconds}s` : `${minutes}m`;
  }

  getConfidenceColor(confidence: number): string {
    if (confidence >= 80) return 'var(--color-accent)';
    if (confidence >= 60) return 'var(--color-warning)';
    return 'var(--color-error)';
  }

  isEnabled(): boolean {
    return this.enabled;
  }

  getConfig(): typeof config.audit {
    return config.audit;
  }
}

export const auditService = new AuditService();