// src/utils/confidenceScoring.ts
import { isToolHosted } from './clientUtils.js';
import 'dotenv/config';

export interface ConfidenceMetrics {
  overall: number;
  semanticRelevance: number;
  taskSuitability: number;
  uncertaintyFactors: string[];
  strengthIndicators: string[];
}

export interface ConfidenceConfig {
  semanticWeight: number;
  suitabilityWeight: number;
  minimumThreshold: number;
  mediumThreshold: number;
  highThreshold: number;
}

export interface AnalysisContext {
  userQuery: string;
  mode: string;
  embeddingsSimilarities: Map<string, number>;
  selectedTools?: Array<{
    tool: any;
    phase: string;
    priority: string;
    justification?: string;
    taskRelevance?: number;
    limitations?: string[];
  }>;
}

class ConfidenceScoring {
  private config: ConfidenceConfig;

  constructor() {
    this.config = {
      semanticWeight: this.getEnvFloat('CONFIDENCE_SEMANTIC_WEIGHT', 0.3),
      suitabilityWeight: this.getEnvFloat('CONFIDENCE_SUITABILITY_WEIGHT', 0.7), 
      minimumThreshold: this.getEnvInt('CONFIDENCE_MINIMUM_THRESHOLD', 40),
      mediumThreshold: this.getEnvInt('CONFIDENCE_MEDIUM_THRESHOLD', 60),
      highThreshold: this.getEnvInt('CONFIDENCE_HIGH_THRESHOLD', 80)
    };

    console.log('[CONFIDENCE-SCORING] Initialized with restored config:', this.config);
  }

  private getEnvFloat(key: string, defaultValue: number): number {
    const value = process.env[key];
    return value ? parseFloat(value) : defaultValue;
  }

  private getEnvInt(key: string, defaultValue: number): number {
    const value = process.env[key];
    return value ? parseInt(value, 10) : defaultValue;
  }

  calculateRecommendationConfidence(
    tool: any,
    context: AnalysisContext,
    taskRelevance: number = 70,
    limitations: string[] = []
  ): ConfidenceMetrics {
    console.log('[CONFIDENCE-SCORING] Calculating confidence for tool:', tool.name);

    const rawSemanticRelevance = context.embeddingsSimilarities.has(tool.name) ?
      context.embeddingsSimilarities.get(tool.name)! * 100 : 50;
    
    let enhancedTaskSuitability = taskRelevance;
    
    if (context.mode === 'workflow') {
      const toolSelection = context.selectedTools?.find((st: any) => st.tool && st.tool.name === tool.name);
      if (toolSelection && tool.phases && Array.isArray(tool.phases) && tool.phases.includes(toolSelection.phase)) {
        const phaseBonus = Math.min(15, 100 - taskRelevance);
        enhancedTaskSuitability = Math.min(100, taskRelevance + phaseBonus);
        console.log('[CONFIDENCE-SCORING] Phase alignment bonus applied:', phaseBonus);
      }
    }
    
    const overall = (
      rawSemanticRelevance * this.config.semanticWeight +
      enhancedTaskSuitability * this.config.suitabilityWeight
    );

    const uncertaintyFactors = this.identifyUncertaintyFactors(tool, context, limitations, overall);
    const strengthIndicators = this.identifyStrengthIndicators(tool, context, overall);

    const result = {
      overall: Math.round(overall),
      semanticRelevance: Math.round(rawSemanticRelevance),
      taskSuitability: Math.round(enhancedTaskSuitability),
      uncertaintyFactors,
      strengthIndicators
    };

    console.log('[CONFIDENCE-SCORING] Confidence calculated:', {
      tool: tool.name,
      overall: result.overall,
      semantic: result.semanticRelevance,
      task: result.taskSuitability,
      uncertaintyCount: uncertaintyFactors.length,
      strengthCount: strengthIndicators.length
    });

    return result;
  }

