"""
Starvex Semantic Router - Topic classification using embeddings

Uses sentence transformers for semantic understanding of topics.
"""

import logging
from dataclasses import dataclass, field
from typing import Dict, Any, List, Optional

logger = logging.getLogger(__name__)


@dataclass
class RouteMatch:
    """Result of semantic routing"""
    route: str
    confidence: float
    safe: bool = True
    details: Dict[str, Any] = field(default_factory=dict)


class SemanticRouter:
    """
    Semantic topic router using sentence embeddings.

    Routes inputs to topics based on semantic similarity rather than
    keyword matching.
    """

    # Default blocked topics with example phrases
    DEFAULT_ROUTES = {
        "politics": [
            "political opinion",
            "election results",
            "government policy",
            "democrat or republican",
            "political party",
        ],
        "competitors": [
            "compare to competitor",
            "what about other products",
            "alternatives to this",
            "competitor pricing",
        ],
        "investment_advice": [
            "where should I invest",
            "stock recommendations",
            "buy or sell stocks",
            "financial advice",
            "trading tips",
        ],
        "medical_advice": [
            "what medicine should I take",
            "diagnose my symptoms",
            "medical treatment",
            "health prescription",
            "am I sick",
        ],
        "legal_advice": [
            "legal opinion",
            "should I sue",
            "legal strategy",
            "court case advice",
            "contract interpretation",
        ],
        "safe": [
            "hello how are you",
            "what can you help with",
            "general question",
            "coding help",
            "explain this concept",
        ],
    }

    def __init__(
        self,
        routes: Optional[Dict[str, List[str]]] = None,
        model_name: str = "all-MiniLM-L6-v2",
    ):
        """
        Initialize semantic router.

        Args:
            routes: Dict mapping route names to example phrases
            model_name: Sentence transformer model to use
        """
        self.routes = routes or self.DEFAULT_ROUTES
        self.model_name = model_name
        self._model = None
        self._embeddings: Dict[str, Any] = {}

    def _ensure_model(self):
        """Load model if not already loaded"""
        if self._model is not None:
            return

        try:
            from sentence_transformers import SentenceTransformer
            import numpy as np

            self._model = SentenceTransformer(self.model_name)
            self._np = np

            # Pre-compute embeddings for all routes
            for route, examples in self.routes.items():
                embeddings = self._model.encode(examples)
                self._embeddings[route] = embeddings

            logger.debug(f"Semantic router initialized with {len(self.routes)} routes")

        except ImportError:
            logger.warning("sentence-transformers not installed, semantic routing disabled")
            self._model = "fallback"

    def check_intent(self, text: str) -> Dict[str, Any]:
        """
        Check the intent of text and route to appropriate topic.

        Args:
            text: Input text to classify

        Returns:
            Dict with route, confidence, and safe status
        """
        self._ensure_model()

        if self._model == "fallback":
            return self._fallback_check(text)

        try:
            # Encode input
            input_embedding = self._model.encode([text])[0]

            best_route = "safe"
            best_score = 0.0

            # Compare against all routes
            for route, route_embeddings in self._embeddings.items():
                # Cosine similarity
                similarities = self._np.dot(route_embeddings, input_embedding) / (
                    self._np.linalg.norm(route_embeddings, axis=1) *
                    self._np.linalg.norm(input_embedding)
                )
                max_sim = float(self._np.max(similarities))

                if max_sim > best_score:
                    best_score = max_sim
                    best_route = route

            # Determine if safe
            unsafe_routes = {"politics", "competitors", "investment_advice",
                           "medical_advice", "legal_advice"}
            is_safe = best_route not in unsafe_routes or best_score < 0.5

            return {
                "route": best_route,
                "confidence": best_score,
                "safe": is_safe,
                "details": {"threshold": 0.5},
            }

        except Exception as e:
            logger.error(f"Semantic routing error: {e}")
            return self._fallback_check(text)

    def _fallback_check(self, text: str) -> Dict[str, Any]:
        """Simple keyword-based fallback"""
        text_lower = text.lower()

        keyword_routes = {
            "politics": ["politic", "election", "government", "democrat", "republican"],
            "investment_advice": ["invest", "stock", "trade", "financial advice"],
            "medical_advice": ["medicine", "diagnose", "symptom", "prescription", "treatment"],
            "legal_advice": ["lawyer", "legal", "sue", "court", "contract"],
        }

        for route, keywords in keyword_routes.items():
            for keyword in keywords:
                if keyword in text_lower:
                    return {
                        "route": route,
                        "confidence": 0.7,
                        "safe": False,
                        "details": {"method": "keyword", "matched": keyword},
                    }

        return {
            "route": "safe",
            "confidence": 0.8,
            "safe": True,
            "details": {"method": "keyword"},
        }


# Alias for backward compatibility
class AccuracyEngine(SemanticRouter):
    """Alias for SemanticRouter"""
    pass
