"""AgentDiscovery - 基于 OrganizationContext 的 Agent 发现与推荐"""

from __future__ import annotations

import logging

from agentkit.org.context import AgentProfile, OrganizationContext

logger = logging.getLogger(__name__)


class AgentDiscovery:
    """Agent 发现 - 提供多种维度的 Agent 查询与推荐"""

    def __init__(self, org_context: OrganizationContext) -> None:
        self._org = org_context

    def discover_by_capability(self, required_capabilities: list[str]) -> list[AgentProfile]:
        """按能力标签发现 Agent（需满足所有指定能力）"""
        result: list[AgentProfile] = []
        for profile in self._org.list_agents():
            profile_caps_lower = {c.lower() for c in profile.capabilities}
            if all(cap.lower() in profile_caps_lower for cap in required_capabilities):
                result.append(profile)
        return result

    def discover_by_execution_mode(self, mode: str) -> list[AgentProfile]:
        """按执行模式发现 Agent"""
        return [
            p for p in self._org.list_agents()
            if p.execution_mode == mode
        ]

    def discover_available(self) -> list[AgentProfile]:
        """发现所有可用的 Agent"""
        return [p for p in self._org.list_agents() if p.availability]

    def recommend_agent(
        self,
        required_capabilities: list[str],
        preferred_mode: str | None = None,
    ) -> AgentProfile | None:
        """推荐最佳 Agent

        逻辑：
        1. 如果指定了 preferred_mode，先按 execution_mode 过滤
        2. 然后按能力匹配 + 负载均衡找到最佳 Agent
        3. 如果没有能力匹配的，回退到任何可用 Agent
        """
        # 按能力发现候选
        candidates = self.discover_by_capability(required_capabilities)

        # 过滤不可用
        candidates = [c for c in candidates if c.availability]

        # 如果指定了 preferred_mode，优先匹配
        if preferred_mode is not None:
            mode_matched = [c for c in candidates if c.execution_mode == preferred_mode]
            if mode_matched:
                mode_matched.sort(key=lambda p: p.current_load)
                return mode_matched[0]

        # 按负载排序返回最佳
        if candidates:
            candidates.sort(key=lambda p: p.current_load)
            return candidates[0]

        # 回退：返回任何可用 Agent
        available = self.discover_available()
        if available:
            available.sort(key=lambda p: p.current_load)
            return available[0]

        return None
