from collections.abc import Callable, Iterable, Iterator, Mapping, Sequence
from decimal import Decimal
from itertools import chain
from typing import Any

from django.core.files.base import File
from django.forms.renderers import BaseRenderer
from django.utils.safestring import SafeText

_OptAttrs = dict[str, Any]

class MediaOrderConflictWarning(RuntimeWarning): ...

class Media:
    _js: str
    def __init__(
        self,
        media: type | None = ...,
        css: dict[str, Iterable[str]] | None = ...,
        js: Iterable[str] | None = ...,
    ) -> None: ...
    def render(self) -> str: ...
    def render_js(self) -> list[str]: ...
    def render_css(self) -> chain[Any]: ...
    def absolute_path(self, path: str) -> str: ...
    def __getitem__(self, name: str) -> Media: ...
    @staticmethod
    def merge(list_1: Iterable[Any], list_2: Iterable[Any]) -> Iterable[Any]: ...
    def __add__(self, other: Media) -> Media: ...

class MediaDefiningClass(type): ...

class Widget:
    needs_multipart_form: bool = ...
    is_localized: bool = ...
    is_required: bool = ...
    supports_microseconds: bool = ...
    attrs: _OptAttrs = ...
    def __init__(self, attrs: _OptAttrs | None = ...) -> None: ...
    @property
    def is_hidden(self) -> bool: ...
    def subwidgets(
        self, name: str, value: list[str] | None, attrs: _OptAttrs = ...
    ) -> Iterator[dict[str, Any]]: ...
    def format_value(self, value: Any) -> str | None: ...
    def get_context(
        self, name: str, value: Any, attrs: _OptAttrs | None
    ) -> dict[str, Any]: ...
    def render(
        self,
        name: str,
        value: Any,
        attrs: _OptAttrs | None = ...,
        renderer: BaseRenderer | None = ...,
    ) -> SafeText: ...
    def build_attrs(
        self, base_attrs: _OptAttrs, extra_attrs: _OptAttrs | None = ...
    ) -> dict[str, Decimal | float | str]: ...
    def value_from_datadict(
        self, data: dict[str, Any], files: Mapping[str, Iterable[Any]], name: str
    ) -> Any: ...
    def value_omitted_from_data(
        self, data: dict[str, Any], files: Mapping[str, Iterable[Any]], name: str
    ) -> bool: ...
    def id_for_label(self, id_: str) -> str: ...
    def use_required_attribute(self, initial: Any) -> bool: ...

class Input(Widget):
    input_type: str = ...
    template_name: str = ...

class TextInput(Input): ...
class NumberInput(Input): ...
class EmailInput(Input): ...
class URLInput(Input): ...

class PasswordInput(Input):
    render_value: bool = ...
    def __init__(
        self, attrs: _OptAttrs | None = ..., render_value: bool = ...
    ) -> None: ...

class HiddenInput(Input):
    choices: Iterable[tuple[str, str]]

class MultipleHiddenInput(HiddenInput): ...
class FileInput(Input): ...

FILE_INPUT_CONTRADICTION: Any

class ClearableFileInput(FileInput):
    clear_checkbox_label: Any = ...
    initial_text: Any = ...
    input_text: Any = ...
    def clear_checkbox_name(self, name: str) -> str: ...
    def clear_checkbox_id(self, name: str) -> str: ...
    def is_initial(self, value: File | str | None) -> bool: ...

class Textarea(Widget):
    template_name: str = ...

class DateTimeBaseInput(TextInput):
    format_key: str = ...
    format: str | None = ...
    def __init__(
        self, attrs: _OptAttrs | None = ..., format: str | None = ...
    ) -> None: ...

class DateInput(DateTimeBaseInput): ...
class DateTimeInput(DateTimeBaseInput): ...
class TimeInput(DateTimeBaseInput): ...

class CheckboxInput(Input):
    check_test: Callable[..., Any] = ...
    def __init__(
        self,
        attrs: _OptAttrs | None = ...,
        check_test: Callable[..., Any] | None = ...,
    ) -> None: ...

class ChoiceWidget(Widget):
    allow_multiple_selected: bool = ...
    input_type: str | None = ...
    template_name: str | None = ...
    option_template_name: str = ...
    add_id_index: bool = ...
    checked_attribute: Any = ...
    option_inherits_attrs: bool = ...
    choices: list[list[int | str]] = ...
    def __init__(
        self, attrs: _OptAttrs | None = ..., choices: Sequence[tuple[Any, Any]] = ...
    ) -> None: ...
    def options(
        self, name: str, value: list[str], attrs: _OptAttrs | None = ...
    ) -> None: ...
    def optgroups(
        self, name: str, value: list[str], attrs: _OptAttrs | None = ...
    ) -> Any: ...
    def create_option(
        self,
        name: str,
        value: Any,
        label: int | str,
        selected: set[str] | bool,
        index: int,
        subindex: int | None = ...,
        attrs: _OptAttrs | None = ...,
    ) -> dict[str, Any]: ...
    def id_for_label(self, id_: str, index: str = ...) -> str: ...

class Select(ChoiceWidget): ...
class NullBooleanSelect(Select): ...

class SelectMultiple(Select):
    allow_multiple_selected: bool = ...

class RadioSelect(ChoiceWidget):
    can_add_related: bool

class CheckboxSelectMultiple(ChoiceWidget): ...

class MultiWidget(Widget):
    template_name: str = ...
    widgets: list[Widget] = ...
    def __init__(
        self,
        widgets: Sequence[Widget | type[Widget]],
        attrs: _OptAttrs | None = ...,
    ) -> None: ...
    def decompress(self, value: Any) -> Any | None: ...
    media: Any = ...

class SplitDateTimeWidget(MultiWidget):
    def __init__(
        self,
        attrs: _OptAttrs | None = ...,
        date_format: str | None = ...,
        time_format: str | None = ...,
        date_attrs: dict[str, str] | None = ...,
        time_attrs: dict[str, str] | None = ...,
    ) -> None: ...

class SplitHiddenDateTimeWidget(SplitDateTimeWidget): ...

class SelectDateWidget(Widget):
    none_value: Any = ...
    month_field: str = ...
    day_field: str = ...
    year_field: str = ...
    template_name: str = ...
    input_type: str = ...
    select_widget: Any = ...
    date_re: Any = ...
    years: Any = ...
    months: Any = ...
    year_none_value: Any = ...
    month_none_value: Any = ...
    day_none_value: Any = ...
    def __init__(
        self,
        attrs: _OptAttrs | None = ...,
        years: Iterable[int | str] | None = ...,
        months: dict[int, str] | None = ...,
        empty_label: str | Sequence[str] | None = ...,
    ) -> None: ...
