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

from remedapy.decorator import make_data_last

TNum = TypeVar('TNum', int, float)


@overload
def add(addend: int, /) -> Callable[[TNum], TNum]: ...


@overload
def add(addend: float, /) -> Callable[[int | float], float]: ...


@overload
def add(addend: str, /) -> Callable[[str], str]: ...


@overload
def add(value: int, addend: TNum, /) -> TNum: ...


@overload
def add(value: TNum, addend: int, /) -> TNum: ...


@overload
def add(value: str, addend: str, /) -> str: ...


@make_data_last
def add(
    a: Any,
    b: Any,
    /,
) -> Any:
    """
    Adds two numbers.

    Alias for `operator.add` (+) - `__add__` magic method.

    Parameters
    ----------
    a : int | float | T
        First thing (positional-only).
    b : int | float | T
        Second thing (positional-only).

    Returns
    -------
    int | float | result of adding T to T
        Sum of a and b.

    Examples
    --------
    Data first:
    >>> R.add(2, 3)
    5

    Data last:
    >>> R.add(3)(2)
    5
    >>> R.add(0.1)(0.2)
    0.3...

    """
    return a + b
