from collections.abc import Callable
from typing import Any, TypeGuard, TypeVar, overload

from remedapy.decorator import make_data_last

T = TypeVar('T')


@overload
def is_number() -> Callable[[Any], TypeGuard[int | float]]: ...


@overload
def is_number(data: Any, /) -> TypeGuard[int | float]: ...


# TODO: strict
@make_data_last
def is_number(value: Any, /) -> TypeGuard[int | float]:
    """
    A function that checks if the passed parameter is a int or float and narrows its type accordingly.

    Alias to `isinstance(value, (int, float))`.

    Parameters
    ----------
    value: Any
        Value to check.

    Returns
    -------
    result: TypeGuard[int | float]
        Whether the value passed is int or float.

    Examples
    --------
    Data first:
    >>> R.is_float(1.1)
    True
    >>> R.is_float(1)
    False
    >>> R.is_float('1')
    False

    Data last:
    >>> R.is_float()(1.1)
    True
    >>> R.is_float()(1)
    False
    >>> R.is_float()('1')
    False

    """
    return isinstance(value, (int, float))
