"""Configuration for SAGEEngine.

Provides a unified configuration dataclass that combines RAG pipeline settings,
tool configurations, and engine-specific options.
"""

from dataclasses import dataclass, field
from enum import Enum
from pathlib import Path
from typing import Any

import yaml

from sage.rag.pipeline import RAGConfig


class EngineMode(Enum):
    """Operating modes for SAGEEngine."""

    KNOWLEDGE_ONLY = "knowledge_only"  # RAG queries only, no tools
    FULL = "full"  # Full capabilities including tools
    RESTRICTED = "restricted"  # Restricted mode with extra safety checks


@dataclass
class RouterConfig:
    """Configuration for query routing."""

    # Classification thresholds
    calculation_confidence_threshold: float = 0.7
    knowledge_confidence_threshold: float = 0.6

    # Keywords for query type detection
    calculation_keywords: list[str] = field(
        default_factory=lambda: [
            "calculate",
            "compute",
            "estimate",
            "determine",
            "find",
            "solve",
            "k-eff",
            "keff",
            "k_eff",
            "criticality",
            "mass",
            "volume",
            "concentration",
            "convert",
            "how much",
            "what is the value",
        ]
    )

    knowledge_keywords: list[str] = field(
        default_factory=lambda: [
            "what is",
            "define",
            "explain",
            "describe",
            "who",
            "when",
            "where",
            "why",
            "history",
            "background",
            "overview",
            "meaning of",
            "purpose of",
            "reason for",
            "history of",
        ]
    )

    document_keywords: list[str] = field(
        default_factory=lambda: [
            "draft",
            "write",
            "create document",
            "cse",
            "safety evaluation",
            "technical report",
            "memo",
            "letter",
            "procedure",
            "checklist",
        ]
    )

    analysis_keywords: list[str] = field(
        default_factory=lambda: [
            "analyze",
            "compare",
            "evaluate",
            "assess",
            "review",
            "determine if",
            "is it safe",
            "check compliance",
            "pros and cons",
            "trade-off",
            "implications",
            "consequences",
            "what if",
            "would it be safe",
        ]
    )

    training_keywords: list[str] = field(
        default_factory=lambda: [
            "teach",
            "tutorial",
            "how do i",
            "learn",
            "training",
            "example",
            "walk through",
            "step by step",
        ]
    )


@dataclass
class ToolConfig:
    """Configuration for tool execution."""

    # Tool enable/disable flags
    enable_keff_estimator: bool = True
    enable_scale_interface: bool = True
    enable_unit_converter: bool = True
    enable_standards_lookup: bool = True
    enable_geometry_visualizer: bool = True

    # Execution settings
    max_tool_execution_time_seconds: float = 30.0
    max_concurrent_tools: int = 3
    require_tool_confirmation: bool = False

    # SCALE-specific settings
    scale_executable_path: str | None = None
    scale_work_directory: str | None = None


@dataclass
class MonitorConfig:
    """Configuration for production monitoring."""

    # Logging
    log_queries: bool = True
    log_responses: bool = True
    log_tool_executions: bool = True

    # Alerting thresholds
    response_time_alert_ms: float = 5000.0
    error_rate_alert_threshold: float = 0.05
    low_confidence_alert_threshold: float = 0.5

    # Metrics
    enable_metrics: bool = True
    metrics_prefix: str = "sage_engine"


@dataclass
class DataCollectionConfig:
    """Configuration for training data collection."""

    # Enable/disable data collection
    enable_interaction_logging: bool = False

    # Storage paths
    interaction_log_path: str = "data/interactions/"
    feedback_path: str = "data/feedback/"

    # Logging settings
    batch_size: int = 100
    log_rag_context: bool = True
    log_tool_executions: bool = True
    log_reasoning_chain: bool = True

    # Privacy
    anonymize_user_ids: bool = True
    exclude_pii_patterns: bool = True


