"""List models method for async inference namespace."""

from __future__ import annotations

from typing import TYPE_CHECKING, Any

from pinecone._internal.logging import get_logger


if TYPE_CHECKING:
    from pinecone.__interface__.inference import ListModelsResponseProtocol
    from pinecone.models.inference import ListModelsResponse


logger = get_logger(__name__)


async def list_models(
    self: Any,
    *,
    model_type: str | None = None,
    vector_type: str | None = None,
    timeout: float | None = None,
) -> ListModelsResponseProtocol:
    """List available embedding and reranking models asynchronously.

    Args:
        model_type: Optional filter by model type ('embed' or 'rerank')
        vector_type: Optional filter by vector type ('dense' or 'sparse') for embedding models
        timeout: Optional request timeout in seconds

    Returns:
        ListModelsResponse containing:
            - models: List of ModelInfo objects with model details

    Raises:
        APIError: If the API returns an error response
        APIConnectionError: If the request fails to connect
        TimeoutError: If the request times out

    Example:
        >>> async with AsyncPinecone(api_key="...") as pc:
        ...     response = await pc.inference.list_models()
        ...     for model in response.models:
        ...         print(f"{model.model} ({model.type}): {model.short_description}")
        ...         if model.type == "embed" and model.supported_dimensions:
        ...             print(f"  Dimensions: {model.supported_dimensions}")

    Example with filters:
        >>> async with AsyncPinecone(api_key="...") as pc:
        ...     # List only embedding models
        ...     response = await pc.inference.list_models(model_type="embed")
        ...     # List only sparse embedding models
        ...     response = await pc.inference.list_models(model_type="embed", vector_type="sparse")

    Example exploring model parameters:
        >>> async with AsyncPinecone(api_key="...") as pc:
        ...     response = await pc.inference.list_models()
        ...     model = response.models[0]
        ...     print(f"Model: {model.model}")
        ...     print(f"Provider: {model.provider_name}")
        ...     print(f"Max sequence length: {model.max_sequence_length}")
        ...     for param in model.supported_parameters:
        ...         print(f"  {param.parameter} ({param.value_type}): required={param.required}")
    """
    logger.info(
        "Listing available models",
        type_filter=model_type,
        vector_type_filter=vector_type,
    )

    # Build query parameters
    params: dict[str, str] = {}
    if model_type is not None:
        params["type"] = model_type
    if vector_type is not None:
        params["vector_type"] = vector_type

    # Make async HTTP request (GET with query params)
    data: dict[str, Any] = await self._make_inference_request(
        "models", timeout=timeout, params=params if params else None
    )

    # Transform response via adapter

    result: ListModelsResponse = self._adapter.to_list_models_response(data)

    logger.debug(
        "Models listed successfully",
        model_count=len(result.models),
    )

    return result
