from __future__ import annotations

from collections.abc import Callable
from typing import TypeVar

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


def sort_with_missing_last(
    base_keys: list[K],
    value_getter: Callable[[K], T | None],
    desc: bool,
) -> list[K]:
    """Sort keys by value while keeping missing values at the end."""
    present: list[tuple[K, T]] = []
    missing: list[K] = []
    for key in base_keys:
        value = value_getter(key)
        if value is None:
            missing.append(key)
            continue
        present.append((key, value))
    present.sort(key=lambda item: item[1], reverse=desc)
    return [key for key, _ in present] + missing


def next_sort_field_index(current: int, total_fields: int) -> int:
    """Cycle sort field index in [0, total_fields)."""
    if total_fields <= 0:
        return 0
    return (current + 1) % total_fields
