"""
Agent Status SDK - Outside-in monitoring for AI agents.

Quick start:
    import agent_status

    agent_status.init(api_key="rora_xxx")

    # Register an agent for continuous monitoring
    agent = agent_status.register(
        endpoint="https://api.mycompany.com/chat",
        name="My Agent",
    )

    # Check status
    status = agent_status.status(agent.id)
    print(status.verdict)  # UP, DEGRADED, DOWN

    # One-off validation
    result = agent_status.run(
        endpoint="https://api.example.com/chat",
        prompts=["Hello"],
    )
"""

from typing import Dict, List, Optional

from agent_status.client import (
    AgentStatusClient,
    AgentStatusError,
    AgentStatusAuthError,
    AgentStatusNotFoundError,
    AgentStatusRateLimitError,
)
from agent_status.models import (
    Agent,
    AgentStatus,
    RunResult,
    Verdict,
)

__version__ = "1.0.0"

# Backward compatibility aliases
RoraClient = AgentStatusClient
RoraError = AgentStatusError
RoraAuthError = AgentStatusAuthError
RoraNotFoundError = AgentStatusNotFoundError
RoraRateLimitError = AgentStatusRateLimitError

__all__ = [
    "init",
    "register",
    "status",
    "run",
    "get_agent",
    "list_agents",
    "delete_agent",
    "Agent",
    "AgentStatus",
    "RunResult",
    "Verdict",
    "AgentStatusClient",
    "AgentStatusError",
    "AgentStatusAuthError",
    "AgentStatusNotFoundError",
    "AgentStatusRateLimitError",
    "RoraClient",
    "RoraError",
    "RoraAuthError",
    "RoraNotFoundError",
    "RoraRateLimitError",
    "integrations",
]

_client: Optional[AgentStatusClient] = None


def init(
    api_key: str,
    base_url: str = "https://api.fabric.carmel.so",
) -> None:
    """
    Initialize the Agent Status SDK with your API key.

    Args:
        api_key: Your API key (starts with 'rora_' or use your Fabric API key)
        base_url: API base URL (default: production)

    Example:
        import agent_status
        agent_status.init(api_key="rora_xxx")
    """
    global _client
    _client = AgentStatusClient(api_key=api_key, base_url=base_url)


def _get_client() -> AgentStatusClient:
    if _client is None:
        raise RuntimeError(
            "Agent Status SDK not initialized. Call agent_status.init(api_key='...') first."
        )
    return _client


def register(
    endpoint: str,
    name: str,
    *,
    auth: Optional[Dict] = None,
    prompts: Optional[List[str]] = None,
    interval_minutes: int = 360,
    max_nodes_per_run: int = 5,
    geos: Optional[List[str]] = None,
    eval_type: str = "basic",
    gold_prompt_profile: str = "general",
    timeout_ms: int = 30000,
    streaming: bool = False,
    inject_geo_context: bool = False,
) -> Agent:
    """
    Register an agent for continuous monitoring.

    Args:
        endpoint: The agent's HTTP endpoint URL
        name: Display name for the agent
        auth: Authentication config, e.g. {"type": "bearer", "token": "..."}
        prompts: Custom prompts to send (default: uses gold prompts based on profile)
        interval_minutes: How often to probe (default: 360 = every 6 hours)
        max_nodes_per_run: Number of distributed nodes per probe (default: 5)
        geos: Geographic regions to probe from (default: all)
        eval_type: Evaluation type: "basic", "llm_judge", or "all"
        gold_prompt_profile: Profile for gold prompts: "general", "search_agent", etc.
        timeout_ms: Request timeout in milliseconds (default: 30000)
        streaming: Whether the agent uses streaming responses
        inject_geo_context: Inject probe node's location into prompts

    Returns:
        Agent object with id, name, endpoint, status, etc.

    Example:
        agent = agent_status.register(
            endpoint="https://api.mycompany.com/chat",
            name="Support Bot",
            auth={"type": "bearer", "token": "sk-xxx"},
            interval_minutes=60,
        )
    """
    return _get_client().register(
        endpoint=endpoint,
        name=name,
        auth=auth,
        prompts=prompts,
        interval_minutes=interval_minutes,
        max_nodes_per_run=max_nodes_per_run,
        geos=geos,
        eval_type=eval_type,
        gold_prompt_profile=gold_prompt_profile,
        timeout_ms=timeout_ms,
        streaming=streaming,
        inject_geo_context=inject_geo_context,
    )


def status(agent_id: str) -> AgentStatus:
    """
    Get the current status of a registered agent.

    Args:
        agent_id: The agent's UUID

    Returns:
        AgentStatus with verdict, uptime, latency, last_checked, etc.

    Example:
        status = agent_status.status("abc-123-def")
        print(status.verdict)  # UP, DEGRADED, DOWN
        print(status.uptime_24h)  # 99.5
    """
    return _get_client().status(agent_id)


def run(
    endpoint: str,
    prompts: List[str],
    *,
    auth: Optional[Dict] = None,
    max_nodes: int = 3,
    geos: Optional[List[str]] = None,
    timeout_ms: int = 30000,
    eval_type: str = "basic",
) -> RunResult:
    """
    Run a one-off validation against an endpoint.

    This does NOT register the agent for continuous monitoring.
    Use this for quick checks or testing.

    Args:
        endpoint: The agent's HTTP endpoint URL
        prompts: List of prompts to send
        auth: Authentication config
        max_nodes: Number of distributed nodes to use (default: 3)
        geos: Geographic regions to probe from
        timeout_ms: Request timeout in milliseconds
        eval_type: Evaluation type: "basic", "llm_judge", or "all"

    Returns:
        RunResult with verdict, latency percentiles, by_region breakdown, etc.

    Example:
        result = agent_status.run(
            endpoint="https://api.example.com/chat",
            prompts=["What is 2+2?", "Hello"],
        )
        print(result.verdict)  # UP, DEGRADED, DOWN
        print(result.latency_p95)  # 1234
    """
    return _get_client().run(
        endpoint=endpoint,
        prompts=prompts,
        auth=auth,
        max_nodes=max_nodes,
        geos=geos,
        timeout_ms=timeout_ms,
        eval_type=eval_type,
    )


def get_agent(agent_id: str) -> Agent:
    """
    Get an agent by ID.

    Args:
        agent_id: The agent's UUID

    Returns:
        Agent object
    """
    return _get_client().get_agent(agent_id)


def list_agents() -> List[Agent]:
    """
    List all registered agents.

    Returns:
        List of Agent objects
    """
    return _get_client().list_agents()


def delete_agent(agent_id: str) -> bool:
    """
    Delete a registered agent.

    Args:
        agent_id: The agent's UUID

    Returns:
        True if deleted successfully
    """
    return _get_client().delete_agent(agent_id)
