// src/utils/aiPipeline.ts
import { getCompressedToolsDataForAI, getDataVersion } from './dataService.js';
import { aiService } from './aiService.js';
import { toolSelector, type SelectionContext } from './toolSelector.js';
import { confidenceScoring, type AnalysisContext } from './confidenceScoring.js';
import { embeddingsService } from './embeddings.js';
import { auditService } from './auditService.js';
import { JSONParser } from './jsonUtils.js';
import { getPrompt } from '../config/prompts.js';

interface PipelineConfig {
  microTaskDelay: number;
  taskRelevanceModeration: {
    maxInitialScore: number;
    maxWithPhaseBonus: number;
    moderationThreshold: number;
  };
}

interface MicroTaskResult {
  taskType: string;
  content: string;
  processingTimeMs: number;
  success: boolean;
  error?: string;
  aiUsage?: {
    promptTokens?: number;
    completionTokens?: number;
    totalTokens?: number;
  };
}

interface AnalysisResult {
  recommendation: any;
  processingStats: {
    candidatesFromEmbeddings: number;
    finalSelectedItems: number;
    processingTimeMs: number;
    microTasksCompleted: number;
    microTasksFailed: number;
    contextContinuityUsed: boolean;
    totalAITokensUsed: number;
    auditEntriesGenerated: number;
    aiModel: string;
    toolsDataHash: string;
    temperature: number;
    maxTokensUsed: number;
  };
}

interface PipelineContext {
  userQuery: string;
  mode: string;
  filteredData: any;
  contextHistory: string[];
  currentContextLength: number;
  scenarioAnalysis?: string;
  problemAnalysis?: string;
  investigationApproach?: string;
  criticalConsiderations?: string;
  selectedTools?: Array<{
    tool: any;
    phase: string;
    priority: string;
    justification?: string;
    taskRelevance?: number;
    limitations?: string[];
  }>;
  backgroundKnowledge?: Array<{
    concept: any;
    relevance: string;
  }>;
  seenToolNames: Set<string>;
  embeddingsSimilarities: Map<string, number>;
  phaseMetadata?: {
    phases: any[];
    criticalPhaseIds: string[];
    phaseComplexity: Map<string, number>;
  };
}

class AIPipeline {
  private config: PipelineConfig;
  private totalTokensUsed: number = 0;

  constructor() {
    this.config = {
      microTaskDelay: parseInt(process.env.AI_MICRO_TASK_DELAY_MS || '500', 10),
      taskRelevanceModeration: {
        maxInitialScore: 85,
        maxWithPhaseBonus: 95,
        moderationThreshold: 80
      }
    };
  }

  async processQuery(userQuery: string, mode: string): Promise<AnalysisResult> {
    const startTime = Date.now();
    let completedTasks = 0;
    let failedTasks = 0;
    this.totalTokensUsed = 0;

    auditService.clearAuditTrail();

    try {
      const toolsData = await getCompressedToolsDataForAI();
      const aiConfig = aiService.getConfig();
      const toolsDataHash = getDataVersion?.() || 'unknown';
      
      auditService.addEntry(
        'initialization',
        'tools-data-loaded',
        { 
          toolsFile: 'tools.yaml',
          hashAlgorithm: 'SHA256'
        },
        { 
          toolsDataHash: toolsDataHash,
          toolsCount: toolsData.tools.length,
          conceptsCount: toolsData.concepts.length,
          domainsCount: toolsData.domains.length,
          phasesCount: toolsData.phases.length
        },
        100,
        Date.now(),
        {
          toolsDataHash: toolsDataHash,
          verification: `Users can verify with: sha256sum src/data/tools.yaml`,
          dataVersion: toolsDataHash.slice(0, 12),
          reasoning: `Geladen: ${toolsData.tools.length} Tools, ${toolsData.concepts.length} Konzepte aus tools.yaml (Hash: ${toolsDataHash.slice(0, 12)}...)`
        }
      );
      
      const context: PipelineContext = {
        userQuery,
        mode,
        filteredData: {},
        contextHistory: [],
        currentContextLength: 0,
        seenToolNames: new Set<string>(),
        embeddingsSimilarities: new Map<string, number>(),
        phaseMetadata: this.initializePhaseMetadata(toolsData.phases)
      };

      const candidateSelectionStart = Date.now();
      const candidateData = await toolSelector.getIntelligentCandidates(userQuery, toolsData, mode, context);
      
      const selectionConfidence = this.calculateToolSelectionConfidence(
        candidateData.tools.length,
        toolsData.tools.length,
        candidateData.concepts.length
      );
      
      auditService.addToolSelection(
        candidateData.tools.map(t => t.name),
        toolsData.tools.map(t => t.name),
        selectionConfidence,
        candidateSelectionStart,
        {
          toolsDataHash: toolsDataHash,
          totalCandidatesFound: candidateData.tools.length + candidateData.concepts.length,
          reductionRatio: candidateData.tools.length / toolsData.tools.length
        }
      );
      
      context.filteredData = candidateData;

      const analysisResult = await this.analyzeScenario(context, startTime, toolsDataHash);
      if (analysisResult.success) completedTasks++; else failedTasks++;
      this.trackTokenUsage(analysisResult.aiUsage);
      await this.delay(this.config.microTaskDelay);

      const approachResult = await this.generateApproach(context, startTime, toolsDataHash);
      if (approachResult.success) completedTasks++; else failedTasks++;
      this.trackTokenUsage(approachResult.aiUsage);
      await this.delay(this.config.microTaskDelay);

      const considerationsResult = await this.generateCriticalConsiderations(context, startTime, toolsDataHash);
      if (considerationsResult.success) completedTasks++; else failedTasks++;
      this.trackTokenUsage(considerationsResult.aiUsage);
      await this.delay(this.config.microTaskDelay);

      if (mode === 'workflow') {
        const workflowResults = await this.processWorkflowMode(context, toolsData, completedTasks, failedTasks, startTime, toolsDataHash);
        completedTasks = workflowResults.completed;
        failedTasks = workflowResults.failed;
      } else {
        const toolResults = await this.processToolMode(context, completedTasks, failedTasks, startTime, toolsDataHash);
        completedTasks = toolResults.completed;
        failedTasks = toolResults.failed;
      }

      const knowledgeResult = await this.selectBackgroundKnowledge(context, startTime, toolsDataHash);
      if (knowledgeResult.success) completedTasks++; else failedTasks++;
      this.trackTokenUsage(knowledgeResult.aiUsage);
      await this.delay(this.config.microTaskDelay);

      const finalResult = await this.generateFinalRecommendations(context, startTime, toolsDataHash);
      if (finalResult.success) completedTasks++; else failedTasks++;
      this.trackTokenUsage(finalResult.aiUsage);

      const recommendation = this.buildRecommendation(context, mode, finalResult.content, toolsDataHash);

      const processingStats = {
        candidatesFromEmbeddings: candidateData.tools.length,
        finalSelectedItems: (context.selectedTools?.length || 0) + (context.backgroundKnowledge?.length || 0),
        processingTimeMs: Date.now() - startTime,
        microTasksCompleted: completedTasks,
        microTasksFailed: failedTasks,
        contextContinuityUsed: true,
        totalAITokensUsed: this.totalTokensUsed,
        auditEntriesGenerated: auditService.getCurrentAuditTrail().length,
        aiModel: aiConfig.model,
        toolsDataHash,
        temperature: 0.3,
        maxTokensUsed: 32768
      };

      const finalAuditTrail = auditService.finalizeAuditTrail();

      return {
        recommendation: {
          ...recommendation,
          auditTrail: auditService.isEnabled() ? finalAuditTrail : undefined,
          processingStats
        },
        processingStats
      };

    } catch (error) {
      console.error('[AI-PIPELINE] Pipeline failed:', error);
      throw error;
    }
  }

