from __future__ import annotations

from typing import TYPE_CHECKING, Any, TypeVar

if TYPE_CHECKING:
    from collections.abc import Callable, Mapping, Sequence

T = TypeVar("T")
K = TypeVar("K")
V = TypeVar("V")


def summarize_items(
    items: Sequence[T],
    *,
    sample_size: int = 5,
    formatter: Callable[[T], str] = str,
) -> dict[str, Any]:
    """Summarize a sequence for debug logging."""
    total = len(items)
    sample = [formatter(item) for item in items[:sample_size]]
    return {
        "rows": total,
        "sample": sample,
    }


def format_sequence(
    items: Sequence[T],
    *,
    formatter: Callable[[T], str] = str,
    limit: int | None = 10,
) -> str:
    """Format a sequence for human-readable logging."""
    total = len(items)
    display_limit = total if limit is None else max(limit, 0)
    rendered = [formatter(item) for item in items[:display_limit]]
    ellipsis = ", ..." if total > display_limit else ""
    content = ", ".join(rendered)
    return f"[{content}{ellipsis}]"


def format_mapping(
    mapping: Mapping[K, V],
    *,
    key_formatter: Callable[[K], str] = str,
    value_formatter: Callable[[V], str] = str,
    limit: int | None = 10,
) -> str:
    """Format a mapping for human-readable logging."""
    total = len(mapping)
    display_limit = total if limit is None else max(limit, 0)
    rendered_pairs = []
    for idx, (key, value) in enumerate(mapping.items()):
        if idx >= display_limit:
            break
        rendered_pairs.append(f"{key_formatter(key)}: {value_formatter(value)}")
    ellipsis = ", ..." if total > display_limit else ""
    content = ", ".join(rendered_pairs)
    return f"{{{content}{ellipsis}}}"


def merge_descriptions(parts: Sequence[str], *, separator: str = " | ") -> str:
    """Combine description fragments, preserving order and removing duplicates/empties."""
    from kele.syntax.mixins import DescriptionJoiner  # noqa: PLC0415

    return DescriptionJoiner.merge(parts, separator=separator)