@dataclass
class SAGEConfig:
    """Unified configuration for SAGEEngine.

    Combines RAG pipeline configuration with engine-specific settings
    for routing, tools, monitoring, and data collection.
    """

    # Core RAG configuration
    rag_config: RAGConfig = field(default_factory=RAGConfig)

    # Engine-specific configuration
    mode: EngineMode = EngineMode.FULL
    router_config: RouterConfig = field(default_factory=RouterConfig)
    tool_config: ToolConfig = field(default_factory=ToolConfig)
    monitor_config: MonitorConfig = field(default_factory=MonitorConfig)
    data_collection_config: DataCollectionConfig = field(default_factory=DataCollectionConfig)

    # General settings
    max_reasoning_steps: int = 5
    enable_multi_step_reasoning: bool = True
    default_user_id: str = "anonymous"

    @classmethod
    def from_yaml(cls, path: str | Path) -> "SAGEConfig":
        """Load configuration from a YAML file.

        Args:
            path: Path to the YAML configuration file.

        Returns:
            SAGEConfig instance with loaded settings.
        """
        path = Path(path)
        with open(path) as f:
            data = yaml.safe_load(f)

        return cls.from_dict(data)

    @classmethod
    def from_dict(cls, data: dict[str, Any]) -> "SAGEConfig":
        """Create configuration from a dictionary.

        Args:
            data: Configuration dictionary.

        Returns:
            SAGEConfig instance.
        """
        # Extract sub-configurations
        rag_data = data.get("rag", {})
        router_data = data.get("router", {})
        tool_data = data.get("tools", {})
        monitor_data = data.get("monitor", {})
        data_collection_data = data.get("data_collection", {})

        # Build RAGConfig from nested data
        rag_config = RAGConfig(**rag_data) if rag_data else RAGConfig()

        # Build sub-configs
        router_config = RouterConfig(**router_data) if router_data else RouterConfig()
        tool_config = ToolConfig(**tool_data) if tool_data else ToolConfig()
        monitor_config = MonitorConfig(**monitor_data) if monitor_data else MonitorConfig()
        data_collection_config = DataCollectionConfig(**data_collection_data) if data_collection_data else DataCollectionConfig()

        # Handle mode enum
        mode_str = data.get("mode", "full")
        mode = EngineMode(mode_str)

        return cls(
            rag_config=rag_config,
            mode=mode,
            router_config=router_config,
            tool_config=tool_config,
            monitor_config=monitor_config,
            data_collection_config=data_collection_config,
            max_reasoning_steps=data.get("max_reasoning_steps", 5),
            enable_multi_step_reasoning=data.get("enable_multi_step_reasoning", True),
            default_user_id=data.get("default_user_id", "anonymous"),
        )

    def to_dict(self) -> dict[str, Any]:
        """Convert configuration to a dictionary.

        Returns:
            Dictionary representation of the configuration.
        """
        return {
            "mode": self.mode.value,
            "max_reasoning_steps": self.max_reasoning_steps,
            "enable_multi_step_reasoning": self.enable_multi_step_reasoning,
            "default_user_id": self.default_user_id,
            "router": {
                "calculation_confidence_threshold": self.router_config.calculation_confidence_threshold,
                "knowledge_confidence_threshold": self.router_config.knowledge_confidence_threshold,
                "calculation_keywords": self.router_config.calculation_keywords,
                "knowledge_keywords": self.router_config.knowledge_keywords,
                "document_keywords": self.router_config.document_keywords,
                "analysis_keywords": self.router_config.analysis_keywords,
                "training_keywords": self.router_config.training_keywords,
            },
            "tools": {
                "enable_keff_estimator": self.tool_config.enable_keff_estimator,
                "enable_scale_interface": self.tool_config.enable_scale_interface,
                "enable_unit_converter": self.tool_config.enable_unit_converter,
                "enable_standards_lookup": self.tool_config.enable_standards_lookup,
                "enable_geometry_visualizer": self.tool_config.enable_geometry_visualizer,
                "max_tool_execution_time_seconds": self.tool_config.max_tool_execution_time_seconds,
                "max_concurrent_tools": self.tool_config.max_concurrent_tools,
                "require_tool_confirmation": self.tool_config.require_tool_confirmation,
            },
            "monitor": {
                "log_queries": self.monitor_config.log_queries,
                "log_responses": self.monitor_config.log_responses,
                "log_tool_executions": self.monitor_config.log_tool_executions,
                "response_time_alert_ms": self.monitor_config.response_time_alert_ms,
                "error_rate_alert_threshold": self.monitor_config.error_rate_alert_threshold,
                "low_confidence_alert_threshold": self.monitor_config.low_confidence_alert_threshold,
                "enable_metrics": self.monitor_config.enable_metrics,
                "metrics_prefix": self.monitor_config.metrics_prefix,
            },
            "data_collection": {
                "enable_interaction_logging": self.data_collection_config.enable_interaction_logging,
                "interaction_log_path": self.data_collection_config.interaction_log_path,
                "feedback_path": self.data_collection_config.feedback_path,
                "batch_size": self.data_collection_config.batch_size,
                "log_rag_context": self.data_collection_config.log_rag_context,
                "log_tool_executions": self.data_collection_config.log_tool_executions,
                "log_reasoning_chain": self.data_collection_config.log_reasoning_chain,
                "anonymize_user_ids": self.data_collection_config.anonymize_user_ids,
                "exclude_pii_patterns": self.data_collection_config.exclude_pii_patterns,
            },
        }
