from collections.abc import Iterator, Mapping, Sequence, Sized
from typing import Any, Generic, TypeVar

from django.forms.forms import BaseForm, Form
from django.forms.utils import ErrorList, _DataT, _FilesT
from django.forms.widgets import Media, Widget
from django.utils.safestring import SafeString

TOTAL_FORM_COUNT: str
INITIAL_FORM_COUNT: str
MIN_NUM_FORM_COUNT: str
MAX_NUM_FORM_COUNT: str
ORDERING_FIELD_NAME: str
DELETION_FIELD_NAME: str

DEFAULT_MIN_NUM: int
DEFAULT_MAX_NUM: int

_F = TypeVar("_F", bound=BaseForm)

class ManagementForm(Form):
    cleaned_data: dict[str, int | None]
    def __init__(self, *args: Any, **kwargs: Any) -> None: ...
    def clean(self) -> dict[str, int | None]: ...

class BaseFormSet(Generic[_F], Sized):
    form: type[_F]
    extra: int
    can_order: bool
    can_delete: bool
    can_delete_extra: bool
    min_num: int
    max_num: int
    absolute_max: int
    validate_min: bool
    validate_max: bool

    is_bound: bool
    prefix: str | None
    auto_id: str
    data: _DataT
    files: _FilesT
    initial: Sequence[Mapping[str, Any]] | None
    form_kwargs: dict[str, Any]
    error_class: type[ErrorList]
    ordering_widget: type[Widget]
    def __init__(
        self,
        data: _DataT | None = ...,
        files: _FilesT | None = ...,
        auto_id: str = ...,
        prefix: str | None = ...,
        initial: Sequence[Mapping[str, Any]] | None = ...,
        error_class: type[ErrorList] = ...,
        form_kwargs: dict[str, Any] | None = ...,
        error_messages: Mapping[str, str] | None = ...,
    ) -> None: ...
    def __iter__(self) -> Iterator[_F]: ...
    def __getitem__(self, index: int) -> _F: ...
    def __len__(self) -> int: ...
    def __bool__(self) -> bool: ...
    @property
    def management_form(self) -> ManagementForm: ...
    def total_form_count(self) -> int: ...
    def initial_form_count(self) -> int: ...
    @property
    def forms(self) -> list[_F]: ...
    def get_form_kwargs(self, index: int | None) -> dict[str, Any]: ...
    @property
    def initial_forms(self) -> list[_F]: ...
    @property
    def extra_forms(self) -> list[_F]: ...
    @property
    def empty_form(self) -> _F: ...
    @property
    def cleaned_data(self) -> list[dict[str, Any]]: ...
    @property
    def deleted_forms(self) -> list[_F]: ...
    @property
    def ordered_forms(self) -> list[_F]: ...
    @classmethod
    def get_default_prefix(cls) -> str: ...
    @classmethod
    def get_ordering_widget(cls) -> type[Widget]: ...
    def non_form_errors(self) -> ErrorList: ...
    @property
    def errors(self) -> list[ErrorList]: ...
    def total_error_count(self) -> int: ...
    def is_valid(self) -> bool: ...
    def full_clean(self) -> None: ...
    def clean(self) -> None: ...
    def has_changed(self) -> bool: ...
    def add_fields(self, form: _F, index: int | None) -> None: ...
    def add_prefix(self, index: int | str) -> str: ...
    def is_multipart(self) -> bool: ...
    @property
    def media(self) -> Media: ...
    def as_table(self) -> SafeString: ...
    def as_p(self) -> SafeString: ...
    def as_ul(self) -> SafeString: ...

def formset_factory(
    form: type[_F],
    formset: type[BaseFormSet[_F]] = ...,
    extra: int = ...,
    can_order: bool = ...,
    can_delete: bool = ...,
    max_num: int | None = ...,
    validate_max: bool = ...,
    min_num: int | None = ...,
    validate_min: bool = ...,
    absolute_max: int | None = ...,
    can_delete_extra: bool = ...,
) -> type[BaseFormSet[_F]]: ...
def all_valid(formsets: Sequence[BaseFormSet[_F]]) -> bool: ...
