from collections.abc import Callable, Sequence
from typing import Any, Generic, Literal, TypeVar

from django.forms.forms import BaseForm
from django.forms.models import BaseModelForm
from django.http import HttpRequest, HttpResponse
from django.utils.functional import _StrOrPromise
from django.views.generic.base import ContextMixin, TemplateResponseMixin, View
from django.views.generic.detail import BaseDetailView, SingleObjectMixin, SingleObjectTemplateResponseMixin

_FormT = TypeVar("_FormT", bound=BaseForm)

class AbstractFormMixin(ContextMixin):
    initial: dict[str, Any] = ...
    form_class: type[BaseForm] | None = ...
    success_url: _StrOrPromise | Callable[..., Any] | None = ...
    prefix: str | None = ...
    def get_initial(self) -> dict[str, Any]: ...
    def get_prefix(self) -> str | None: ...
    def get_form_kwargs(self) -> dict[str, Any]: ...
    def get_success_url(self) -> str: ...

class FormMixin(AbstractFormMixin, Generic[_FormT]):
    def get_form_class(self) -> type[_FormT]: ...
    def get_form(self, form_class: type[_FormT] | None = ...) -> BaseForm: ...
    def form_valid(self, form: _FormT) -> HttpResponse: ...
    def form_invalid(self, form: _FormT) -> HttpResponse: ...

class ModelFormMixin(AbstractFormMixin, SingleObjectMixin):
    fields: Sequence[str] | Literal["__all__"] | None = ...
    def get_form_class(self) -> type[BaseModelForm]: ...
    def get_form(self, form_class: type[BaseModelForm] | None = ...) -> BaseModelForm: ...
    def form_valid(self, form: BaseModelForm) -> HttpResponse: ...
    def form_invalid(self, form: BaseModelForm) -> HttpResponse: ...

class ProcessFormView(View):
    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[_FormT], ProcessFormView): ...
class FormView(TemplateResponseMixin, BaseFormView[_FormT]): ...
class BaseCreateView(ModelFormMixin, ProcessFormView): ...
class CreateView(SingleObjectTemplateResponseMixin, BaseCreateView): ...
class BaseUpdateView(ModelFormMixin, ProcessFormView): ...
class UpdateView(SingleObjectTemplateResponseMixin, BaseUpdateView): ...

class DeletionMixin:
    success_url: _StrOrPromise | None = ...
    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): ...
