"""Web Search tool using generated API client."""

from __future__ import annotations

from .._config import SDKConfig
from .._api.client import (
    BaseResource,
    AsyncBaseResource,
    SyncSearchSearchAPI,
    SearchSearchAPI,
)
from .._api.generated.search.search__api__search.models import (
    SearchQueryRequest,
    URLFetchRequest,
    SearchResponse,
    Citation,
    UserLocationRequest,
    SearchRequestList,
)


# Re-export UserLocation as alias for convenience
UserLocation = UserLocationRequest


class SearchResource(BaseResource):
    """Web Search tool (sync).

    Uses generated SyncSearchSearchAPI client.
    """

    def __init__(self, config: SDKConfig):
        super().__init__(config)
        self._api = SyncSearchSearchAPI(self._http_client)

    def query(
        self,
        query: str,
        *,
        model: str | None = None,
        max_tokens: int | None = None,
        max_searches: int | None = None,
        allowed_domains: list[str] | None = None,
        blocked_domains: list[str] | None = None,
        user_location: UserLocation | None = None,
    ) -> SearchResponse:
        """
        Execute a web search query.

        Args:
            query: Search query
            model: Claude model to use (default: claude-3-5-haiku-20241022)
            max_tokens: Maximum tokens for response (default: 1024)
            max_searches: Maximum number of web searches (default: 5)
            allowed_domains: Only search these domains
            blocked_domains: Exclude these domains from search
            user_location: User location for localized search

        Returns:
            SearchResponse with content and citations
        """
        # Build request with only non-None values
        kwargs = {"query": query}
        if model is not None:
            kwargs["model"] = model
        if max_tokens is not None:
            kwargs["max_tokens"] = max_tokens
        if max_searches is not None:
            kwargs["max_searches"] = max_searches
        if allowed_domains is not None:
            kwargs["allowed_domains"] = allowed_domains
        if blocked_domains is not None:
            kwargs["blocked_domains"] = blocked_domains
        if user_location is not None:
            kwargs["user_location"] = user_location

        request = SearchQueryRequest(**kwargs)
        return self._api.query_create(request)

    def fetch(
        self,
        url: str,
        *,
        prompt: str | None = None,
        model: str | None = None,
        max_tokens: int | None = None,
    ) -> SearchResponse:
        """
        Fetch and analyze URL content.

        Args:
            url: URL to fetch and analyze
            prompt: Prompt for analyzing the content (default: "Summarize this page")
            model: Claude model to use (default: claude-3-5-haiku-20241022)
            max_tokens: Maximum tokens for response (default: 1024)

        Returns:
            SearchResponse with analyzed content
        """
        # Build request with only non-None values
        kwargs = {"url": url}
        if prompt is not None:
            kwargs["prompt"] = prompt
        if model is not None:
            kwargs["model"] = model
        if max_tokens is not None:
            kwargs["max_tokens"] = max_tokens

        request = URLFetchRequest(**kwargs)
        return self._api.fetch_create(request)

    def list(self) -> list[SearchRequestList]:
        """
        List search history.

        Returns:
            List of search request summaries (last 100 records)
        """
        return self._api.list()


class AsyncSearchResource(AsyncBaseResource):
    """Web Search tool (async).

    Uses generated SearchSearchAPI client.
    """

    def __init__(self, config: SDKConfig):
        super().__init__(config)
        self._api = SearchSearchAPI(self._http_client)

    async def query(
        self,
        query: str,
        *,
        model: str | None = None,
        max_tokens: int | None = None,
        max_searches: int | None = None,
        allowed_domains: list[str] | None = None,
        blocked_domains: list[str] | None = None,
        user_location: UserLocation | None = None,
    ) -> SearchResponse:
        """
        Execute a web search query.

        Args:
            query: Search query
            model: Claude model to use (default: claude-3-5-haiku-20241022)
            max_tokens: Maximum tokens for response (default: 1024)
            max_searches: Maximum number of web searches (default: 5)
            allowed_domains: Only search these domains
            blocked_domains: Exclude these domains from search
            user_location: User location for localized search

        Returns:
            SearchResponse with content and citations
        """
        # Build request with only non-None values
        kwargs = {"query": query}
        if model is not None:
            kwargs["model"] = model
        if max_tokens is not None:
            kwargs["max_tokens"] = max_tokens
        if max_searches is not None:
            kwargs["max_searches"] = max_searches
        if allowed_domains is not None:
            kwargs["allowed_domains"] = allowed_domains
        if blocked_domains is not None:
            kwargs["blocked_domains"] = blocked_domains
        if user_location is not None:
            kwargs["user_location"] = user_location

        request = SearchQueryRequest(**kwargs)
        return await self._api.query_create(request)

    async def fetch(
        self,
        url: str,
        *,
        prompt: str | None = None,
        model: str | None = None,
        max_tokens: int | None = None,
    ) -> SearchResponse:
        """
        Fetch and analyze URL content.

        Args:
            url: URL to fetch and analyze
            prompt: Prompt for analyzing the content (default: "Summarize this page")
            model: Claude model to use (default: claude-3-5-haiku-20241022)
            max_tokens: Maximum tokens for response (default: 1024)

        Returns:
            SearchResponse with analyzed content
        """
        # Build request with only non-None values
        kwargs = {"url": url}
        if prompt is not None:
            kwargs["prompt"] = prompt
        if model is not None:
            kwargs["model"] = model
        if max_tokens is not None:
            kwargs["max_tokens"] = max_tokens

        request = URLFetchRequest(**kwargs)
        return await self._api.fetch_create(request)

    async def list(self) -> list[SearchRequestList]:
        """
        List search history.

        Returns:
            List of search request summaries (last 100 records)
        """
        return await self._api.list()


__all__ = [
    "SearchResource",
    "AsyncSearchResource",
    # Models
    "SearchResponse",
    "Citation",
    "UserLocation",
    "SearchRequestList",
    "SearchQueryRequest",
    "URLFetchRequest",
    "UserLocationRequest",
]