  private initializePhaseMetadata(phases: any[]): {
    phases: any[];
    criticalPhaseIds: string[];
    phaseComplexity: Map<string, number>;
  } {
    if (!phases || !Array.isArray(phases)) {
      return {
        phases: [],
        criticalPhaseIds: [],
        phaseComplexity: new Map()
      };
    }

    const criticalPhaseIds = phases
      .filter(phase => {
        const typicalToolsCount = phase.typical_tools?.length || 0;
        const keyActivitiesCount = phase.key_activities?.length || 0;
        return typicalToolsCount >= 3 || keyActivitiesCount >= 2;
      })
      .map(phase => phase.id);

    const phaseComplexity = new Map<string, number>();
    phases.forEach(phase => {
      let complexity = 1;
      if (phase.typical_tools?.length > 5) complexity += 1;
      if (phase.key_activities?.length > 3) complexity += 1;
      if (phase.description?.length > 100) complexity += 1;
      phaseComplexity.set(phase.id, complexity);
    });

    return {
      phases,
      criticalPhaseIds,
      phaseComplexity
    };
  }

  private calculateToolSelectionConfidence(
    selectedCount: number,
    totalCount: number,
    conceptsCount: number
  ): number {
    let confidence = 50;
    const selectionRatio = selectedCount / totalCount;
    
    if (selectionRatio >= 0.05 && selectionRatio <= 0.20) {
      confidence += 25;
    } else if (selectionRatio < 0.05) {
      confidence += 15;
    } else if (selectionRatio > 0.30) {
      confidence -= 15;
    }
    
    if (conceptsCount > 0) confidence += 10;
    if (selectedCount >= 8 && selectedCount <= 25) confidence += 10;
    
    return Math.min(95, Math.max(40, confidence));
  }

  private async processWorkflowMode(
    context: PipelineContext, 
    toolsData: any, 
    completedTasks: number, 
    failedTasks: number,
    pipelineStart: number,
    toolsDataHash: string
  ): Promise<{ completed: number; failed: number }> {
    const phases = toolsData.phases || [];
    
    for (const phase of phases) {
      const phaseStart = Date.now();
      const phaseTools = context.filteredData.tools.filter((tool: any) =>
        tool && tool.phases && Array.isArray(tool.phases) && tool.phases.includes(phase.id)
      );
      
      if (phaseTools.length === 0) continue;
      
      const selections = await toolSelector.selectToolsForPhase(context.userQuery, phase, phaseTools, context);
      
      const phaseConfidence = this.calculatePhaseSelectionConfidence(
        selections.length,
        phaseTools.length,
        phase.id,
        selections,
        context.phaseMetadata
      );
      
      auditService.addEntry(
        'workflow-phase',
        'phase-tool-selection',
        { 
          phaseId: phase.id, 
          phaseName: phase.name, 
          availableTools: phaseTools.map(t => t.name),
          toolCount: phaseTools.length
        },
        { 
          selectedTools: selections.map(s => s.toolName),
          selectionCount: selections.length,
          avgTaskRelevance: selections.length > 0 ? 
            Math.round(selections.reduce((sum, s) => sum + (s.taskRelevance || 70), 0) / selections.length) : 0
        },
        phaseConfidence,
        phaseStart,
        {
          toolsDataHash: toolsDataHash,
          phaseId: phase.id,
          availableToolsCount: phaseTools.length,
          selectedToolsCount: selections.length,
          microTaskType: 'phase-tool-selection',
          reasoning: `${selections.length} von ${phaseTools.length} verfügbaren Tools für ${phase.name} ausgewählt - KI bewertete Eignung für spezifische Phasenaufgaben`
        }
      );
      
      selections.forEach((sel: any) => {
        const tool = phaseTools.find((t: any) => t && t.name === sel.toolName);
        if (tool) {
          const moderatedTaskRelevance = this.moderateTaskRelevance(sel.taskRelevance);
          const priority = this.derivePriorityFromScore(moderatedTaskRelevance);
          const dynamicLimitations = this.generateDynamicLimitations(tool, phase, sel);
          
          this.addToolToSelection(context, tool, phase.id, priority, sel.justification, moderatedTaskRelevance, dynamicLimitations);
          
          auditService.addEntry(
            'tool-reasoning',
            'tool-added-to-phase',
            { 
              toolName: tool.name, 
              phaseId: phase.id, 
              taskRelevance: moderatedTaskRelevance,
              priority: priority
            },
            { 
              justification: sel.justification, 
              limitations: dynamicLimitations,
              addedToPhase: phase.name
            },
            moderatedTaskRelevance || 70,
            phaseStart,
            {
              toolsDataHash: toolsDataHash,
              toolType: tool.type,
              priority,
              moderationApplied: sel.taskRelevance !== moderatedTaskRelevance,
              reasoning: `${tool.name} als ${priority}-Priorität für ${phase.name} ausgewählt: ${sel.justification?.slice(0, 100)}...`
            }
          );
        }
      });
      
      if (selections.length > 0) completedTasks++; else failedTasks++;
      await this.delay(this.config.microTaskDelay);
    }
    
    const completionResult = await this.completeUnderrepresentedPhases(context, toolsData, pipelineStart, toolsDataHash);
    completedTasks += completionResult.completed;
    failedTasks += completionResult.failed;
    
    return { completed: completedTasks, failed: failedTasks };
  }

