"""
Joy Trust Client

Main client class for interacting with the Joy agent trust network.
"""

import json
import requests
from typing import Dict, List, Optional, Union
from .exceptions import JoyAPIError, JoyValidationError


class JoyClient:
    """Client for the Joy agent trust network API."""
    
    def __init__(self, api_key: Optional[str] = None, base_url: str = "https://joy-connect.fly.dev"):
        """
        Initialize Joy client.
        
        Args:
            api_key: Optional API key for authenticated requests
            base_url: Base URL for the Joy API
        """
        self.api_key = api_key
        self.base_url = base_url.rstrip("/")
        self.session = requests.Session()
        
        if api_key:
            self.session.headers.update({"x-api-key": api_key})
    
    def _request(self, method: str, endpoint: str, **kwargs) -> Dict:
        """Make API request with error handling."""
        url = f"{self.base_url}{endpoint}"
        
        try:
            response = self.session.request(method, url, **kwargs)
            response.raise_for_status()
            return response.json()
        except requests.RequestException as e:
            raise JoyAPIError(f"API request failed: {e}")
        except json.JSONDecodeError as e:
            raise JoyAPIError(f"Invalid JSON response: {e}")
    
    def discover_agents(self, 
                       capability: Optional[str] = None,
                       min_trust: float = 0.0,
                       limit: int = 20) -> List[Dict]:
        """
        Discover agents by capability with minimum trust threshold.
        
        Args:
            capability: Filter by capability (e.g. 'data-analysis', 'code-execution')
            min_trust: Minimum trust score (0.0 to 3.0)
            limit: Maximum number of results
            
        Returns:
            List of agent dictionaries with id, name, trust_score, capabilities
        """
        params = {"limit": limit}
        if capability:
            params["capability"] = capability
        if min_trust > 0:
            params["min_trust"] = min_trust
            
        response = self._request("GET", "/agents/discover", params=params)
        return response.get("agents", [])
    
    def get_agent_trust(self, agent_id: str) -> float:
        """
        Get trust score for a specific agent.
        
        Args:
            agent_id: The agent ID to check
            
        Returns:
            Trust score (0.0 to 3.0)
        """
        response = self._request("GET", f"/agents/{agent_id}")
        return response.get("trust_score", 0.0)
    
    def get_agent_details(self, agent_id: str) -> Dict:
        """
        Get full details for an agent.
        
        Args:
            agent_id: The agent ID to retrieve
            
        Returns:
            Agent details dictionary
        """
        return self._request("GET", f"/agents/{agent_id}")
    
    def vouch_for_agent(self, agent_id: str, message: str = "") -> bool:
        """
        Vouch for an agent (requires API key and successful collaboration).
        
        Args:
            agent_id: Agent to vouch for
            message: Optional vouch message
            
        Returns:
            True if vouch was successful
        """
        if not self.api_key:
            raise JoyValidationError("API key required for vouching")
            
        data = {"agent_id": agent_id, "message": message}
        self._request("POST", "/vouches", json=data)
        return True
    
    def get_vouch_suggestions(self, agent_id: str) -> Dict:
        """
        Get suggested agents to vouch for based on similarity and network.
        
        Args:
            agent_id: Your agent ID for personalized suggestions
            
        Returns:
            Dictionary with 'similar', 'voucher_network', and 'complementary' agents
        """
        return self._request("GET", f"/agents/vouch-suggestions", params={"agentId": agent_id})
    
    def register_agent(self, 
                      name: str,
                      capabilities: List[str],
                      description: str = "",
                      endpoint: Optional[str] = None) -> Dict:
        """
        Register a new agent (requires API key).
        
        Args:
            name: Agent name
            capabilities: List of capabilities
            description: Optional description
            endpoint: Optional API endpoint for the agent
            
        Returns:
            Registration response with agent_id
        """
        if not self.api_key:
            raise JoyValidationError("API key required for agent registration")
            
        data = {
            "name": name,
            "capabilities": capabilities,
            "description": description
        }
        if endpoint:
            data["endpoint"] = endpoint
            
        return self._request("POST", "/agents", json=data)
    
    def search_agents(self, query: str, limit: int = 20) -> List[Dict]:
        """
        Search agents by name or description.
        
        Args:
            query: Search query
            limit: Maximum results
            
        Returns:
            List of matching agents
        """
        params = {"q": query, "limit": limit}
        response = self._request("GET", "/agents/search", params=params)
        return response.get("agents", [])