"""Utility functions for normalizing vector input formats.

This module provides backward compatibility with tuple formats from prior
versions of the SDK while maintaining the modern dict-based API.
"""

from collections.abc import Sequence
from typing import Any


def normalize_vector(
    vector: dict[str, Any] | tuple[str, list[float]] | tuple[str, list[float], dict[str, Any]],
) -> dict[str, Any]:
    """Normalize vector from tuple or dict to dict format.

    Args:
        vector: Vector in dict, 2-tuple (id, values), or 3-tuple (id, values, metadata) format

    Returns:
        Dict with 'id', 'values', and optionally 'metadata' keys

    Raises:
        ValueError: If vector format is invalid or tuple contains invalid types

    Examples:
        Dict format (passes through):

        >>> normalize_vector({"id": "v1", "values": [0.1, 0.2]})
        {"id": "v1", "values": [0.1, 0.2]}

        2-tuple format:

        >>> normalize_vector(("v1", [0.1, 0.2]))
        {"id": "v1", "values": [0.1, 0.2]}

        3-tuple format:

        >>> normalize_vector(("v1", [0.1, 0.2], {"key": "val"}))
        {"id": "v1", "values": [0.1, 0.2], "metadata": {"key": "val"}}
    """
    if isinstance(vector, dict):
        # Already in correct format
        return vector

    if isinstance(vector, tuple):
        if len(vector) == 2:
            # 2-tuple: (id, values)
            id_val, values = vector
            if not isinstance(id_val, str):
                raise ValueError(f"Vector ID must be a string, got {type(id_val).__name__}")
            if not isinstance(values, list):
                raise ValueError(f"Vector values must be a list, got {type(values).__name__}")
            return {"id": id_val, "values": values}
        if len(vector) == 3:
            # 3-tuple: (id, values, metadata)
            id_val, values, metadata = vector
            if not isinstance(id_val, str):
                raise ValueError(f"Vector ID must be a string, got {type(id_val).__name__}")
            if not isinstance(values, list):
                raise ValueError(f"Vector values must be a list, got {type(values).__name__}")
            if not isinstance(metadata, dict):
                raise ValueError(f"Vector metadata must be a dict, got {type(metadata).__name__}")
            return {"id": id_val, "values": values, "metadata": metadata}
        raise ValueError(
            f"Tuple vectors must be 2-tuple (id, values) or 3-tuple (id, values, metadata), got {len(vector)}-tuple"
        )

    raise ValueError(f"Vector must be dict or tuple, got {type(vector).__name__}")


def normalize_vectors(
    vectors: Sequence[
        dict[str, Any] | tuple[str, list[float]] | tuple[str, list[float], dict[str, Any]]
    ],
) -> list[dict[str, Any]]:
    """Normalize a sequence of vectors to dict format.

    Optimized to avoid unnecessary copying when all inputs are already dicts.

    Args:
        vectors: Sequence of vectors in dict or tuple format

    Returns:
        List of dicts with normalized vector data

    Examples:
        >>> normalize_vectors(
        ...     [
        ...         {"id": "v1", "values": [0.1]},
        ...         ("v2", [0.2]),
        ...         ("v3", [0.3], {"key": "val"}),
        ...     ]
        ... )
        [
            {"id": "v1", "values": [0.1]},
            {"id": "v2", "values": [0.2]},
            {"id": "v3", "values": [0.3], "metadata": {"key": "val"}}
        ]
    """
    # Fast path: if input is a list and all are dicts, return as-is (avoids allocation)
    if isinstance(vectors, list) and all(isinstance(v, dict) for v in vectors):
        return vectors

    # Mixed or tuple inputs, or non-list sequence: normalize
    return [normalize_vector(v) for v in vectors]
