"""
InsAIts SDK - Intervention Engine
==================================
Active response system that takes action on detected anomalies
based on severity level and user-configurable callbacks.

Intervention hierarchy:
    CRITICAL -> quarantine + escalate to human (HITL)
    HIGH     -> reroute to backup agent or deliver with warning
    MEDIUM   -> deliver + log warning
    LOW/INFO -> deliver + log

Supports:
    - Human-in-the-loop (HITL) callbacks for critical decisions
    - Agent rerouting: redirect messages from misbehaving agents
    - Custom handlers: user-defined functions per anomaly type
"""

import logging
from typing import Any, Callable, Dict, List, Optional

from .models import MonitorResult, Severity

logger = logging.getLogger(__name__)


# Type alias for HITL callback
# Signature: callback(message: Dict, result: MonitorResult, context: Dict) -> bool
# Returns True to allow message, False to quarantine
HITLCallback = Callable[[Dict, MonitorResult, Dict], bool]


class InterventionEngine:
    """Severity-based intervention system for anomalous messages.

    Users configure the engine with callbacks and rerouting rules,
    then call handle() for each message that has anomalies.

    Usage:
        engine = InterventionEngine()

        # Register human-in-the-loop callback
        def my_hitl(message, result, context):
            # Inspect and decide
            return True  # Allow
        engine.register_hitl_callback(my_hitl)

        # Register agent rerouting
        engine.register_reroute("risky_agent", "backup_agent")

        # Handle a message
        outcome = engine.handle(message_dict, monitor_result)
        if outcome["action"] == "quarantined":
            # Message was blocked
            ...
    """

    def __init__(self) -> None:
        """Initialize the intervention engine with no callbacks."""
        self._hitl_callback: Optional[HITLCallback] = None
        self._reroute_map: Dict[str, str] = {}
        self._custom_handlers: Dict[str, Callable] = {}

    def register_hitl_callback(self, callback: HITLCallback) -> None:
        """Register a human-in-the-loop callback for critical anomalies.

        The callback receives (message, monitor_result, context) and
        must return True to allow the message or False to quarantine it.

        Args:
            callback: Function with signature (Dict, MonitorResult, Dict) -> bool
        """
        self._hitl_callback = callback
        logger.info("HITL callback registered")

    def register_reroute(self, from_agent: str, to_agent: str) -> None:
        """Register a rerouting rule for a misbehaving agent.

        Messages from from_agent will be redirected to to_agent
        when the intervention engine handles a HIGH severity anomaly.

        Args:
            from_agent: Agent ID to reroute from
            to_agent: Backup agent ID to reroute to
        """
        self._reroute_map[from_agent] = to_agent
        logger.info("Reroute registered: %s -> %s", from_agent, to_agent)

    def register_handler(
        self, anomaly_type: str, handler: Callable
    ) -> None:
        """Register a custom handler for a specific anomaly type.

        Args:
            anomaly_type: The anomaly type to handle (e.g. "SEMANTIC_DRIFT")
            handler: Function to call when this anomaly type is detected
        """
        self._custom_handlers[anomaly_type] = handler

    def handle(
        self,
        message: Dict[str, Any],
        result: MonitorResult,
        context: Optional[Dict[str, Any]] = None,
    ) -> Dict[str, Any]:
        """Handle a message based on its anomaly results.

        Applies the intervention hierarchy:
            CRITICAL -> quarantine + HITL escalation
            HIGH -> reroute or deliver with warning
            MEDIUM -> deliver + log
            LOW/INFO -> deliver + log

        Args:
            message: The original message dict
            result: MonitorResult from send_message
            context: Optional additional context for callbacks

        Returns:
            Dict with:
                action (str): "delivered", "quarantined", "rerouted", "delivered_with_warning"
                modified (bool): Whether the message was altered
                severity (str): Highest severity encountered
                reason (str): Explanation of action taken
                rerouted_to (str, optional): Target agent if rerouted
        """
        if context is None:
            context = {}

        if result.clean:
            return {
                "action": "delivered",
                "modified": False,
                "severity": "info",
                "reason": "No anomalies detected",
            }

        severity = result.highest_severity

        # Run custom handlers for specific anomaly types
        for anomaly in result.anomalies:
            if anomaly.detected and anomaly.type in self._custom_handlers:
                try:
                    self._custom_handlers[anomaly.type](
                        message, anomaly, context
                    )
                except Exception as exc:
                    logger.error(
                        "Custom handler error for %s: %s",
                        anomaly.type,
                        exc,
                    )

        # CRITICAL: quarantine + HITL
        if severity == Severity.CRITICAL:
            return self._handle_critical(message, result, context)

        # HIGH: reroute or warn
        if severity == Severity.HIGH:
            return self._handle_high(message, result, context)

        # MEDIUM: deliver with warning
        if severity == Severity.MEDIUM:
            return {
                "action": "delivered_with_warning",
                "modified": False,
                "severity": severity.value,
                "reason": "Medium severity anomaly: monitoring continues",
            }

        # LOW / INFO: deliver
        return {
            "action": "delivered",
            "modified": False,
            "severity": severity.value,
            "reason": "Low severity anomaly: logged for monitoring",
        }

    def _handle_critical(
        self,
        message: Dict[str, Any],
        result: MonitorResult,
        context: Dict[str, Any],
    ) -> Dict[str, Any]:
        """Handle CRITICAL severity: quarantine + HITL escalation."""
        # Escalate to HITL if callback registered
        if self._hitl_callback is not None:
            try:
                allowed = self._hitl_callback(message, result, context)
                if allowed:
                    return {
                        "action": "delivered_with_warning",
                        "modified": False,
                        "severity": "critical",
                        "reason": "HITL approved delivery despite critical anomaly",
                    }
            except Exception as exc:
                logger.error("HITL callback error: %s", exc)

        # Quarantine
        anomaly_types = [
            a.type for a in result.anomalies if a.detected
        ]
        return {
            "action": "quarantined",
            "modified": False,
            "severity": "critical",
            "reason": (
                f"Critical anomaly detected: {', '.join(anomaly_types)}. "
                "Message quarantined."
            ),
        }

    def _handle_high(
        self,
        message: Dict[str, Any],
        result: MonitorResult,
        context: Dict[str, Any],
    ) -> Dict[str, Any]:
        """Handle HIGH severity: reroute or deliver with warning."""
        sender = result.sender_id
        reroute_target = self._reroute_map.get(sender)

        if reroute_target is not None:
            return {
                "action": "rerouted",
                "modified": True,
                "severity": "high",
                "reason": (
                    f"High anomaly from {sender}: "
                    f"rerouted to {reroute_target}"
                ),
                "rerouted_to": reroute_target,
            }

        return {
            "action": "delivered_with_warning",
            "modified": False,
            "severity": "high",
            "reason": "High severity anomaly: delivered with warning",
        }
