"""Adapter for list_indexes operation (2026-01.alpha API)."""

from __future__ import annotations

import logging

from typing import Any

import orjson

from msgspec import json as msgspec_json

from pinecone.models.indexes import IndexList


logger = logging.getLogger(__name__)


def _normalize_schema_fields(response_dict: dict[str, Any]) -> dict[str, Any]:
    """Normalize schema fields in API response to ensure 'type' attribute exists.

    The 'type' field is required by msgspec's tagged union system to determine
    which field type class to deserialize into. Some API responses may omit this
    field during schema evolution. This function infers the type based on field
    name and properties.

    Args:
        response_dict: Raw API response dictionary

    Returns:
        Normalized response dictionary with 'type' added to fields missing it

    Note:
        The SDK is intentionally flexible about other field attributes (metric,
        dimension, model, etc.) - they are optional in the models to handle
        evolving API responses. Only 'type' is required for deserialization.
    """
    indexes = response_dict.get("indexes", [])
    fixed_count = 0

    for idx in indexes:
        index_name = idx.get("name", "<unknown>")
        schema = idx.get("schema", {})
        fields = schema.get("fields", {})

        for field_name, field_config in fields.items():
            if not isinstance(field_config, dict):
                continue

            # Only add 'type' if missing - all other fields are optional
            if "type" not in field_config:
                inferred_type = _infer_field_type(field_name, field_config)
                field_config["type"] = inferred_type
                fixed_count += 1

                logger.debug(
                    f"Inferred missing 'type' for {index_name}.{field_name}: '{inferred_type}'"
                )

    if fixed_count > 0:
        logger.info(
            f"Inferred 'type' for {fixed_count} schema fields in list_indexes response. "
            f"This may occur during API schema evolution."
        )

    return response_dict


def _infer_field_type(field_name: str, field_config: dict[str, Any]) -> str:
    """Infer field type from field name and properties.

    Args:
        field_name: Name of the field
        field_config: Field configuration dict (without 'type')

    Returns:
        Inferred type string ('integer' or 'string')

    Note:
        This is a heuristic for fixing malformed API responses. Common patterns:
        - year, count, age, id, etc. -> integer
        - Everything else -> string (safe default)
    """
    # Check for common integer field names
    integer_patterns = {"year", "count", "age", "id", "num", "number", "index"}

    field_lower = field_name.lower()
    if any(pattern in field_lower for pattern in integer_patterns):
        return "integer"

    # Default to string (safe for filterable fields)
    return "string"


def from_response(response_dict: dict[str, Any]) -> IndexList:
    """Parse API response JSON to IndexList.

    Uses msgspec for fast deserialization with automatic type validation.
    Includes preprocessing to handle malformed schema fields from API bugs.

    Args:
        response_dict: Dictionary from response.json()

    Returns:
        IndexList instance containing list of IndexModel objects

    Raises:
        msgspec.ValidationError: If response doesn't match IndexList schema

    Example:
        >>> response = requests.get(...).json()
        >>> index_list = from_response(response)
        >>> for index in index_list.indexes:
        ...     print(f"{index.name}: {index.status.state}")
    """
    # Normalize malformed fields before validation
    normalized = _normalize_schema_fields(response_dict)

    decoder = msgspec_json.Decoder(IndexList)
    return decoder.decode(orjson.dumps(normalized))


__all__ = ["from_response"]
