import re
from collections.abc import Callable
from typing import overload

from remedapy.decorator import make_data_last

Separator = str | re.Pattern[str]


@overload
def split(s: str, separator: Separator, /, *, limit: int | None = None) -> list[str]: ...


@overload
def split(separator: Separator, /, *, limit: int | None = None) -> Callable[[str], list[str]]: ...


@make_data_last
def split(  # pyright: ignore[reportInconsistentOverload]
    string: str,
    separator: Separator | re.Pattern[str],
    /,
    *,
    limit: int | None = None,
) -> list[str] | Callable[[str], list[str]]:
    r"""
    Splits the given string by separator.

    If limit is specified the string will be split at max `limit` number of times into
    at most `limit + 1` parts.

    Parameters
    ----------
    string: str
        String to split (positional-only).
    separator: Separator | re.Pattern[str]
        Separator to split by (positional-only).
    limit: int | None
        Maximum number of splits (keyword-only, optional).

    Returns
    -------
    list[str]
        List of substrings.

    Examples
    --------
    Data first:
    >>> R.split('a,b,c', ',')
    ['a', 'b', 'c']
    >>> R.split('a,b,c', ',', limit=2)
    ['a', 'b', 'c']
    >>> R.split('a,b,c', ',', limit=1)
    ['a', 'b,c']
    >>> R.split('a,,b,,c', ',,', limit=1)
    ['a', 'b,,c']
    >>> R.split('a1b2c3d', '\\d')
    ['a', 'b', 'c', 'd']
    >>> R.split('a1b2c3d', '[0-9]')
    ['a', 'b', 'c', 'd']

    Data last:
    >>> R.pipe('a,b,c', R.split(','))
    ['a', 'b', 'c']
    >>> R.pipe('a,b,c', R.split(',', limit=2))
    ['a', 'b', 'c']
    >>> R.pipe('a,b,c', R.split(',', limit=1))
    ['a', 'b,c']
    >>> R.pipe('a1b2c3d', R.split('\\d'))
    ['a', 'b', 'c', 'd']
    >>> R.pipe('a1b2c3d', R.split('[0-9]'))
    ['a', 'b', 'c', 'd']

    """
    if limit is not None:
        return re.split(separator, string, maxsplit=limit)
    return re.split(separator, string)
