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

from remedapy.decorator import make_data_last

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


@overload
def merge_all() -> Callable[[Iterable[dict[Key, T]]], dict[Key, T]]: ...


@overload
def merge_all(array: Iterable[dict[Key, T]], /) -> dict[Key, T]: ...


@make_data_last
def merge_all(dicts: Iterable[dict[Key, T]], /) -> dict[Key, T]:
    """
    Merges an iterable of dicts.

    Parameters
    ----------
    dicts: Iterable[dict[Key, T]]
        The iterable.

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

    See Also
    --------
    merge
    merge_deep

    Examples
    --------
    Data first:
    >>> R.merge_all([{'a': 1, 'b': 1}, {'b': 2, 'c': 3}, {'d': 10}])
    {'a': 1, 'b': 2, 'c': 3, 'd': 10}
    >>> R.merge_all([])
    {}

    Data last:
    >>> R.merge_all()([{'a': 1, 'b': 1}, {'b': 2, 'c': 3}, {'d': 10}])
    {'a': 1, 'b': 2, 'c': 3, 'd': 10}
    >>> R.merge_all()([])
    {}

    """
    result: dict[Key, T] = {}
    for d in dicts:
        result.update(d)
    return result
