import os
from typing import Optional

from .client import SeltzClient
from .exceptions import SeltzConfigurationError
from .services import Includes, SearchResponse
from .services.search_service import SearchService


class Seltz:
    """Main Seltz SDK client for interacting with the Seltz API."""

    _ENDPOINT: str = "grpc.seltz.ai"

    def __init__(
        self,
        api_key: Optional[str] = os.environ.get("SELTZ_API_KEY"),
        endpoint: str = _ENDPOINT,
        insecure: bool = False,
    ):
        """Initialize the Seltz client.

        Args:
            api_key: API key for authentication. If None, will try to read from SELTZ_API_KEY environment variable
            endpoint: The API endpoint to connect to (default: grpc.seltz.ai)
            insecure: Whether to use insecure connection (default: False)

        Returns:
            Seltz: A new Seltz client instance

        Raises:
            SeltzConfigurationError: If no API key is provided
        """
        if api_key is None:
            raise SeltzConfigurationError("No API key provided")
        self._client = SeltzClient(
            endpoint=endpoint, api_key=api_key, insecure=insecure
        )
        self._search = SearchService(self._client.channel, self._client.api_key)

    def search(
        self,
        query: str,
        *,
        includes: Optional[Includes] = None,
        context: Optional[str] = None,
        profile: Optional[str] = None,
    ) -> SearchResponse:
        """Perform a search query.

        This method searches using the Seltz AI-powered search engine. You can
        customize the search behavior using optional parameters.

        Args:
            query: The search query string. Keep this concise for best performance.
            includes: Protobuf Includes message configuring result options (e.g.
                max_documents). If not specified, server defaults are used.
            context: Additional context for the query. Include as much relevant
                information as feasible to improve search quality. For example,
                "user is looking for Python documentation for beginners".
            profile: Search profile to use. Different profiles may use different
                ranking algorithms or have different data source preferences.

        Returns:
            SearchResponse: Protobuf search response. Iterate results via
                response.documents. Note: optional string fields on Document
                (url, content) return "" when unset, not None. Use
                `if doc.url:` rather than `doc.url is not None` to check presence.

        Raises:
            SeltzAuthenticationError: If API key is invalid
            SeltzConnectionError: If connection to API fails
            SeltzTimeoutError: If request times out
            SeltzRateLimitError: If rate limit is exceeded
            SeltzAPIError: For other API errors
        """
        return self._search.search(
            query=query,
            includes=includes,
            context=context,
            profile=profile,
        )
