// src/utils/auditService.ts 
import 'dotenv/config';

function env(key: string, fallback: string | undefined = undefined): string | undefined {
  if (typeof process !== 'undefined' && process.env?.[key] !== undefined) {
    return process.env[key];
  }
  if (typeof import.meta !== 'undefined' && (import.meta as any).env?.[key] !== undefined) {
    return (import.meta as any).env[key];
  }
  return fallback;
}

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

interface AuditConfig {
  enabled: boolean;
  detailLevel: 'minimal' | 'standard' | 'verbose';
  retentionHours: number;
  maxEntries: number;
}

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

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 config: AuditConfig;
  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.config = this.loadConfig();
  }

  private loadConfig(): AuditConfig {
    // Use the env() helper function that handles both server and client contexts
    const enabledFlag = env('FORENSIC_AUDIT_ENABLED', 'false');
    const detailLevel = env('FORENSIC_AUDIT_DETAIL_LEVEL', 'standard') as 'minimal' | 'standard' | 'verbose';
    const retentionHours = parseInt(env('FORENSIC_AUDIT_RETENTION_HOURS', '72') || '72', 10);
    const maxEntries = parseInt(env('FORENSIC_AUDIT_MAX_ENTRIES', '50') || '50', 10);

    console.log('[AUDIT SERVICE] Configuration loaded:', {
      enabled: enabledFlag === 'true',
      detailLevel,
      retentionHours,
      maxEntries,
      context: typeof process !== 'undefined' ? 'server' : 'client'
    });

    return {
      enabled: enabledFlag === 'true',
      detailLevel,
      retentionHours,
      maxEntries
    };
  }

  getDebugInfo(): {
    config: AuditConfig;
    environment: Record<string, any>;
    context: string;
  } {
    const context = typeof process !== 'undefined' ? 'server' : 'client';
    
    return {
      config: this.config,
      environment: {
        FORENSIC_AUDIT_ENABLED: env('FORENSIC_AUDIT_ENABLED'),
        FORENSIC_AUDIT_DETAIL_LEVEL: env('FORENSIC_AUDIT_DETAIL_LEVEL'),
        FORENSIC_AUDIT_RETENTION_HOURS: env('FORENSIC_AUDIT_RETENTION_HOURS'),
        FORENSIC_AUDIT_MAX_ENTRIES: env('FORENSIC_AUDIT_MAX_ENTRIES'),
        processEnvKeys: typeof process !== 'undefined' ? Object.keys(process.env).filter(k => k.includes('AUDIT')) : [],
        importMetaEnvAvailable: typeof import.meta !== 'undefined' && !!(import.meta as any).env
      },
      context
    };
  }

  addEntry(
    phase: string,
    action: string,
    input: any,
    output: any,
    confidence: number,
    startTime: number,
    metadata: Record<string, any> = {}
  ): void {
    if (!this.config.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);
    console.log(`[AUDIT] ${phase}/${action}: ${confidence}% confidence, ${entry.processingTimeMs}ms`);
  }


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

    auditTrail.unshift(...this.tempEntries);
    const entryCount = this.tempEntries.length;
    this.tempEntries = [];
    
    console.log(`[AUDIT] Merged ${entryCount} entries into audit trail`);
  }


  processAuditTrail(rawAuditTrail: AuditEntry[]): ProcessedAuditTrail | null {
    if (!this.config.enabled) {
        console.log('[AUDIT] Service disabled, returning null');
        return null;
    }
    
    if (!rawAuditTrail || !Array.isArray(rawAuditTrail) || rawAuditTrail.length === 0) {
        console.log('[AUDIT] No audit trail data provided');
        return null;
    }

    try {
        console.log('[AUDIT] Processing', rawAuditTrail.length, 'audit entries');

        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
        };

        console.log('[AUDIT] Successfully processed audit trail:', result);
        return result;
        
    } catch (error) {
        console.error('[AUDIT] Error processing audit trail:', error);
        return null;
    }
  }

  private compressEntry(entry: AuditEntry): CompressedAuditEntry | null {
    if (!entry || typeof entry !== 'object') {
        console.warn('[AUDIT] 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) {
        console.error('[AUDIT] Error compressing entry:', error);
        return null;
    }
  }

  private compressData(data: any): any {
    if (this.config.detailLevel === 'verbose') {
      return data; 
    } else if (this.config.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.config.enabled;
  }

  getConfig(): AuditConfig {
    return { ...this.config };
  }
}

export const auditService = new AuditService();
export type { ProcessedAuditTrail, CompressedAuditEntry };
// Add this at the bottom of auditService.ts (after the existing exports)

// Export debug utilities for troubleshooting
export const debugAuditService = {
  getDebugInfo() {
    return auditService.getDebugInfo();
  },
  isEnabled() {
    return auditService.isEnabled();
  },
  getConfig() {
    return auditService.getConfig();
  }
};