  private calculatePhaseSelectionConfidence(
    selectedCount: number,
    availableCount: number,
    phaseId: string,
    selections: any[],
    phaseMetadata?: {
      phases: any[];
      criticalPhaseIds: string[];
      phaseComplexity: Map<string, number>;
    }
  ): number {
    let confidence = 60;
    const isCritical = phaseMetadata?.criticalPhaseIds.includes(phaseId) || false;
    const phaseComplexity = phaseMetadata?.phaseComplexity.get(phaseId) || 1;
    
    if (selectedCount > 0) {
      confidence += 20;
    } else {
      return 30;
    }
    
    const ratio = selectedCount / availableCount;
    if (ratio >= 0.2 && ratio <= 0.5) {
      confidence += 15;
    } else if (ratio < 0.2 && selectedCount >= 1) {
      confidence += 10;
    }
    
    if (isCritical && selectedCount >= 2) confidence += 10;
    if (phaseComplexity > 2 && selectedCount >= phaseComplexity) confidence += 5;
    
    const avgRelevance = selections.length > 0 ? 
      selections.reduce((sum, s) => sum + (s.taskRelevance || 70), 0) / selections.length : 0;
    
    if (avgRelevance >= 75) {
      confidence += 10;
    } else if (avgRelevance >= 65) {
      confidence += 5;
    }
    
    return Math.min(95, Math.max(30, confidence));
  }

  private generateDynamicLimitations(tool: any, phase: any, selection: any): string[] {
    const limitations: string[] = [];
    
    if (selection.limitations && Array.isArray(selection.limitations)) {
      limitations.push(...selection.limitations);
    }
    
    if (tool.type === 'software' && !tool.projectUrl) {
      limitations.push('Installation und Konfiguration erforderlich');
    }
    
    if (tool.skillLevel === 'expert') {
      limitations.push('Erfordert spezialisierte Kenntnisse');
    }
    
    if (tool.license === 'Proprietary') {
      limitations.push('Kommerzielle Lizenz erforderlich');
    }
    
    if (phase.id === 'acquisition' && tool.type === 'method') {
      limitations.push('Sorgfältige Dokumentation für Chain of Custody erforderlich');
    }
    
    return limitations.slice(0, 3);
  }

  private async processToolMode(
    context: PipelineContext, 
    completedTasks: number, 
    failedTasks: number,
    pipelineStart: number,
    toolsDataHash: string
  ): Promise<{ completed: number; failed: number }> {
    const candidates = context.filteredData.tools || [];
    if (!Array.isArray(candidates) || candidates.length === 0) {
      return { completed: completedTasks, failed: failedTasks };
    }

    for (let i = 0; i < candidates.length; i++) {
      const evaluationResult = await this.evaluateSpecificTool(context, candidates[i], i + 1, pipelineStart, toolsDataHash);
      if (evaluationResult.success) completedTasks++; else failedTasks++;
      this.trackTokenUsage(evaluationResult.aiUsage);
      await this.delay(this.config.microTaskDelay);
    }

    if (Array.isArray(context.selectedTools) && context.selectedTools.length > 0) {
      context.selectedTools.sort((a: any, b: any) => {
        const ar = typeof a.taskRelevance === 'number' ? a.taskRelevance : -1;
        const br = typeof b.taskRelevance === 'number' ? b.taskRelevance : -1;
        if (br !== ar) return br - ar;

        const aLen = (a.justification || '').length;
        const bLen = (b.justification || '').length;
        if (bLen !== aLen) return bLen - aLen;

        const aRank = a.tool?.evaluation?.rank ?? Number.MAX_SAFE_INTEGER;
        const bRank = b.tool?.evaluation?.rank ?? Number.MAX_SAFE_INTEGER;
        return aRank - bRank;
      });

      context.selectedTools = context.selectedTools.slice(0, 3);
    }

    return { completed: completedTasks, failed: failedTasks };
  }

  private async completeUnderrepresentedPhases(
    context: PipelineContext, 
    toolsData: any, 
    pipelineStart: number,
    toolsDataHash: string
  ): Promise<{ completed: number; failed: number }> {
    const phases = toolsData.phases || [];
    const selectedPhases = new Map<string, number>();
    let completedTasks = 0;
    let failedTasks = 0;
    
    context.selectedTools?.forEach((st: any) => {
      const count = selectedPhases.get(st.phase) || 0;
      selectedPhases.set(st.phase, count + 1);
    });
    
    const underrepresentedPhases = phases.filter((phase: any) => {
      const count = selectedPhases.get(phase.id) || 0;
      return count <= 1;
    });
    
    if (underrepresentedPhases.length === 0) return { completed: 0, failed: 0 };
    
    for (const phase of underrepresentedPhases) {
      const result = await this.completePhaseWithSemanticSearchAndAI(context, phase, toolsData, pipelineStart, toolsDataHash);
      if (result.success) completedTasks++; else failedTasks++;
      await this.delay(this.config.microTaskDelay);
    }
    
    return { completed: completedTasks, failed: failedTasks };
  }

