"""Mantr API Client"""

from typing import List, Optional
import requests
from requests.adapters import HTTPAdapter
from urllib3.util.retry import Retry

from .models import WalkRequest, WalkResponse
from .exceptions import (
    MantrError,
    AuthenticationError,
    InsufficientCreditsError,
    RateLimitError,
)


class MantrClient:
    """
    Official Python client for Mantr API.
    
    Example:
        >>> from mantr import MantrClient
        >>> client = MantrClient(api_key='vak_live_...')
        >>> result = client.walk(['dharma', 'karma'])
        >>> print(result.paths)
    """
    
    def __init__(
        self,
        api_key: str,
        base_url: str = "https://api.mantr.net",
        timeout: int = 30,
    ):
        """
        Initialize Mantr client.
        
        Args:
            api_key: Your Mantr API key (starts with 'vak_')
            base_url: API base URL (default: https://api.mantr.net)
            timeout: Request timeout in seconds (default: 30)
        
        Raises:
            ValueError: If API key format is invalid
        """
        if not api_key or not api_key.startswith('vak_'):
            raise ValueError("Invalid API key format. Must start with 'vak_'")
        
        self.api_key = api_key
        self.base_url = base_url.rstrip('/')
        self.timeout = timeout
        
        # Configure session with retry logic
        self.session = requests.Session()
        retry_strategy = Retry(
            total=3,
            backoff_factor=0.5,
            status_forcelist=[429, 500, 502, 503, 504],
            allowed_methods=["POST", "GET"]
        )
        adapter = HTTPAdapter(max_retries=retry_strategy)
        self.session.mount("http://", adapter)
        self.session.mount("https://", adapter)
        
        # Set default headers
        self.session.headers.update({
            'Authorization': f'Bearer {api_key}',
            'User-Agent': 'mantr-python/1.0.0',
            'Content-Type': 'application/json',
        })
    
    def walk(
        self,
        phonemes: List[str],
        pod: Optional[str] = None,
        depth: int = 3,
        limit: int = 100,
    ) -> WalkResponse:
        """
        Traverse the semantic graph to discover connections.
        
        Args:
            phonemes: List of Sanskrit phoneme concepts to explore
            pod: Optional context pod for isolated knowledge domains
            depth: Maximum traversal depth (1-10, default: 3)
            limit: Maximum number of results (1-1000, default: 100)
        
        Returns:
            WalkResponse containing paths, latency, and credits used
        
        Raises:
            AuthenticationError: Invalid API key
            InsufficientCreditsError: Account out of credits
            RateLimitError: Too many requests
            MantrError: Other API errors
        
        Example:
            >>> result = client.walk(['dharma', 'karma', 'yoga'])
            >>> for path in result.paths:
            ...     print(f"Path: {' → '.join(path.nodes)} (score: {path.score})")
        """
        # Validate and build request
        request = WalkRequest(
            phonemes=phonemes,
            pod=pod,
            depth=depth,
            limit=limit
        )
        
        try:
            response = self.session.post(
                f"{self.base_url}/v1/walk",
                json=request.model_dump(exclude_none=True),
                timeout=self.timeout
            )
            
            # Handle errors
            if response.status_code == 401:
                raise AuthenticationError("Invalid API key")
            elif response.status_code == 402:
                raise InsufficientCreditsError("Insufficient credits. Upgrade your plan or wait for monthly reset.")
            elif response.status_code == 429:
                retry_after = response.headers.get('Retry-After')
                raise RateLimitError(
                    "Rate limit exceeded",
                    retry_after=int(retry_after) if retry_after else None
                )
            elif not response.ok:
                raise MantrError(f"API error ({response.status_code}): {response.text}")
            
            # Parse and return response
            return WalkResponse(**response.json())
        
        except requests.exceptions.Timeout:
            raise MantrError(f"Request timed out after {self.timeout}s")
        except requests.exceptions.RequestException as e:
            raise MantrError(f"Network error: {str(e)}")
    
    def create_pod(self, name: str, description: str = "") -> dict:
        """
        Create a context pod for isolated knowledge storage.
        
        Args:
            name: Unique pod identifier
            description: Optional pod description
        
        Returns:
            dict with pod details
        
        Note:
            This feature is coming soon in a future release.
        """
        raise NotImplementedError(
            "Pod creation is coming soon. Stay tuned for updates!"
        )
    
    def __enter__(self):
        """Context manager entry"""
        return self
    
    def __exit__(self, *args):
        """Context manager exit - cleanup session"""
        self.session.close()
    
    def __repr__(self):
        return f"MantrClient(base_url='{self.base_url}')"
