"""Embed method for inference namespace."""

from __future__ import annotations

from typing import TYPE_CHECKING, Any, cast

from pinecone._internal.logging import get_logger
from pinecone._internal.validation import require_non_empty
from pinecone.models.inference import EmbedRequest, EmbedResponse


if TYPE_CHECKING:
    from pinecone.__interface__ import EmbedParameters
    from pinecone.__interface__.inference import EmbeddingResponseProtocol


logger = get_logger(__name__)


def embed(
    self: Any,
    model: str,
    *,
    texts: list[str],
    parameters: EmbedParameters | dict[str, Any] | None = None,
    timeout: float | None = None,
) -> EmbeddingResponseProtocol:
    """Generate embeddings for texts using specified model.

    This method demonstrates the complete request/response cycle:
    1. Validate inputs
    2. Build request model
    3. Make HTTP request with error handling
    4. Transform response via adapter
    5. Log success metrics

    Args:
            model: Name of the embedding model to use (e.g., "multilingual-e5-large")
            texts: List of text strings to embed (non-empty)
            parameters: Optional model-specific parameters. See EmbedParameters for
                common options. Additional parameters can be passed as a dict.
            timeout: Optional request timeout in seconds

    Returns:
        EmbeddingResponse containing:
            - embeddings: List of embedding vectors
            - model: Name of the model used
            - usage: Token usage information

    Raises:
        ValueError: If inputs are invalid (empty texts, missing model)
        APIError: If the API returns an error response
        APIConnectionError: If the request fails to connect
        TimeoutError: If the request times out

    Example:
            >>> response = inference.embed(
            ...     model="multilingual-e5-large",
            ...     texts=["Hello world", "Goodbye world"],
            ...     parameters={"input_type": "passage", "truncate": "END"},
            ... )
            >>> print(f"Generated {len(response.embeddings)} embeddings")
            >>> print(f"Dimension: {len(response.embeddings[0])}")
            >>> print(f"Tokens used: {response.usage.total_tokens}")

        Example with query input type:
            >>> response = inference.embed(
            ...     model="multilingual-e5-large",
            ...     texts=["What is machine learning?"],
            ...     parameters={"input_type": "query", "truncate": "END"},
            ... )

    Example with timeout:
            >>> try:
            ...     response = inference.embed(
            ...         model="multilingual-e5-large",
            ...         texts=["Hello world"],
            ...         timeout=5.0,
            ...     )
            ... except TimeoutError:
            ...     print("Request timed out after 5 seconds")

    Discovery:
        In interactive environments (REPL, notebooks), use these commands to explore:

        >>> from pinecone import Pinecone
        >>> pc = Pinecone(api_key="...")
        >>> # See available methods
        >>> dir(pc.inference)
        ['embed', 'rerank']
        >>> # Get detailed help
        >>> help(pc.inference.embed)
        >>> # Tab completion works
        >>> pc.inference.<TAB>  # Shows: embed, rerank
    """
    # Validation
    require_non_empty("model", model)
    require_non_empty("texts", texts)

    logger.info(
        "Generating embeddings",
        model=model,
        text_count=len(texts),
        has_parameters=parameters is not None,
    )

    # Build request - convert texts to input format expected by API
    request: EmbedRequest = EmbedRequest(
        model=model,
        inputs=[{"text": text} for text in texts],
        parameters=cast("dict[str, Any] | None", parameters),
    )

    # Make HTTP request
    data: dict[str, Any] = self._make_inference_request("embed", request, timeout)

    # Transform response via adapter
    result: EmbedResponse = self._adapter.to_embed_response(data)

    logger.debug(
        "Embeddings generated successfully",
        model=result.model,
        embedding_count=len(result.embeddings),
        total_tokens=result.usage.total_tokens,
    )

    return result