  private async completePhaseWithSemanticSearchAndAI(
    context: PipelineContext, 
    phase: any, 
    toolsData: any, 
    pipelineStart: number,
    toolsDataHash: string
  ): Promise<MicroTaskResult> {
    const phaseStart = Date.now();
    const phaseQuery = `forensic ${phase.name.toLowerCase()} tools methods`;
    
    try {
      const phaseResults = await embeddingsService.findSimilar(phaseQuery, 20, 0.2);
      
      auditService.addEmbeddingsSearch(
        phaseQuery,
        phaseResults,
        0.2,
        phaseStart,
        {
          toolsDataHash: toolsDataHash,
          phaseId: phase.id,
          phaseName: phase.name,
          completionPurpose: 'underrepresented-phase-enhancement'
        }
      );
      
      if (phaseResults.length === 0) {
        return {
          taskType: 'phase-completion',
          content: '',
          processingTimeMs: Date.now() - phaseStart,
          success: true
        };
      }
      
      const toolsMap = new Map(toolsData.tools.map((tool: any) => [tool.name, tool]));
      const conceptsMap = new Map(toolsData.concepts.map((concept: any) => [concept.name, concept]));
      
      const phaseTools = phaseResults
        .filter((result: any) => result.type === 'tool')
        .map((result: any) => toolsMap.get(result.name))
        .filter((tool: any): tool is NonNullable<any> =>
          tool !== undefined &&
          tool !== null &&
          tool.phases &&
          Array.isArray(tool.phases) &&
          tool.phases.includes(phase.id) &&
          !context.seenToolNames.has(tool.name)
        )
        .slice(0, 5);
      
      const phaseConcepts = phaseResults
        .filter((result: any) => result.type === 'concept')
        .map((result: any) => conceptsMap.get(result.name))
        .filter((concept: any): concept is NonNullable<any> => concept !== undefined && concept !== null)
        .slice(0, 2);
      
      if (phaseTools.length === 0) {
        return {
          taskType: 'phase-completion',
          content: '',
          processingTimeMs: Date.now() - phaseStart,
          success: true
        };
      }
      
      const selectionPrompt = getPrompt('generatePhaseCompletionPrompt', context.userQuery, phase, phaseTools, phaseConcepts);
      const selectionResult = await this.callMicroTaskAI(selectionPrompt, context, 'phase-completion-selection');
      
      if (!selectionResult.success) {
        return {
          taskType: 'phase-completion',
          content: '',
          processingTimeMs: Date.now() - phaseStart,
          success: false,
          error: 'Selection micro-task failed'
        };
      }
      
      const selection = JSONParser.safeParseJSON(selectionResult.content, { 
        selectedTools: [], 
        selectedConcepts: [],
        completionReasoning: ''
      });
      
      const validTools = selection.selectedTools
        .map((name: string) => phaseTools.find((t: any) => t && t.name === name))
        .filter((tool: any): tool is NonNullable<any> => tool !== undefined && tool !== null)
        .slice(0, 2);
      
      if (validTools.length === 0) {
        return {
          taskType: 'phase-completion',
          content: selection.completionReasoning || '',
          processingTimeMs: Date.now() - phaseStart,
          success: true
        };
      }
      
      const actualToolsAdded = validTools.map(tool => tool.name);
      
      for (const tool of validTools) {
        const reasoningPrompt = getPrompt(
          'phaseCompletionReasoning',
          context.userQuery,
          phase,
          tool.name,
          tool,
          selection.completionReasoning || 'Nachergänzung zur Vervollständigung der Phasenabdeckung'
        );
        
        const reasoningResult = await this.callMicroTaskAI(reasoningPrompt, context, 'phase-completion-reasoning');
        
        let detailedJustification: string;
        let moderatedTaskRelevance = 75;
        
        if (reasoningResult.success && reasoningResult.content.trim()) {
          detailedJustification = reasoningResult.content.trim();
          moderatedTaskRelevance = this.moderateTaskRelevance(80);
        } else {
          detailedJustification = `Nachträglich hinzugefügt zur Vervollständigung der ${phase.name}-Phase. Die ursprüngliche KI-Auswahl war zu spezifisch und hat wichtige Tools für diese Phase übersehen.`;
          moderatedTaskRelevance = this.moderateTaskRelevance(75);
        }
        
        const dynamicLimitations = this.generateCompletionLimitations(tool, phase, selection);
        
        this.addToolToSelection(
          context,
          tool,
          phase.id,
          'medium',
          detailedJustification,
          moderatedTaskRelevance,
          dynamicLimitations
        );
      }
      
      auditService.addPhaseCompletion(
        phase.id,
        actualToolsAdded,
        selection.completionReasoning || `${actualToolsAdded.length} Tools für ${phase.name} hinzugefügt`,
        phaseStart,
        {
          toolsDataHash: toolsDataHash,
          toolsAdded: actualToolsAdded,
          toolType: validTools[0]?.type,
          semanticSimilarity: phaseResults.find(r => r.name === validTools[0]?.name)?.similarity,
          completionReason: 'underrepresented-phase',
          originalSelectionMissed: true,
          aiReasoningUsed: true,
          moderatedTaskRelevance: 75
        }
      );
      
      return {
        taskType: 'phase-completion',
        content: selection.completionReasoning || '',
        processingTimeMs: Date.now() - phaseStart,
        success: true
      };
      
    } catch (error) {
      return {
        taskType: 'phase-completion',
        content: '',
        processingTimeMs: Date.now() - phaseStart,
        success: false,
        error: error.message
      };
    }
  }

