"""
Configuration for EDS-NLP integration.

This module defines the configuration dataclass for EDS-NLP processing,
including model selection, component toggles, performance tuning, and
fallback behavior.

Validates: Requirements 1.1
"""

from dataclasses import dataclass, field
from pathlib import Path
from typing import Optional, List


@dataclass
class EDSNLPConfig:
    """Configuration for EDS-NLP integration."""
    
    # Model configuration
    model_name: str = "fr_core_news_sm"
    """spaCy model name for French language processing."""
    
    # Component toggles
    enable_sentences: bool = True
    """Enable eds.sentences component for sentence segmentation."""
    
    enable_negation: bool = True
    """Enable eds.negation component for negation detection."""
    
    enable_hypothesis: bool = True
    """Enable eds.hypothesis component for hypothesis/suspicion detection."""
    
    enable_history: bool = True
    """Enable eds.history component for historical context detection."""
    
    enable_family: bool = True
    """Enable eds.family component for family context detection."""
    
    enable_reported_speech: bool = True
    """Enable eds.reported_speech component for reported speech detection."""
    
    # Performance tuning
    cache_pipeline: bool = True
    """Whether to cache the spaCy pipeline instance for reuse."""
    
    batch_size: int = 32
    """Batch size for processing multiple documents."""
    
    max_length: int = 1000000
    """Maximum document length in characters (spaCy limit)."""
    
    # Fallback configuration
    enable_fallback: bool = True
    """Whether to fall back to regex-based extraction on EDS-NLP failure."""
    
    max_failures_before_cooldown: int = 3
    """Maximum consecutive failures before entering cooldown period."""
    
    cooldown_period_seconds: int = 300
    """Cooldown period in seconds (5 minutes) after repeated failures."""
    
    # Timeout configuration
    processing_timeout_seconds: float = 30.0
    """Maximum time allowed for processing a single document."""
    
    # Normalization
    enable_normalization: bool = True
    """Whether to normalize clinical terms."""
    
    abbreviations_file: Optional[Path] = None
    """Path to JSON file containing medical abbreviation mappings."""
    
    # Entity extraction configuration
    extract_diagnostics: bool = True
    """Whether to extract diagnostic entities."""
    
    extract_medications: bool = True
    """Whether to extract medication entities."""
    
    extract_procedures: bool = True
    """Whether to extract procedure entities."""
    
    extract_dates: bool = True
    """Whether to extract temporal entities (dates)."""
    
    extract_measurements: bool = True
    """Whether to extract measurement entities."""
    
    # Confidence thresholds
    min_entity_confidence: float = 0.3
    """Minimum confidence score for extracted entities."""
    
    min_qualifier_confidence: float = 0.5
    """Minimum confidence score for detected qualifiers."""
    
    # Logging configuration
    log_processing_time: bool = True
    """Whether to log processing time for each document."""
    
    log_entity_counts: bool = True
    """Whether to log counts of extracted entities by type."""
    
    performance_warning_threshold: float = 1.0
    """Log warning if processing time exceeds this threshold (seconds)."""
    
    def get_enabled_components(self) -> List[str]:
        """
        Get list of enabled EDS-NLP component names.
        
        Returns:
            List of component names to add to the pipeline
        """
        components = []
        
        if self.enable_sentences:
            components.append("eds.sentences")
        if self.enable_negation:
            components.append("eds.negation")
        if self.enable_hypothesis:
            components.append("eds.hypothesis")
        if self.enable_history:
            components.append("eds.history")
        if self.enable_family:
            components.append("eds.family")
        if self.enable_reported_speech:
            components.append("eds.reported_speech")
            
        return components
    
    def should_extract_entity_type(self, entity_type: str) -> bool:
        """
        Check if a specific entity type should be extracted.
        
        Args:
            entity_type: Entity type to check (diagnostic, medication, etc.)
            
        Returns:
            True if entity type should be extracted
        """
        entity_type_lower = entity_type.lower()
        
        if entity_type_lower in ["diagnostic", "diagnosis", "disease"]:
            return self.extract_diagnostics
        elif entity_type_lower in ["medication", "drug", "treatment"]:
            return self.extract_medications
        elif entity_type_lower in ["procedure", "intervention", "surgery"]:
            return self.extract_procedures
        elif entity_type_lower in ["date", "time", "temporal"]:
            return self.extract_dates
        elif entity_type_lower in ["measurement", "lab", "result"]:
            return self.extract_measurements
        else:
            # Unknown entity type - extract by default
            return True
    
    @classmethod
    def from_yaml(cls, yaml_path: Path) -> "EDSNLPConfig":
        """
        Load configuration from YAML file.
        
        Args:
            yaml_path: Path to YAML configuration file
            
        Returns:
            EDSNLPConfig instance
        """
        import yaml
        
        with open(yaml_path, 'r', encoding='utf-8') as f:
            config_dict = yaml.safe_load(f)
        
        return cls(**config_dict)
    
    def to_dict(self) -> dict:
        """
        Convert configuration to dictionary.
        
        Returns:
            Dictionary representation of configuration
        """
        return {
            "model_name": self.model_name,
            "enable_sentences": self.enable_sentences,
            "enable_negation": self.enable_negation,
            "enable_hypothesis": self.enable_hypothesis,
            "enable_history": self.enable_history,
            "enable_family": self.enable_family,
            "enable_reported_speech": self.enable_reported_speech,
            "cache_pipeline": self.cache_pipeline,
            "batch_size": self.batch_size,
            "max_length": self.max_length,
            "enable_fallback": self.enable_fallback,
            "max_failures_before_cooldown": self.max_failures_before_cooldown,
            "cooldown_period_seconds": self.cooldown_period_seconds,
            "processing_timeout_seconds": self.processing_timeout_seconds,
            "enable_normalization": self.enable_normalization,
            "abbreviations_file": str(self.abbreviations_file) if self.abbreviations_file else None,
            "extract_diagnostics": self.extract_diagnostics,
            "extract_medications": self.extract_medications,
            "extract_procedures": self.extract_procedures,
            "extract_dates": self.extract_dates,
            "extract_measurements": self.extract_measurements,
            "min_entity_confidence": self.min_entity_confidence,
            "min_qualifier_confidence": self.min_qualifier_confidence,
            "log_processing_time": self.log_processing_time,
            "log_entity_counts": self.log_entity_counts,
            "performance_warning_threshold": self.performance_warning_threshold,
        }
