"""
Asynchronous client for Nova Trading SDK

Example:
    >>> import asyncio
    >>> from nova_trading_sdk import AsyncNovaClient
    >>> 
    >>> async def main():
    ...     async with AsyncNovaClient(api_key="your-key") as client:
    ...         ticker = await client.get_ticker("BTCUSDT")
    ...         print(f"BTC: ${ticker['price']}")
    >>> 
    >>> asyncio.run(main())
"""

import httpx
from typing import Optional, Dict, Any, List
from ..exceptions import NovaAPIError, AuthenticationError

class AsyncNovaClient:
    """
    Async client for Nova Global Keys API
    
    Args:
        api_key: Your Nova Global Keys API key
        base_url: API base URL
        timeout: Request timeout
    """
    
    def __init__(
        self,
        api_key: str,
        base_url: str = "https://api.novatradingkeys.com",
        timeout: int = 30
    ):
        self.api_key = api_key
        self.base_url = base_url.rstrip('/')
        self.timeout = timeout
        self.client = httpx.AsyncClient(
            timeout=timeout,
            headers={
                'Authorization': f'Bearer {api_key}',
                'Content-Type': 'application/json',
                'User-Agent': f'NovaSDK/2.0.0'
            }
        )
    
    async def _request(self, method: str, endpoint: str, **kwargs) -> Dict:
        """Make async request to API"""
        url = f"{self.base_url}{endpoint}"
        
        try:
            response = await self.client.request(method, url, **kwargs)
            data = response.json()
            
            if response.status_code == 401:
                raise AuthenticationError("Invalid API key")
            elif response.status_code >= 400:
                error_msg = data.get('detail', data.get('error', 'Unknown error'))
                raise NovaAPIError(f"API Error ({response.status_code}): {error_msg}")
            
            return data
        except httpx.RequestError as e:
            raise NovaAPIError(f"Request failed: {str(e)}")
    
    async def get_ticker(self, symbol: str) -> Dict:
        """Get current ticker"""
        return await self._request('GET', f'/api/market/tickers/{symbol}')
    
    async def get_balance(self, exchange: str = None) -> Dict:
        """Get account balance"""
        if exchange:
            return await self._request('GET', f'/api/{exchange}/balance')
        return await self._request('GET', '/api/balance/all')
    
    async def place_order(
        self, 
        exchange: str, 
        symbol: str, 
        side: str, 
        quantity: float,
        order_type: str = 'market',
        price: float = None
    ) -> Dict:
        """Place an order"""
        data = {
            'exchange': exchange,
            'symbol': symbol,
            'side': side,
            'order_type': order_type,
            'quantity': quantity
        }
        if price:
            data['price'] = price
        
        return await self._request('POST', '/api/trade/order', json=data)
    
    async def close(self):
        """Close the HTTP client"""
        await self.client.aclose()
    
    async def __aenter__(self):
        return self
    
    async def __aexit__(self, *args):
        await self.close()