  private generateCompletionLimitations(tool: any, phase: any, selection: any): string[] {
    const limitations: string[] = [];
    
    limitations.push('Nachträgliche Ergänzung - ursprünglich nicht als Hauptmethode identifiziert');
    
    if (tool.skillLevel === 'expert') {
      limitations.push('Erfordert Expertenwissen für optimale Nutzung');
    }
    
    if (tool.type === 'software' && !tool.projectUrl) {
      limitations.push('Zusätzliche Setup-Zeit erforderlich');
    }
    
    if (phase.typical_tools && !phase.typical_tools.includes(tool.name)) {
      limitations.push(`Nicht typisch für ${phase.name}-Phase - alternative Anwendung`);
    }
    
    return limitations.slice(0, 3);
  }

  private moderateTaskRelevance(taskRelevance: number): number {
    if (typeof taskRelevance !== 'number') return 70;
    
    let moderated = Math.min(taskRelevance, this.config.taskRelevanceModeration.maxInitialScore);
    
    if (moderated > this.config.taskRelevanceModeration.moderationThreshold) {
      const excess = moderated - this.config.taskRelevanceModeration.moderationThreshold;
      moderated = this.config.taskRelevanceModeration.moderationThreshold + (excess * 0.7);
    }
    
    return Math.round(Math.min(moderated, this.config.taskRelevanceModeration.maxInitialScore));
  }

  private async analyzeScenario(context: PipelineContext, pipelineStart: number, toolsDataHash: string): Promise<MicroTaskResult> {
    const taskStart = Date.now();
    const isWorkflow = context.mode === 'workflow';
    const prompt = getPrompt('scenarioAnalysis', isWorkflow, context.userQuery);

    const result = await this.callMicroTaskAI(prompt, context, 'scenario-analysis');
    
    if (result.success) {
      if (isWorkflow) {
        context.scenarioAnalysis = result.content;
      } else {
        context.problemAnalysis = result.content;
      }
      
      this.addToContextHistory(context, `${isWorkflow ? 'Szenario' : 'Problem'}-Analyse: ${result.content.slice(0, 200)}...`);
      
      const confidence = auditService.calculateAIResponseConfidence(
        result.content,
        { min: 50, max: 300 },
        'scenario-analysis'
      );
      
      auditService.addAIDecision(
        'contextual-analysis',
        prompt,
        result.content,
        confidence,
        `Analysierte ${isWorkflow ? 'Szenario' : 'Problem'} basierend auf Nutzereingabe: "${context.userQuery.slice(0, 100)}..." - Identifizierte Kernaspekte und Herausforderungen für Untersuchung`,
        taskStart,
        {
          toolsDataHash: toolsDataHash,
          microTaskType: 'scenario-analysis',
          analysisType: isWorkflow ? 'scenario' : 'problem',
          contentLength: result.content.length,
          decisionBasis: 'ai-analysis',
          aiModel: aiService.getConfig().model,
          ...result.aiUsage
        }
      );
    }
    
    return result;
  }

  private async generateApproach(context: PipelineContext, pipelineStart: number, toolsDataHash: string): Promise<MicroTaskResult> {
    const taskStart = Date.now();
    const isWorkflow = context.mode === 'workflow';
    const prompt = getPrompt('investigationApproach', isWorkflow, context.userQuery);

    const result = await this.callMicroTaskAI(prompt, context, 'investigation-approach');
    
    if (result.success) {
      context.investigationApproach = result.content;
      this.addToContextHistory(context, `${isWorkflow ? 'Untersuchungs' : 'Lösungs'}ansatz: ${result.content.slice(0, 200)}...`);
      
      const confidence = auditService.calculateAIResponseConfidence(
        result.content,
        { min: 50, max: 300 },
        'investigation-approach'
      );
      
      auditService.addAIDecision(
        'contextual-analysis',
        prompt,
        result.content,
        confidence,
        `Entwickelte ${isWorkflow ? 'Untersuchungs' : 'Lösungs'}ansatz unter Berücksichtigung der Szenario-Analyse - Strukturierte Herangehensweise für forensische Methodik`,
        taskStart,
        {
          toolsDataHash: toolsDataHash,
          microTaskType: 'investigation-approach',
          approachType: isWorkflow ? 'investigation' : 'solution',
          contentLength: result.content.length,
          contextHistoryLength: context.contextHistory.length,
          decisionBasis: 'ai-analysis',
          aiModel: aiService.getConfig().model,
          ...result.aiUsage
        }
      );
    }
    
    return result;
  }

  private async generateCriticalConsiderations(context: PipelineContext, pipelineStart: number, toolsDataHash: string): Promise<MicroTaskResult> {
    const taskStart = Date.now();
    const isWorkflow = context.mode === 'workflow';
    const prompt = getPrompt('criticalConsiderations', isWorkflow, context.userQuery);

    const result = await this.callMicroTaskAI(prompt, context, 'critical-considerations');
    
    if (result.success) {
      context.criticalConsiderations = result.content;
      this.addToContextHistory(context, `Kritische Überlegungen: ${result.content.slice(0, 200)}...`);
      
      const confidence = auditService.calculateAIResponseConfidence(
        result.content,
        { min: 40, max: 250 },
        'critical-considerations'
      );
      
      auditService.addAIDecision(
        'contextual-analysis',
        prompt,
        result.content,
        confidence,
        'Identifizierte kritische Überlegungen für forensische Untersuchung - Berücksichtigung von Beweissicherung, Chain of Custody und methodischen Herausforderungen',
        taskStart,
        {
          toolsDataHash: toolsDataHash,
          microTaskType: 'critical-considerations',
          contentLength: result.content.length,
          decisionBasis: 'ai-analysis',
          aiModel: aiService.getConfig().model,
          ...result.aiUsage
        }
      );
    }
    
    return result;
  }

