"""Router core: thin wrapper that tries Rust extension, falls back to Python.

Import this module instead of calling functions directly:

    from llmhosts.router._core import RUST_AVAILABLE, knn_search, extract_features, ...
"""

from __future__ import annotations

import logging

logger = logging.getLogger(__name__)

RUST_AVAILABLE: bool = False

try:
    from _llmhosts import router as _router_core_mod  # type: ignore[import]

    _rust_classify_privacy = _router_core_mod.classify_privacy
    _rust_extract_features = _router_core_mod.extract_features
    _rust_knn_search = _router_core_mod.knn_search
    _rust_score_confidence = _router_core_mod.score_confidence
    RUST_AVAILABLE = True
    logger.debug("Rust router core loaded (_llmhosts.router)")
except ImportError:
    # Fallback: try standalone module (development mode with individual maturin develop)
    try:
        from _router_core import classify_privacy as _rust_classify_privacy  # type: ignore[import,no-redef]
        from _router_core import extract_features as _rust_extract_features  # type: ignore[import,no-redef]
        from _router_core import knn_search as _rust_knn_search  # type: ignore[import,no-redef]
        from _router_core import score_confidence as _rust_score_confidence  # type: ignore[import,no-redef]

        RUST_AVAILABLE = True
        logger.debug("Rust router core loaded (standalone _router_core)")
    except ImportError:
        logger.debug("Rust router core not available, using Python fallback")


def knn_search(
    query: list[float],
    index_vectors: list[list[float]],
    labels: list[str],
    k: int = 5,
) -> list[tuple[str, float]]:
    """Return top-k (label, l2_distance) pairs from brute-force kNN search."""
    if RUST_AVAILABLE:
        return _rust_knn_search(query, index_vectors, labels, k)  # type: ignore[return-value,no-any-return]
    # Python fallback
    if not index_vectors:
        return []
    k = min(k, len(index_vectors))
    scored = []
    for i, vec in enumerate(index_vectors):
        dist = sum((a - b) ** 2 for a, b in zip(query, vec, strict=False))
        scored.append((labels[i], float(dist)))
    scored.sort(key=lambda x: x[1])
    return scored[:k]


def extract_features(text: str) -> dict[str, int]:
    """Extract routing features from request text."""
    if RUST_AVAILABLE:
        return dict(_rust_extract_features(text))  # type: ignore[arg-type]
    # Python fallback
    lower = text.lower()
    code_markers = sum(
        1 for m in ["```", "def ", "fn ", "class ", "import ", "function", "const ", "let ", "var "] if m in text
    )
    complexity = sum(
        1
        for m in [
            "compare",
            "analyze",
            "multiple",
            "synthesis",
            "comprehensive",
            "trade-off",
            "pros and cons",
            "step-by-step",
        ]
        if m in lower
    )
    return {
        "estimated_tokens": len(text.split()),
        "code_marker_count": code_markers,
        "complexity_indicators": complexity,
        "is_question": 1 if "?" in text else 0,
        "has_system_context": 1 if len(text) > 200 else 0,
    }


def score_confidence(features: dict[str, int]) -> float:
    """Score confidence from extracted features."""
    if RUST_AVAILABLE:
        return float(_rust_score_confidence(features))
    # Python fallback
    signal_count = sum(
        [
            features.get("complexity_indicators", 0) > 0,
            features.get("code_marker_count", 0) > 0,
            features.get("estimated_tokens", 0) > 50,
        ]
    )
    return {0: 0.6, 1: 0.72, 2: 0.85}.get(signal_count, 0.93)


def classify_privacy(text: str) -> str:
    """Classify text as 'personal', 'private', or 'external'."""
    if RUST_AVAILABLE:
        return str(_rust_classify_privacy(text))
    # Python fallback
    lower = text.lower()
    personal_kw = [
        "my name is",
        "my address",
        "my ssn",
        "my social security",
        "my date of birth",
        "my medical",
        "my health",
        "my diagnosis",
        "my credit card",
        "my bank account",
        "my password",
        "my private key",
        "my phone",
        "my email",
    ]
    if any(kw in lower for kw in personal_kw):
        return "personal"
    private_kw = [
        "internal",
        "confidential",
        "proprietary",
        "secret",
        "our company",
        "our revenue",
        "our customers",
        "our api key",
        "our database",
    ]
    if any(kw in lower for kw in private_kw):
        return "private"
    return "external"
