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

from remedapy.decorator import make_data_last

Key = TypeVar('Key', str, int)
T = TypeVar('T')


@overload
def merge(destination: dict[Key, T], source: dict[Key, T], /) -> dict[Key, T]: ...


@overload
def merge(source: dict[Key, T], /) -> Callable[[dict[Key, T]], dict[Key, T]]: ...


@make_data_last
def merge(destination: dict[Key, T], source: dict[Key, T], /) -> dict[Key, T]:
    """
    Merges two dicts.

    Alias for `destination | source`.

    Parameters
    ----------
    destination : dict[Key, T]
        The destination dict (positional-only).
    source : dict[Key, T]
        The source dict (positional-only).

    Returns
    -------
    dict[K, T]
        The resulting dict.

    See Also
    --------
    merge_all
    merge_deep

    Examples
    --------
    Data first:
    >>> R.merge({'x': 1, 'y': 2}, {'y': 10, 'z': 2})
    {'x': 1, 'y': 10, 'z': 2}
    >>> R.merge({'x': 1, 'y': {'a': 3}}, {'y': {'b': 3}, 'z': 2})
    {'x': 1, 'y': {'b': 3}, 'z': 2}

    Data last:
    >>> R.pipe({'x': 1, 'y': 2}, R.merge({'y': 10, 'z': 2}))
    {'x': 1, 'y': 10, 'z': 2}

    """
    return destination | source
