// src/services/ai/confidenceService.ts
import { config } from '../../config/appConfig.js';
import { isToolHosted } from '../../utils/toolHelpers.js';
import { logger } from '../logger.js';

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

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

export class ConfidenceService {
  private readonly semanticWeight: number;
  private readonly suitabilityWeight: number;
  private readonly minimumThreshold: number;
  private readonly mediumThreshold: number;
  private readonly highThreshold: number;

  constructor() {
    this.semanticWeight = config.confidence.semanticWeight;
    this.suitabilityWeight = config.confidence.suitabilityWeight;
    this.minimumThreshold = config.confidence.minimumThreshold;
    this.mediumThreshold = config.confidence.mediumThreshold;
    this.highThreshold = config.confidence.highThreshold;
    
    logger.info('confidence', 'Confidence service initialized', {
      semanticWeight: this.semanticWeight,
      suitabilityWeight: this.suitabilityWeight
    });
  }

  calculateRecommendationConfidence(
    tool: any,
    context: AnalysisContext,
    taskRelevance: number = 70,
    limitations: string[] = []
  ): ConfidenceMetrics {
    // Calculate semantic relevance from embeddings
    const rawSemanticRelevance = context.embeddingsSimilarities.has(tool.name) ?
      context.embeddingsSimilarities.get(tool.name)! * 100 : 50;
    
    // Enhanced task suitability based on context
    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);
      }
    }
    
    // Calculate overall confidence
    const overall = (
      rawSemanticRelevance * this.semanticWeight +
      enhancedTaskSuitability * this.suitabilityWeight
    );

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

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

    logger.confidence(
      tool.name,
      result.overall,
      result.semanticRelevance,
      result.taskSuitability
    );

    return result;
  }

  private identifyUncertaintyFactors(
    tool: any,
    context: AnalysisContext,
    limitations: string[],
    confidence: number
  ): string[] {
    const factors: string[] = [];
    
    // Include provided limitations
    if (limitations?.length > 0) {
      factors.push(...limitations.slice(0, 2));
    }
    
    // Semantic similarity concerns
    const similarity = context.embeddingsSimilarities.get(tool.name) || 0.5;
    if (similarity < 0.7) {
      factors.push('Geringe semantische Ähnlichkeit zur Anfrage');
    }
    
    // Skill level vs query urgency mismatch
    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');
    }
    
    // Installation/setup requirements
    if (tool.type === 'software' && !isToolHosted(tool) && 
        tool.accessType === 'download') {
      factors.push('Installation und Setup erforderlich');
    }
    
    // License considerations
    if (tool.license === 'Proprietary') {
      factors.push('Kommerzielle Software - Lizenzkosten zu beachten');
    }
    
    // Overall confidence concerns
    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[] = [];
    
    // High semantic similarity
    const similarity = context.embeddingsSimilarities.get(tool.name) || 0.5;
    if (similarity >= 0.7) {
      indicators.push('Sehr gute semantische Übereinstimmung mit Ihrer Anfrage');
    }
    
    // Documentation availability
    if (tool.knowledgebase === true) {
      indicators.push('Umfassende Dokumentation und Wissensbasis verfügbar');
    }
    
    // Immediate availability
    if (isToolHosted(tool)) {
      indicators.push('Sofort verfügbar über gehostete Lösung');
    }
    
    // Balanced complexity
    if (tool.skillLevel === 'intermediate' || tool.skillLevel === 'advanced') {
      indicators.push('Ausgewogenes Verhältnis zwischen Funktionalität und Benutzerfreundlichkeit');
    }
    
    // Method alignment with query type
    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);
  }

  getConfidenceLevel(confidence: number): 'low' | 'medium' | 'high' {
    if (confidence >= this.highThreshold) return 'high';
    if (confidence >= this.mediumThreshold) return 'medium';
    return 'low';
  }

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

  calculateSelectionConfidence(
    result: any, 
    candidateCount: number
  ): number {
    if (!result?.selectedTools) return 30;
    
    const selectionRatio = result.selectedTools.length / candidateCount;
    const hasReasoning = result.reasoning && result.reasoning.length > 50;
    
    let confidence = 60;
    
    // Selection ratio scoring
    if (selectionRatio > 0.05 && selectionRatio < 0.3) {
      confidence += 20;
    } else if (selectionRatio <= 0.05) {
      confidence -= 10;
    } else {
      confidence -= 15;
    }
    
    // Quality indicators
    if (hasReasoning) confidence += 15;
    if (result.selectedConcepts?.length > 0) confidence += 5;
    
    return Math.min(95, Math.max(25, confidence));
  }
}

export const confidenceService = new ConfidenceService();