"""MCP Gateway API Client."""

import os
import requests
from typing import Optional, Dict, Any
from .exceptions import AuthenticationError, APIError
from .resources import WorkspaceResource, BackendResource, AgentResource, CatalogResource


class MCPGatewayClient:
    """
    Main client for interacting with the MCP Gateway API.
    
    Usage:
        # With token
        client = MCPGatewayClient(token="your-token")
        
        # With email/password
        client = MCPGatewayClient()
        client.login(email="user@example.com", password="password")
        
        # Use resources
        workspaces = client.workspaces.list()
        workspace = client.workspaces.create(name="Production")
        backend = client.backends.add(workspace['id'], name="Gmail", url="...")
    """
    
    def __init__(
        self,
        api_url: Optional[str] = None,
        token: Optional[str] = None,
        timeout: int = 30
    ):
        """
        Initialize the MCP Gateway client.
        
        Args:
            api_url: API base URL. Defaults to https://api.mcpgw.io/api/v1
            token: Authentication token
            timeout: Request timeout in seconds
        """
        self.api_url = api_url or os.getenv('MCPGW_API_URL', 'https://api.mcpgw.io/api/v1')
        self.token = token or os.getenv('MCPGW_TOKEN')
        self.timeout = timeout
        
        # Initialize resource endpoints
        self.workspaces = WorkspaceResource(self)
        self.backends = BackendResource(self)
        self.agents = AgentResource(self)
        self.catalog = CatalogResource(self)
    
    def login(self, email: str, password: str) -> Dict[str, Any]:
        """
        Authenticate with email and password.
        
        Args:
            email: User email
            password: User password
            
        Returns:
            Authentication response with token
            
        Raises:
            AuthenticationError: If login fails
        """
        response = self.request(
            'POST',
            '/auth/login',
            json={'email': email, 'password': password},
            authenticated=False
        )
        
        if 'token' in response:
            self.token = response['token']
        
        return response
    
    def request(
        self,
        method: str,
        endpoint: str,
        authenticated: bool = True,
        **kwargs
    ) -> Any:
        """
        Make an HTTP request to the API.
        
        Args:
            method: HTTP method (GET, POST, PUT, DELETE, etc.)
            endpoint: API endpoint path
            authenticated: Whether to include authentication token
            **kwargs: Additional arguments passed to requests
            
        Returns:
            API response data
            
        Raises:
            AuthenticationError: If authentication is required but no token
            APIError: If the API returns an error
        """
        url = f"{self.api_url.rstrip('/')}/{endpoint.lstrip('/')}"
        
        headers = kwargs.pop('headers', {})
        if authenticated:
            if not self.token:
                raise AuthenticationError("No authentication token. Please login first.")
            headers['Authorization'] = f'Bearer {self.token}'
        
        headers.setdefault('Content-Type', 'application/json')
        
        try:
            response = requests.request(
                method,
                url,
                headers=headers,
                timeout=self.timeout,
                **kwargs
            )
            
            # Handle authentication errors
            if response.status_code == 401:
                raise AuthenticationError("Authentication failed. Please check your credentials.")
            
            # Handle other errors
            if not response.ok:
                error_msg = f"API Error: {response.status_code}"
                try:
                    error_data = response.json()
                    if 'message' in error_data:
                        error_msg = error_data['message']
                    elif 'error' in error_data:
                        error_msg = error_data['error']
                except Exception:
                    error_msg = response.text or error_msg
                
                raise APIError(error_msg, status_code=response.status_code, response=response)
            
            # Return JSON response or empty dict
            try:
                return response.json()
            except Exception:
                return {}
                
        except requests.exceptions.RequestException as e:
            raise APIError(f"Request failed: {str(e)}")
