from typing import Any, Callable, Dict, Optional, Sequence, Type, Union

from django.db import models
from django.forms.forms import BaseForm
from django.http import HttpRequest, HttpResponse
from django.views.generic.base import ContextMixin, TemplateResponseMixin, View
from django.views.generic.detail import BaseDetailView, SingleObjectMixin, SingleObjectTemplateResponseMixin
from typing_extensions import Literal

class FormMixin(ContextMixin):
    initial: Dict[str, Any] = ...
    form_class: Optional[Type[BaseForm]] = ...
    success_url: Optional[Union[str, Callable[..., Any]]] = ...
    prefix: Optional[str] = ...
    request: HttpRequest = ...
    def render_to_response(self, context: Dict[str, Any], **response_kwargs: object) -> HttpResponse: ...
    def get_initial(self) -> Dict[str, Any]: ...
    def get_prefix(self) -> Optional[str]: ...
    def get_form_class(self) -> Type[BaseForm]: ...
    def get_form(self, form_class: Optional[Type[BaseForm]] = None) -> BaseForm: ...
    def get_form_kwargs(self) -> Dict[str, Any]: ...
    def get_success_url(self) -> str: ...
    def form_valid(self, form: BaseForm) -> HttpResponse: ...
    def form_invalid(self, form: BaseForm) -> HttpResponse: ...

class ModelFormMixin(FormMixin, SingleObjectMixin):
    fields: Optional[Union[Sequence[str], Literal["__all__"]]] = ...

class ProcessFormView(View):
    def render_to_response(self, context: Dict[str, Any], **response_kwargs: Any) -> HttpResponse: ...
    def get_context_data(self, **kwargs: Any) -> Dict[str, Any]: ...
    def get(self, request: HttpRequest, *args: str, **kwargs: Any) -> HttpResponse: ...
    def post(self, request: HttpRequest, *args: str, **kwargs: Any) -> HttpResponse: ...
    def put(self, *args: str, **kwargs: Any) -> HttpResponse: ...

class BaseFormView(FormMixin, ProcessFormView): ...
class FormView(TemplateResponseMixin, BaseFormView): ...
class BaseCreateView(ModelFormMixin, ProcessFormView): ...
class CreateView(SingleObjectTemplateResponseMixin, BaseCreateView): ...
class BaseUpdateView(ModelFormMixin, ProcessFormView): ...
class UpdateView(SingleObjectTemplateResponseMixin, BaseUpdateView): ...

_object = object

class DeletionMixin:
    success_url: Optional[str] = ...
    object: models.Model = ...
    def post(self, request: HttpRequest, *args: str, **kwargs: Any) -> HttpResponse: ...
    def delete(self, request: HttpRequest, *args: str, **kwargs: Any) -> HttpResponse: ...
    def get_success_url(self) -> str: ...

class BaseDeleteView(DeletionMixin, BaseDetailView): ...
class DeleteView(SingleObjectTemplateResponseMixin, BaseDeleteView): ...
