from collections.abc import Callable, Mapping, MutableMapping
from typing import overload

__all__ = ["merge", "merge_with"]

@overload
def merge_with[K, V]() -> Callable[
	..., dict[K, V] | MutableMapping[K, V]
]: ...
@overload
def merge_with[K, V](
	func: Callable[[list[V]], V], /
) -> Callable[..., dict[K, V] | MutableMapping[K, V]]: ...
@overload
def merge_with[K, V](
	func: Callable[[list[V]], V],
	d: Mapping[K, V],
	/,
) -> dict[K, V]: ...
@overload
def merge_with[K, V](
	func: Callable[[list[V]], V],
	d: Mapping[K, V],
	d2: Mapping[K, V],
	/,
	*dicts: Mapping[K, V],
) -> dict[K, V]: ...
@overload
def merge_with[K, V](
	func: Callable[[list[V]], V],
	d: Mapping[K, V],
	d2: Mapping[K, V],
	/,
	*dicts: Mapping[K, V],
	factory: Callable[[], MutableMapping[K, V]],
) -> MutableMapping[K, V]: ...
@overload
def merge_with[K, V](
	func: Callable[[list[V]], V],
	/,
	*,
	factory: Callable[[], MutableMapping[K, V]],
) -> Callable[..., MutableMapping[K, V]]: ...
def merge_with[K, V](
	func: Callable[[list[V]], V] = ...,
	d: Mapping[K, V] = ...,
	*dicts: Mapping[K, V],
	factory: Callable[[], MutableMapping[K, V]] = ...,
) -> (
	dict[K, V]
	| MutableMapping[K, V]
	| Callable[..., dict[K, V] | MutableMapping[K, V]]
):
	...

@overload
def merge[K, V]() -> Callable[
	..., dict[K, V] | MutableMapping[K, V]
]: ...
@overload
def merge[K, V](d: Mapping[K, V], /) -> dict[K, V]: ...
@overload
def merge[K, V](
	d: Mapping[K, V],
	d2: Mapping[K, V],
	/,
	*dicts: Mapping[K, V],
) -> dict[K, V]: ...
@overload
def merge[K, V](
	d: Mapping[K, V],
	d2: Mapping[K, V],
	/,
	*dicts: Mapping[K, V],
	factory: Callable[[], MutableMapping[K, V]],
) -> MutableMapping[K, V]: ...
@overload
def merge[K, V](
	*,
	factory: Callable[[], MutableMapping[K, V]],
) -> Callable[..., MutableMapping[K, V]]: ...
def merge[K, V](
	d: Mapping[K, V] = ...,
	*dicts: Mapping[K, V],
	factory: Callable[[], MutableMapping[K, V]] = ...,
) -> (
	dict[K, V]
	| MutableMapping[K, V]
	| Callable[..., dict[K, V] | MutableMapping[K, V]]
):
	...
