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

from remedapy.decorator import make_data_last

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


@overload
def is_subset(set1: Set[T], set2: Set[T]) -> bool: ...


@overload
def is_subset(set1: Set[T], /) -> Callable[[Set[T]], bool]: ...


@overload
def is_subset(set1: dict[Key, T], set2: dict[Key, T]) -> bool: ...


@overload
def is_subset(set1: dict[Key, T], /) -> Callable[[dict[Key, T]], bool]: ...


# TODO: proper
@make_data_last
def is_subset(set1: Set[T] | dict[Key, T], set2: Set[T] | dict[Key, T], /) -> bool:
    """
    Returns true if set1 is a subset of set2.

    Parameters
    ----------
    set1: Set[T] | dict[Key, T]
        Set that should be a subset of the other for the result to be true.
    set2: Set[T] | dict[Key, T]
        Set that should be a superset of the other for the result to be true.


    Returns
    -------
    result: bool
        Whether set1 is a subset of set2.

    Examples
    --------
    Data first:
    >>> R.is_subset({1, 2}, {1, 2, 3})
    True
    >>> R.is_subset({1, 2, 3}, {1, 2, 3})
    True
    >>> R.is_subset({1, 2}, {1, 4})
    False
    >>> R.is_subset({'a': 3}, {'a': 3, 'b': 5})
    True
    >>> R.is_subset({'a': 3}, {'a': 3})
    True
    >>> R.is_subset({'a': 4}, {'a': 3, 'b': 5})
    False


    Data last:
    >>> R.is_subset({1, 2, 3})({1, 2})
    True
    >>> R.is_subset({1, 2})({1, 4})
    False

    """
    if isinstance(set1, dict):
        return set1.items() <= set2.items()  # pyright: ignore[reportUnknownVariableType, reportUnknownMemberType, reportAttributeAccessIssue]
    return set1 <= set2  # pyright: ignore[reportUnknownVariableType, reportUnknownMemberType, reportAttributeAccessIssue, reportOperatorIssue]
