import sys
from collections.abc import Iterator
from re import Pattern
from typing import Final, Generic, TypedDict, TypeVar, overload, type_check_only

from markdown.core import Markdown

_T = TypeVar("_T")

BLOCK_LEVEL_ELEMENTS: Final[list[str]]
STX: Final[str]
ETX: Final[str]
INLINE_PLACEHOLDER_PREFIX: Final[str]
INLINE_PLACEHOLDER: Final[str]
INLINE_PLACEHOLDER_RE: Final[Pattern[str]]
AMP_SUBSTITUTE: Final[str]
HTML_PLACEHOLDER: Final[str]
HTML_PLACEHOLDER_RE: Final[Pattern[str]]
TAG_PLACEHOLDER: Final[str]
RTL_BIDI_RANGES: Final[tuple[tuple[str, str], tuple[str, str]]]

if sys.version_info >= (3, 10):
    from importlib import metadata
    def get_installed_extensions() -> metadata.EntryPoints: ...

else:
    def get_installed_extensions(): ...

def deprecated(message: str, stacklevel: int = 2): ...
@overload
def parseBoolValue(value: str) -> bool: ...
@overload
def parseBoolValue(value: str | None, fail_on_errors: bool = True, preserve_none: bool = False) -> bool | None: ...
def code_escape(text: str) -> str: ...
def nearing_recursion_limit() -> bool: ...

class AtomicString(str): ...

class Processor:
    md: Markdown
    def __init__(self, md: Markdown | None = None) -> None: ...

@type_check_only
class _TagData(TypedDict):
    tag: str
    attrs: dict[str, str]
    left_index: int
    right_index: int

class HtmlStash:
    html_counter: int
    rawHtmlBlocks: list[str]
    tag_counter: int
    tag_data: list[_TagData]
    def __init__(self) -> None: ...
    def store(self, html: str) -> str: ...
    def reset(self) -> None: ...
    def get_placeholder(self, key: int) -> str: ...
    def store_tag(self, tag: str, attrs: dict[str, str], left_index: int, right_index: int) -> str: ...

class Registry(Generic[_T]):
    def __init__(self) -> None: ...
    def __contains__(self, item: str | _T) -> bool: ...
    def __iter__(self) -> Iterator[_T]: ...
    @overload
    def __getitem__(self, key: slice) -> Registry[_T]: ...
    @overload
    def __getitem__(self, key: str | int) -> _T: ...
    def __len__(self) -> int: ...
    def get_index_for_name(self, name: str) -> int: ...
    def register(self, item: _T, name: str, priority: float) -> None: ...
    def deregister(self, name: str, strict: bool = True) -> None: ...
