from collections.abc import Iterable
from typing import Any

from django.core.paginator import Page
from django.db import models
from django.forms import Form
from django.http import HttpRequest, HttpResponse, JsonResponse
from django.utils.functional import cached_property
from django.views.generic.base import ContextMixin, View
from wagtail.admin.forms.choosers import BaseFilterForm
from wagtail.admin.paginator import WagtailPaginator
from wagtail.admin.ui.tables import Column, Table, TitleColumn
from wagtail.permission_policies import BasePermissionPolicy

class ModalPageFurnitureMixin(ContextMixin):
    icon: str | None
    page_title: str | None
    page_subtitle: str | None
    def get_context_data(self, **kwargs: Any) -> dict[str, Any]: ...

class ModelLookupMixin:
    model: type[models.Model] | str | None
    @cached_property
    def model_class(self) -> type[models.Model] | None: ...

class PreserveURLParametersMixin:
    preserve_url_parameters: list[str]
    @cached_property
    def _preserved_param_string(self) -> str: ...
    def append_preserved_url_parameters(self, url: str) -> str: ...

class CheckboxSelectColumn(Column):
    cell_template_name: str

class BaseChooseView(
    ModalPageFurnitureMixin,
    ModelLookupMixin,
    PreserveURLParametersMixin,
    ContextMixin,
    View,
):
    per_page: int
    ordering: str | list[str] | tuple[str, ...] | None
    chosen_url_name: str | None
    chosen_multiple_url_name: str | None
    results_url_name: str | None
    icon: str
    page_title: str
    filter_form_class: type[Form] | None
    template_name: str
    results_template_name: str
    construct_queryset_hook_name: str | None
    url_filter_parameters: list[str]
    paginator_class: type[WagtailPaginator]
    filter_form: BaseFilterForm
    results: Page[models.Model]
    paginator: WagtailPaginator
    table: Table
    @cached_property
    def i18n_enabled(self) -> bool: ...
    def get_object_list(self) -> models.QuerySet[models.Model]: ...
    def apply_object_list_ordering(self, objects: models.QuerySet[models.Model]) -> models.QuerySet[models.Model]: ...
    def get_filter_form_class(self) -> type[BaseFilterForm]: ...
    def get_filter_form(self) -> BaseFilterForm: ...
    def filter_object_list(self, objects: models.QuerySet[models.Model]) -> models.QuerySet[models.Model]: ...
    def get_results_url(self) -> str: ...
    def get_chosen_multiple_url(self) -> str: ...
    @cached_property
    def is_multiple_choice(self) -> str | None: ...
    @property
    def columns(self) -> list[Column]: ...
    @property
    def title_column(self) -> TitleColumn: ...
    @property
    def checkbox_column(self) -> CheckboxSelectColumn: ...
    def get_results_page(self, request: HttpRequest) -> Page[models.Model]: ...
    def get(self, request: HttpRequest) -> HttpResponse: ...
    def get_context_data(self, **kwargs: Any) -> dict[str, Any]: ...
    def render_to_response(self) -> HttpResponse: ...

class CreationFormMixin(ModelLookupMixin, PreserveURLParametersMixin):
    creation_form_class: type[Form] | None
    form_fields: list[str] | None
    exclude_form_fields: list[str] | None
    creation_form_template_name: str
    creation_tab_id: str
    create_action_label: str
    create_action_clicked_label: str | None
    create_url_name: str | None
    permission_policy: BasePermissionPolicy | None
    def get_permission_policy(self) -> BasePermissionPolicy: ...
    def can_create(self) -> bool: ...
    def get_creation_form_class(self) -> type[Form] | None: ...
    def get_creation_form_kwargs(self) -> dict[str, Any]: ...
    def get_creation_form(self) -> Form | None: ...
    def get_create_url(self) -> str: ...
    def get_creation_form_context_data(self, form: Form) -> dict[str, Any]: ...

class ChooseViewMixin:
    search_tab_label: str
    creation_tab_label: str | None
    def get_context_data(self, **kwargs: Any) -> dict[str, Any]: ...
    def get_response_json_data(self) -> dict[str, Any]: ...
    def render_to_response(self) -> JsonResponse: ...

class ChooseView(ChooseViewMixin, CreationFormMixin, BaseChooseView): ...

class ChooseResultsViewMixin:
    def render_to_response(self) -> HttpResponse: ...

class ChooseResultsView(ChooseResultsViewMixin, CreationFormMixin, BaseChooseView): ...

class ChosenResponseMixin:
    response_data_title_key: str
    chosen_response_name: str
    def get_object_id(self, instance: models.Model) -> Any: ...
    def get_display_title(self, instance: models.Model) -> str: ...
    def get_edit_item_url(self, instance: models.Model) -> str | None: ...
    def get_chosen_response_data(self, item: models.Model) -> dict[str, Any]: ...
    def _wrap_chosen_response_data(self, response_data: dict[str, Any] | list[dict[str, Any]]) -> JsonResponse: ...
    def get_multiple_chosen_response(self, items: Iterable[models.Model]) -> JsonResponse: ...
    def get_chosen_response(self, item: models.Model) -> JsonResponse: ...

class ChosenViewMixin(ModelLookupMixin):
    def get_object(self, pk: str) -> models.Model: ...
    def get(self, request: HttpRequest, pk: str) -> JsonResponse: ...

class ChosenView(ChosenViewMixin, ChosenResponseMixin, View): ...

class ChosenMultipleViewMixin(ModelLookupMixin):
    def get_objects(self, pks: list[str]) -> models.QuerySet[models.Model]: ...
    def get(self, request: HttpRequest) -> JsonResponse: ...

class ChosenMultipleView(ChosenMultipleViewMixin, ChosenResponseMixin, View): ...

class CreateViewMixin:
    model: type[models.Model] | str | None
    form: Form
    def dispatch(self, request: HttpRequest, *args: Any, **kwargs: Any) -> HttpResponse: ...
    def get(self, request: HttpRequest) -> JsonResponse: ...
    def save_form(self, form: Form) -> models.Model: ...
    def post(self, request: HttpRequest) -> JsonResponse: ...
    def get_reshow_creation_form_response(self) -> JsonResponse: ...

class CreateView(CreateViewMixin, CreationFormMixin, ChosenResponseMixin, View): ...