  private async evaluateSpecificTool(
    context: PipelineContext, 
    tool: any, 
    rank: number,
    pipelineStart: number,
    toolsDataHash: string
  ): Promise<MicroTaskResult> {
    const taskStart = Date.now();

    const prompt = getPrompt('toolEvaluation', context.userQuery, tool, rank);
    const result = await this.callMicroTaskAI(prompt, context, 'tool-evaluation');

    if (!result.success) {
      return result;
    }

    const evaluation = JSONParser.safeParseJSON(result.content, null);

    const aiProvided = evaluation && typeof evaluation.taskRelevance === 'number' && Number.isFinite(evaluation.taskRelevance)
      ? Math.round(evaluation.taskRelevance)
      : null;

    if (aiProvided === null) {
      auditService.addAIDecision(
        'tool-evaluation',
        prompt,
        result.content,
        0,
        `Bewertung für "${tool.name}" ignoriert: fehlender/ungültiger taskRelevance`,
        taskStart,
        {
          toolsDataHash,
          microTaskType: 'tool-evaluation',
          toolName: tool.name,
          toolType: tool.type,
          rank,
          evaluationParsed: false,
          decisionBasis: 'ai-analysis',
          aiModel: aiService.getConfig().model,
          ...(result.aiUsage || {})
        }
      );
      return result;
    }

    const moderatedTaskRelevance = this.moderateTaskRelevance(aiProvided);
    const priority = this.derivePriorityFromScore(moderatedTaskRelevance);

    const detailed_explanation = String(evaluation?.detailed_explanation || '').trim();
    const implementation_approach = String(evaluation?.implementation_approach || '').trim();
    const pros = Array.isArray(evaluation?.pros) ? evaluation.pros : [];
    const limitations = Array.isArray(evaluation?.limitations) ? evaluation.limitations : [];
    const alternatives = String(evaluation?.alternatives || '').trim();

    this.addToolToSelection(
      context,
      {
        ...tool,
        evaluation: {
          detailed_explanation,
          implementation_approach,
          pros,
          limitations,
          alternatives,
          rank,
          task_relevance: moderatedTaskRelevance
        }
      },
      'evaluation',
      priority,
      detailed_explanation,
      moderatedTaskRelevance,
      limitations
    );

    const responseConfidence = auditService.calculateAIResponseConfidence(
      result.content,
      { min: 200, max: 800 },
      'tool-evaluation'
    );

    const finalConfidence = Math.max(responseConfidence, moderatedTaskRelevance);

    auditService.addAIDecision(
      'tool-evaluation',
      prompt,
      result.content,
      finalConfidence,
      `Bewertete Tool "${tool.name}" (Rang ${rank}) – AI-Score ${aiProvided}, moderiert ${moderatedTaskRelevance}`,
      taskStart,
      {
        toolsDataHash,
        microTaskType: 'tool-evaluation',
        toolName: tool.name,
        toolType: tool.type,
        rank,
        aiProvidedTaskRelevance: aiProvided,
        moderatedTaskRelevance,
        responseConfidence,
        finalConfidence,
        moderationApplied: aiProvided !== moderatedTaskRelevance,
        evaluationParsed: true,
        prosCount: pros.length,
        limitationsCount: limitations.length,
        decisionBasis: 'ai-analysis',
        aiModel: aiService.getConfig().model,
        ...(result.aiUsage || {})
      }
    );

    return result;
  }

  private async selectBackgroundKnowledge(context: PipelineContext, pipelineStart: number, toolsDataHash: string): Promise<MicroTaskResult> {
    const taskStart = Date.now();
    const availableConcepts = context.filteredData.concepts;
    
    if (availableConcepts.length === 0) {
      return {
        taskType: 'background-knowledge',
        content: JSON.stringify([]),
        processingTimeMs: 0,
        success: true
      };
    }

    const selectedToolNames = context.selectedTools?.map((st: any) => st.tool && st.tool.name).filter(Boolean) || [];
    const prompt = getPrompt('backgroundKnowledgeSelection', context.userQuery, context.mode, selectedToolNames, availableConcepts);
    const result = await this.callMicroTaskAI(prompt, context, 'background-knowledge');
    
    if (result.success) {
      const selections = JSONParser.safeParseJSON(result.content, []);
      
      if (Array.isArray(selections)) {
        context.backgroundKnowledge = selections.filter((sel: any) =>
          sel.conceptName && availableConcepts.some((concept: any) => concept.name === sel.conceptName)
        ).map((sel: any) => ({
          concept: availableConcepts.find((c: any) => c.name === sel.conceptName),
          relevance: sel.relevance
        }));
        
        const responseConfidence = auditService.calculateAIResponseConfidence(
          result.content,
          { min: 100, max: 500 },
          'background-knowledge'
        );
        
        const selectionQualityBonus = this.calculateKnowledgeSelectionBonus(context.backgroundKnowledge, availableConcepts);
        const finalConfidence = Math.min(95, responseConfidence + selectionQualityBonus);
        
        auditService.addEntry(
          'knowledge-synthesis',
          'concept-selection',
          { 
            availableConcepts: availableConcepts.map(c => c.name),
            selectedToolsContext: selectedToolNames,
            selectionCriteria: 'methodische Fundierung'
          },
          { 
            selectedConcepts: context.backgroundKnowledge.map(bk => bk.concept.name),
            selectionReasonings: context.backgroundKnowledge.map(bk => bk.relevance)
          },
          finalConfidence,
          taskStart,
          {
            toolsDataHash: toolsDataHash,
            microTaskType: 'background-knowledge',
            availableConceptsCount: availableConcepts.length,
            selectedConceptsCount: context.backgroundKnowledge.length,
            selectionRatio: context.backgroundKnowledge.length / availableConcepts.length,
            responseConfidence,
            selectionQualityBonus,
            decisionBasis: 'ai-analysis',
            reasoning: `Wählte ${context.backgroundKnowledge.length} von ${availableConcepts.length} verfügbaren Konzepten für methodische Fundierung der Empfehlungen`,
            aiModel: aiService.getConfig().model,
            ...result.aiUsage
          }
        );
      }
    }
    
    return result;
  }

