from collections.abc import Callable, Iterable, Iterator
from html.parser import HTMLParser
from io import BytesIO
from re import Pattern
from typing import ClassVar, TypeVar, overload

from django.db.models.base import Model
from django.utils.functional import SimpleLazyObject, _StrOrPromise, cached_property

_StrOrPromiseT = TypeVar("_StrOrPromiseT", bound=_StrOrPromise)
_StrOrPromiseOrNoneT = TypeVar("_StrOrPromiseOrNoneT", bound=_StrOrPromise | None)

def capfirst(x: _StrOrPromiseOrNoneT) -> _StrOrPromiseOrNoneT: ...

re_newlines: Pattern[str]
re_camel_case: Pattern[str]

def wrap(text: _StrOrPromiseT, width: int) -> _StrOrPromiseT: ...
def add_truncation_text(text: str, truncate: str | None = None) -> str: ...
def calculate_truncate_chars_length(length: int, replacement: str | None) -> int: ...

class TruncateHTMLParser(HTMLParser):
    TruncationCompleted: ClassVar[type[Exception]]
    def __init__(self, *, length: int, replacement: str | None, convert_charrefs: bool = True) -> None: ...
    @cached_property
    def void_elements(self) -> frozenset[str]: ...

class TruncateCharsHTMLParser(TruncateHTMLParser):
    def process(self, data: str) -> tuple[str, str]: ...

class TruncateWordsHTMLParser(TruncateHTMLParser):
    def process(self, data: str) -> tuple[str, str]: ...

class Truncator(SimpleLazyObject):
    MAX_LENGTH_HTML: ClassVar[int]
    def __init__(self, text: Model | str) -> None: ...
    def chars(self, num: int, truncate: str | None = None, html: bool = False) -> str: ...
    def words(self, num: int, truncate: str | None = None, html: bool = False) -> str: ...

def get_valid_filename(name: _StrOrPromiseT) -> _StrOrPromiseT: ...
@overload
def get_text_list(list_: list[str], last_word: str = ...) -> str: ...
@overload
def get_text_list(list_: list[_StrOrPromise], last_word: _StrOrPromise = ...) -> _StrOrPromise: ...
def normalize_newlines(text: _StrOrPromiseT) -> _StrOrPromiseT: ...
def phone2numeric(phone: _StrOrPromiseT) -> _StrOrPromiseT: ...
def compress_string(s: bytes, *, max_random_bytes: int | None = None) -> bytes: ...

class StreamingBuffer(BytesIO):
    vals: list[bytes]
    def read(self) -> bytes: ...  # type: ignore[override]

def compress_sequence(sequence: Iterable[bytes], *, max_random_bytes: int | None = None) -> Iterator[bytes]: ...

smart_split_re: Pattern[str]

def smart_split(text: str) -> Iterator[str]: ...
def unescape_string_literal(s: _StrOrPromiseT) -> _StrOrPromiseT: ...
def slugify(value: _StrOrPromiseT, allow_unicode: bool = False) -> _StrOrPromiseT: ...
def camel_case_to_spaces(value: str) -> str: ...

format_lazy: Callable[..., _StrOrPromise]
