"""Hive router -- routes requests across Hive members' shared GPUs.

Routing priority:
1. Check privacy → PRIVATE stays local; SENSITIVE is never shared (main router/dispatcher).
2. Check local availability → use own GPU if model available
3. Check Hive members → route to highest-karma member with model (respects sharing controls)
4. Cloud fallback
"""

from __future__ import annotations

import logging
from typing import TYPE_CHECKING

from llmhosts.hive.models import HiveRoutingDecision, PrivacyTier
from llmhosts.hive.sharing import can_share_model

if TYPE_CHECKING:
    from llmhosts.hive.karma import KarmaEngine
    from llmhosts.hive.manager import HiveManager
    from llmhosts.hive.privacy import PrivacyClassifier

logger = logging.getLogger(__name__)


class HiveRouter:
    """Routes requests across Hive members' shared GPUs.

    Routing priority:
    1. Check privacy → PRIVATE stays local
    2. Check local availability → use own GPU if model available
    3. Check Hive members → route to highest-karma member with model
    4. Cloud fallback
    """

    def __init__(
        self,
        hive_manager: HiveManager,
        privacy_classifier: PrivacyClassifier,
        karma_engine: KarmaEngine,
    ) -> None:
        self._hive_manager = hive_manager
        self._privacy = privacy_classifier
        self._karma = karma_engine

    async def route(self, prompt: str, model: str) -> HiveRoutingDecision:
        """Route a request with Hive awareness."""
        # 1. Privacy check - PRIVATE never leaves local
        classification = self._privacy.classify(prompt)
        if classification.tier == PrivacyTier.PRIVATE:
            return HiveRoutingDecision(
                use_hive=False,
                target_member_id=None,
                target_device_id=None,
                privacy_tier=PrivacyTier.PRIVATE,
                karma_priority=0.0,
                reason="Sensitive content: stays local (PRIVATE tier)",
            )

        # 2. No Hive - local or cloud fallback
        hive = await self._hive_manager.get_hive()
        if hive is None or len(hive.members) <= 1:
            return HiveRoutingDecision(
                use_hive=False,
                target_member_id=None,
                target_device_id=None,
                privacy_tier=classification.tier,
                karma_priority=1.0,
                reason="No Hive or solo member: use local or cloud",
            )

        # 3. Get karma-sorted members (excluding self for routing to others)
        current_member_id = self._hive_manager.get_current_member_id()
        priority_order = await self._karma.get_priority_order()

        # Filter out current user - we want to route TO another member
        candidates = [(mid, karma) for mid, karma in priority_order if mid != current_member_id]

        if not candidates:
            return HiveRoutingDecision(
                use_hive=False,
                target_member_id=None,
                target_device_id=None,
                privacy_tier=classification.tier,
                karma_priority=1.0,
                reason="No other Hive members to route to",
            )

        # Pick highest-karma member who can share this model (sharing_enabled, schedule, shared_models)
        for best_member_id, best_karma in candidates:
            best_member = next((m for m in hive.members if m.id == best_member_id), None)
            if best_member is None:
                continue
            if not can_share_model(best_member, model):
                logger.debug(
                    "Skip member %s for model %s (sharing disabled or outside schedule/whitelist)",
                    best_member.name,
                    model,
                )
                continue
            device_id = best_member.devices[0] if best_member.devices else None
            return HiveRoutingDecision(
                use_hive=True,
                target_member_id=best_member_id,
                target_device_id=device_id,
                privacy_tier=classification.tier,
                karma_priority=best_karma,
                reason=f"Route to Hive member {best_member.name} (karma={best_karma:.2f})",
            )

        return HiveRoutingDecision(
            use_hive=False,
            target_member_id=None,
            target_device_id=None,
            privacy_tier=classification.tier,
            karma_priority=0.0,
            reason="No Hive member available to share this model (sharing off or outside schedule)",
        )