  private calculateKnowledgeSelectionBonus(
    selectedKnowledge: Array<{concept: any; relevance: string}>,
    availableConcepts: any[]
  ): number {
    let bonus = 0;
    
    if (selectedKnowledge.length > 0) bonus += 10;
    
    const ratio = selectedKnowledge.length / availableConcepts.length;
    if (ratio >= 0.1 && ratio <= 0.3) bonus += 15;
    
    const hasGoodReasonings = selectedKnowledge.some(bk => 
      bk.relevance && bk.relevance.length > 30
    );
    if (hasGoodReasonings) bonus += 10;
    
    return bonus;
  }

  private async generateFinalRecommendations(context: PipelineContext, pipelineStart: number, toolsDataHash: string): Promise<MicroTaskResult> {
    const taskStart = Date.now();
    const selectedToolNames = context.selectedTools?.map((st: any) => st.tool && st.tool.name).filter(Boolean) || [];
    const prompt = getPrompt('finalRecommendations', context.mode === 'workflow', context.userQuery, selectedToolNames);
    
    const result = await this.callMicroTaskAI(prompt, context, 'final-recommendations');
    
    if (result.success) {
      const confidence = auditService.calculateAIResponseConfidence(
        result.content,
        { min: 60, max: 250 },
        'final-recommendations'
      );
      
      const contextBonus = this.calculateSynthesisBonus(selectedToolNames, context);
      const finalConfidence = Math.min(95, confidence + contextBonus);
      
      auditService.addAIDecision(
        'synthesis',
        prompt,
        result.content,
        finalConfidence,
        `Generierte abschließende ${context.mode}-Empfehlungen basierend auf ausgewählten ${selectedToolNames.length} Tools - Synthese aller Analyseschritte zu kohärenter Handlungsempfehlung`,
        taskStart,
        {
          toolsDataHash: toolsDataHash,
          microTaskType: 'final-recommendations',
          mode: context.mode,
          selectedToolsCount: selectedToolNames.length,
          contentLength: result.content.length,
          responseConfidence: confidence,
          contextBonus,
          decisionBasis: 'ai-analysis',
          aiModel: aiService.getConfig().model,
          ...result.aiUsage
        }
      );
    }
    
    return result;
  }

  private calculateSynthesisBonus(selectedToolNames: string[], context: PipelineContext): number {
    let bonus = 0;
    
    if (selectedToolNames.length >= 3) bonus += 10;
    if (context.backgroundKnowledge && context.backgroundKnowledge.length > 0) bonus += 10;
    if (context.scenarioAnalysis || context.problemAnalysis) bonus += 5;
    if (context.investigationApproach) bonus += 5;
    
    return bonus;
  }

  private buildRecommendation(context: PipelineContext, mode: string, finalContent: string, toolsDataHash: string): any {
    const isWorkflow = mode === 'workflow';
    
    const base = {
      [isWorkflow ? 'scenario_analysis' : 'problem_analysis']: 
        isWorkflow ? context.scenarioAnalysis : context.problemAnalysis,
      investigation_approach: context.investigationApproach,
      critical_considerations: context.criticalConsiderations,
      background_knowledge: context.backgroundKnowledge?.map((bk: any) => ({
        concept_name: bk.concept.name,
        relevance: bk.relevance
      })) || []
    };

    if (isWorkflow) {
      const recommendedToolsWithConfidence = context.selectedTools?.map((st: any) => {
        const analysisContext: AnalysisContext = {
          userQuery: context.userQuery,
          mode: context.mode,
          embeddingsSimilarities: context.embeddingsSimilarities,
          selectedTools: context.selectedTools
        };
        
        const confidence = confidenceScoring.calculateRecommendationConfidence(
          st.tool,
          analysisContext,
          st.taskRelevance || 70,
          st.limitations || []
        );

        auditService.addConfidenceCalculation(
          st.tool.name,
          confidence,
          Date.now(),
          {
            toolsDataHash: toolsDataHash,
            phase: st.phase,
            priority: st.priority,
            toolType: st.tool.type,
            moderatedTaskRelevance: st.taskRelevance
          }
        );

        return {
          name: st.tool.name,
          type: st.tool.type,
          phase: st.phase,
          priority: st.priority,
          justification: st.justification || `Empfohlen für ${st.phase}`,
          confidence: confidence,
          recommendationStrength: confidenceScoring.getConfidenceLevel(confidence.overall)
        };
      }) || [];

      return {
        ...base,
        recommended_tools: recommendedToolsWithConfidence,
        workflow_suggestion: finalContent
      };
    } else {
      const recommendedToolsWithConfidence = context.selectedTools?.map((st: any) => {
        const analysisContext: AnalysisContext = {
          userQuery: context.userQuery,
          mode: context.mode,
          embeddingsSimilarities: context.embeddingsSimilarities,
          selectedTools: context.selectedTools
        };
        
        const confidence = confidenceScoring.calculateRecommendationConfidence(
          st.tool,
          analysisContext,
          st.taskRelevance || 70,
          st.limitations || []
        );

        auditService.addConfidenceCalculation(
          st.tool.name,
          confidence,
          Date.now(),
          {
            toolsDataHash: toolsDataHash,
            rank: st.tool.evaluation?.rank || 1,
            toolType: st.tool.type,
            moderatedTaskRelevance: st.taskRelevance
          }
        );

        return {
          name: st.tool.name,
          type: st.tool.type,
          rank: st.tool.evaluation?.rank || 1,
          suitability_score: st.priority,
          detailed_explanation: st.tool.evaluation?.detailed_explanation || '',
          implementation_approach: st.tool.evaluation?.implementation_approach || '',
          pros: st.tool.evaluation?.pros || [],
          cons: st.tool.evaluation?.limitations || [],
          alternatives: st.tool.evaluation?.alternatives || '',
          confidence: confidence,
          recommendationStrength: confidenceScoring.getConfidenceLevel(confidence.overall)
        };
      }) || [];

      return {
        ...base,
        recommended_tools: recommendedToolsWithConfidence,
        additional_considerations: finalContent
      };
    }
  }

