from typing import Any, Self
import logging

from django.core.checks import CheckMessage
from django.db import models
from django.db.models import QuerySet

logger: logging.Logger

class BaseField:
    field_name: str
    kwargs: dict[str, Any]
    def __init__(self, field_name: str, **kwargs: Any) -> None: ...
    def get_field(self, cls: type[models.Model]) -> models.Field[Any, Any]: ...
    def get_attname(self, cls: type[models.Model]) -> str: ...
    def get_definition_model(self, cls: type[models.Model]) -> type[models.Model] | None: ...
    def get_type(self, cls: type[models.Model]) -> str: ...
    def get_value(self, obj: models.Model) -> Any: ...

class SearchField(BaseField):
    boost: float | None
    def __init__(self, field_name: str, boost: float | None = None, **kwargs: Any) -> None: ...

class AutocompleteField(BaseField): ...
class FilterField(BaseField): ...

class RelatedFields:
    field_name: str
    fields: list[BaseField]
    def __init__(self, field_name: str, fields: list[BaseField]) -> None: ...
    def get_field(self, cls: type[models.Model]) -> models.Field[Any, Any]: ...
    def get_definition_model(self, cls: type[models.Model]) -> type[models.Model]: ...
    def get_value(self, obj: models.Model) -> Any: ...
    def select_on_queryset(self, queryset: QuerySet[models.Model]) -> QuerySet[models.Model]: ...

class Indexed:
    search_fields: list[BaseField | RelatedFields]
    @classmethod
    def indexed_get_parent(cls, require_model: bool = True) -> type[Indexed] | None: ...
    @classmethod
    def indexed_get_content_type(cls) -> str: ...
    @classmethod
    def indexed_get_toplevel_content_type(cls) -> str: ...
    @classmethod
    def get_search_fields(cls) -> list[BaseField | RelatedFields]: ...
    @classmethod
    def get_searchable_search_fields(cls) -> list[SearchField]: ...
    @classmethod
    def get_autocomplete_search_fields(cls) -> list[AutocompleteField]: ...
    @classmethod
    def get_filterable_search_fields(cls) -> list[FilterField]: ...
    @classmethod
    def get_indexed_objects(cls) -> QuerySet[models.Model]: ...
    @classmethod
    def check(cls, **kwargs: Any) -> list[CheckMessage]: ...
    def get_indexed_instance(self) -> Self | None: ...

def get_indexed_models() -> list[type[models.Model]]: ...
def class_is_indexed(cls: type) -> bool: ...
def get_indexed_instance(instance: models.Model, check_exists: bool = True) -> models.Model | None: ...
def insert_or_update_object(instance: models.Model) -> None: ...
def remove_object(instance: models.Model) -> None: ...
