from collections.abc import Callable, Sequence
from typing import TYPE_CHECKING, overload

import remedapy as R

from .decorator import make_data_last

if TYPE_CHECKING:
    from _typeshed import SupportsRichComparisonT


@overload
def sorted_last_index(data: Sequence['SupportsRichComparisonT'], item: 'SupportsRichComparisonT', /) -> int: ...


@overload
def sorted_last_index(item: 'SupportsRichComparisonT', /) -> Callable[[Sequence['SupportsRichComparisonT']], int]: ...


@make_data_last
def sorted_last_index(data: Sequence['SupportsRichComparisonT'], item: 'SupportsRichComparisonT', /) -> int:
    """
    Given a sorted sequence and an item, returns the index.

    The index is the last position where the item should be inserted to keep the sequence sorted.

    "sorted" means that elements are sorted.

    The result is also the number of elements smaller or equal to the item.

    Parameters
    ----------
    data: Sequence[T]
        The data.
    item: T
        The item to insert.

    Returns
    -------
    int
        The index. Will be non-negative.

    See Also
    --------
    sorted_index

    Examples
    --------
    Data first:
    >>> R.sorted_last_index(['a', 'a', 'b', 'c', 'c'], 'c')
    5
    >>> R.sorted_last_index(['a', 'a', 'b', 'c', 'c', 'd'], 'c')
    5

    Data last:
    >>> R.pipe(['a', 'a', 'b', 'c', 'c'], R.sorted_last_index('c'))
    5

    """
    return R.sorted_index_with(data, R.le(item))
