"""
SuperSearch API Client

Provides a simple interface to the SuperSearch Product API.
"""

import requests
from typing import List, Dict, Any, Optional


class SuperSearchError(Exception):
    """Base exception for SuperSearch SDK errors."""
    pass


class AuthenticationError(SuperSearchError):
    """Raised when API key is invalid or missing."""
    pass


class APIError(SuperSearchError):
    """Raised when API returns an error."""
    pass


class SuperSearch:
    """
    SuperSearch API Client.
    
    A simple interface to search products using natural language queries.
    
    Example:
        >>> client = SuperSearch(api_key="YOUR_API_KEY")
        >>> results = client.search("blue cotton hoodie under 2000")
        >>> for product in results:
        ...     print(product['title'])
    """
    
    DEFAULT_BASE_URL = "https://1ty8wshy87.execute-api.ap-south-1.amazonaws.com"
    
    def __init__(self, api_key: str, base_url: Optional[str] = None):
        """
        Initialize the SuperSearch client.
        
        Args:
            api_key: Your SuperSearch API key
            base_url: Optional custom API base URL
        """
        if not api_key:
            raise AuthenticationError("API key is required")
        
        self.api_key = api_key
        self.base_url = (base_url or self.DEFAULT_BASE_URL).rstrip("/")
        self._session = requests.Session()
        self._session.headers.update({
            "Content-Type": "application/json",
            "X-API-Key": self.api_key
        })
    
    def _request(self, endpoint: str, query: str, limit: int) -> List[Dict[str, Any]]:
        """Make a request to the API."""
        url = f"{self.base_url}{endpoint}"
        payload = {
            "query": query,
            "limit": min(limit, 250)  # API max is 250
        }
        
        try:
            response = self._session.post(url, json=payload, timeout=30)
        except requests.RequestException as e:
            raise APIError(f"Request failed: {e}")
        
        if response.status_code == 401:
            raise AuthenticationError("Invalid API key")
        elif response.status_code == 403:
            raise AuthenticationError("API key not authorized")
        elif response.status_code != 200:
            raise APIError(f"API error: {response.status_code} - {response.text}")
        
        data = response.json()
        
        if data.get("error"):
            raise APIError(data["error"])
        
        return data.get("products", [])
    
    def search(self, query: str, limit: int = 10) -> List[Dict[str, Any]]:
        """
        Search for products using natural language.
        
        The API automatically extracts attributes from your query:
        - Product type (t-shirt, shoes, jacket)
        - Brand (Nike, Adidas, H&M)
        - Color (red, blue, navy)
        - Size (XL, medium, size 10)
        - Material (cotton, leather, denim)
        - Gender (men, women, unisex)
        - Price (under 2000, above 500)
        
        Args:
            query: Natural language search query
            limit: Maximum number of results (default: 10, max: 250)
            
        Returns:
            List of product dictionaries with keys like:
            - title, brand, price, actual_price
            - colour, size, material, gender_type
            - product_url, first_image, image_urls
            - available, variant_id
            
        Example:
            >>> results = client.search("red cotton t-shirt for women under 1000")
        """
        return self._request("/api/search", query, limit)
    
    def pdp_search(self, query: str, limit: int = 10) -> List[Dict[str, Any]]:
        """
        AEO-optimized search for AI agents.
        
        Returns more comprehensive product data including additional
        fields like created_at, updated_at, sku, and aeo_description.
        
        Args:
            query: Natural language search query
            limit: Maximum number of results (default: 10, max: 250)
            
        Returns:
            List of detailed product dictionaries
            
        Example:
            >>> results = client.pdp_search("running shoes for women")
        """
        return self._request("/api/pdp_search", query, limit)
    
    def suggestions(self) -> List[str]:
        """
        Get example search suggestions.
        
        Returns a list of example natural language queries that
        demonstrate the API's capabilities.
        
        Returns:
            List of example query strings
            
        Example:
            >>> suggestions = client.suggestions()
            >>> for s in suggestions:
            ...     print(s)
        """
        url = f"{self.base_url}/api/suggestions"
        
        try:
            response = self._session.get(url, timeout=30)
        except requests.RequestException as e:
            raise APIError(f"Request failed: {e}")
        
        if response.status_code != 200:
            raise APIError(f"API error: {response.status_code}")
        
        data = response.json()
        return data.get("suggestions", [])