  private async callMicroTaskAI(
    prompt: string, 
    context: PipelineContext, 
    taskType: string = 'micro-task'
  ): Promise<MicroTaskResult> {
    const startTime = Date.now();
    
    let contextPrompt = prompt;
    if (context.contextHistory.length > 0) {
      const contextSection = `BISHERIGE ANALYSE:\n${context.contextHistory.join('\n\n')}\n\nAKTUELLE AUFGABE:\n`;
      contextPrompt = contextSection + prompt;
    }
    
    try {
      const response = await aiService.callMicroTaskAI(contextPrompt);
      
      const toolsDataHash = getDataVersion?.() || 'unknown';
      const aiConfig = aiService.getConfig();
      
      const responseConfidence = auditService.calculateAIResponseConfidence(
        response.content,
        this.getExpectedLengthForTaskType(taskType),
        taskType
      );
      
      auditService.addAIDecision(
        this.getPhaseForTaskType(taskType),
        prompt,
        response.content,
        responseConfidence,
        this.getReasoningForTaskType(taskType, response.content),
        startTime,
        {
          toolsDataHash: toolsDataHash,
          microTaskType: taskType,
          aiModel: aiConfig.model,
          contextLength: contextPrompt.length,
          originalPromptLength: prompt.length,
          contextHistoryUsed: context.contextHistory.length > 0,
          decisionBasis: 'ai-analysis',
          ...response.usage
        }
      );
      
      return {
        taskType,
        content: response.content,
        processingTimeMs: Date.now() - startTime,
        success: true,
        aiUsage: response.usage
      };

    } catch (error) {
      auditService.addEntry(
        this.getPhaseForTaskType(taskType),
        'ai-decision-failed',
        { 
          prompt: prompt.slice(0, 200) + '...',
          taskType: taskType,
          error: error.message
        },
        { 
          error: error.message,
          success: false
        },
        0,
        startTime,
        {
          toolsDataHash: getDataVersion?.() || 'unknown',
          microTaskType: taskType,
          failed: true,
          decisionBasis: 'ai-analysis'
        }
      );
      
      return {
        taskType,
        content: '',
        processingTimeMs: Date.now() - startTime,
        success: false,
        error: error.message
      };
    }
  }

  private getPhaseForTaskType(taskType: string): string {
    const phaseMap: Record<string, string> = {
      'scenario-analysis': 'contextual-analysis',
      'investigation-approach': 'contextual-analysis',
      'critical-considerations': 'contextual-analysis',
      'tool-evaluation': 'tool-evaluation',
      'background-knowledge': 'knowledge-synthesis',
      'final-recommendations': 'synthesis',
      'phase-completion-selection': 'phase-completion',
      'phase-completion-reasoning': 'phase-completion'
    };
    return phaseMap[taskType] || 'contextual-analysis';
  }

  private getExpectedLengthForTaskType(taskType: string): { min: number; max: number } {
    const lengthMap: Record<string, { min: number; max: number }> = {
      'scenario-analysis': { min: 100, max: 500 },
      'investigation-approach': { min: 100, max: 400 },
      'critical-considerations': { min: 80, max: 300 },
      'tool-evaluation': { min: 200, max: 800 },
      'background-knowledge': { min: 50, max: 300 },
      'final-recommendations': { min: 150, max: 600 },
      'phase-completion-selection': { min: 50, max: 200 },
      'phase-completion-reasoning': { min: 100, max: 300 }
    };
    return lengthMap[taskType] || { min: 50, max: 300 };
  }

  private getReasoningForTaskType(taskType: string, response: string): string {
    const responseLength = response.length;
    const taskNames: Record<string, string> = {
      'scenario-analysis': 'Szenario-Analyse',
      'investigation-approach': 'Untersuchungsansatz',
      'critical-considerations': 'Kritische Überlegungen',
      'tool-evaluation': 'Tool-Bewertung',
      'background-knowledge': 'Hintergrundwissen-Auswahl',
      'final-recommendations': 'Abschließende Empfehlungen',
      'phase-completion-selection': 'Phasen-Vervollständigung',
      'phase-completion-reasoning': 'Phasen-Begründung'
    };
    
    const taskName = taskNames[taskType] || taskType;
    return `KI generierte ${taskName} (${responseLength} Zeichen) - Analyse mit methodischer Begründung`;
  }

  private addToContextHistory(context: PipelineContext, newEntry: string): void {
    const entryTokens = aiService.estimateTokens(newEntry);
    
    context.contextHistory.push(newEntry);
    context.currentContextLength += entryTokens;
    
    if (context.contextHistory.length > 1) {
      const removed = context.contextHistory.shift()!;
      context.currentContextLength -= aiService.estimateTokens(removed);
    }
  }

  private addToolToSelection(
    context: PipelineContext,
    tool: any,
    phase: string,
    priority: string,
    justification?: string,
    taskRelevance?: number,
    limitations?: string[]
  ): boolean {
    context.seenToolNames.add(tool.name);
    if (!context.selectedTools) context.selectedTools = [];
    
    context.selectedTools.push({
      tool,
      phase,
      priority,
      justification,
      taskRelevance,
      limitations
    });
    
    return true;
  }

  private derivePriorityFromScore(taskRelevance: number): string {
    if (taskRelevance >= 80) return 'high';
    if (taskRelevance >= 60) return 'medium';
    return 'low';
  }

  private trackTokenUsage(usage?: { promptTokens?: number; completionTokens?: number; totalTokens?: number }): void {
    if (usage?.totalTokens) {
      this.totalTokensUsed += usage.totalTokens;
    }
  }

  private async delay(ms: number): Promise<void> {
    return new Promise(resolve => setTimeout(resolve, ms));
  }
}

export const aiPipeline = new AIPipeline();
export type { AnalysisResult };