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

from remedapy.decorator import make_data_last

T = TypeVar('T')


@overload
def only() -> Callable[[Sequence[T]], T | None]: ...


@overload
def only(sequence: Sequence[T], /) -> T | None: ...


@make_data_last
def only(sequence: Sequence[T], /) -> T | None | Callable[[Sequence[T]], T | None]:
    """
    Returns the only element of the sequence if it has exactly one element, otherwise `None`.

    Parameters
    ----------
    sequence : Sequence[T]
        Input sequence (positional-only).

    Returns
    -------
    T | None
        Only element of the sequence or `None` if the sequence is empty or has more than one element.

    Examples
    --------
    Data first:
    >>> R.only([1])
    1
    >>> R.only([])
    >>> R.only([1, 2])

    Data last:
    >>> R.only()([1])
    1
    >>> R.only()([])
    >>> R.only()([1, 2])

    """
    return sequence[0] if len(sequence) == 1 else None