  private identifyUncertaintyFactors(
    tool: any,
    context: AnalysisContext,
    limitations: string[],
    confidence: number
  ): string[] {
    const factors: string[] = [];
    
    if (limitations?.length > 0) {
      factors.push(...limitations.slice(0, 2));
    }
    
    const similarity = context.embeddingsSimilarities.get(tool.name) || 0.5;
    if (similarity < 0.7) {
      factors.push('Geringe semantische Ähnlichkeit zur Anfrage');
    }
    
    if (tool.skillLevel === 'expert' && /schnell|rapid|triage|urgent|sofort/i.test(context.userQuery)) {
      factors.push('Experten-Tool für zeitkritisches Szenario');
    }
    
    if (tool.skillLevel === 'novice' && /komplex|erweitert|tiefgehend|advanced|forensisch/i.test(context.userQuery)) {
      factors.push('Einsteiger-Tool für komplexe Analyse');
    }
    
    if (tool.type === 'software' && !isToolHosted(tool) && tool.accessType === 'download') {
      factors.push('Installation und Setup erforderlich');
    }
    
    if (tool.license === 'Proprietary') {
      factors.push('Kommerzielle Software - Lizenzkosten zu beachten');
    }
    
    if (confidence < 60) {
      factors.push('Moderate Gesamtbewertung - alternative Ansätze empfohlen');
    }
    
    return factors.slice(0, 4);
  }

  private identifyStrengthIndicators(tool: any, context: AnalysisContext, confidence: number): string[] {
    const indicators: string[] = [];
    
    const similarity = context.embeddingsSimilarities.get(tool.name) || 0.5;
    if (similarity >= 0.7) {
      indicators.push('Sehr gute semantische Übereinstimmung mit Ihrer Anfrage');
    }
    
    if (tool.knowledgebase === true) {
      indicators.push('Umfassende Dokumentation und Wissensbasis verfügbar');
    }
    
    if (isToolHosted(tool)) {
      indicators.push('Sofort verfügbar über gehostete Lösung');
    }
    
    if (tool.skillLevel === 'intermediate' || tool.skillLevel === 'advanced') {
      indicators.push('Ausgewogenes Verhältnis zwischen Funktionalität und Benutzerfreundlichkeit');
    }
    
    if (tool.type === 'method' && /methodik|vorgehen|prozess|ansatz/i.test(context.userQuery)) {
      indicators.push('Methodischer Ansatz passt zu Ihrer prozeduralen Anfrage');
    }
    
    return indicators.slice(0, 4);
  }

  calculateSelectionConfidence(result: any, candidateCount: number): number {
    if (!result?.selectedTools) {
      console.log('[CONFIDENCE-SCORING] No selected tools for confidence calculation');
      return 30;
    }
    
    const selectionRatio = result.selectedTools.length / candidateCount;
    const hasReasoning = result.reasoning && result.reasoning.length > 50;
    
    let confidence = 60;
    
    if (selectionRatio > 0.05 && selectionRatio < 0.3) confidence += 20;
    else if (selectionRatio <= 0.05) confidence -= 10;
    else confidence -= 15;
    
    if (hasReasoning) confidence += 15;
    if (result.selectedConcepts?.length > 0) confidence += 5;
    
    const finalConfidence = Math.min(95, Math.max(25, confidence));
    
    console.log('[CONFIDENCE-SCORING] Selection confidence calculated:', {
      candidateCount,
      selectedCount: result.selectedTools.length,
      selectionRatio: selectionRatio.toFixed(3),
      hasReasoning,
      confidence: finalConfidence
    });
    
    return finalConfidence;
  }

  getConfidenceLevel(confidence: number): 'weak' | 'moderate' | 'strong' {
    if (confidence >= this.config.highThreshold) return 'strong';
    if (confidence >= this.config.mediumThreshold) return 'moderate';
    return 'weak';
  }

  getConfidenceColor(confidence: number): string {
    if (confidence >= this.config.highThreshold) return 'var(--color-accent)';
    if (confidence >= this.config.mediumThreshold) return 'var(--color-warning)';
    return 'var(--color-error)';
  }

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

export const confidenceScoring = new ConfidenceScoring();