from collections.abc import Iterable
from typing import Any

from django.db import models
from django.db.models import QuerySet
from wagtail.search.backends.base import BaseSearchBackend, BaseSearchQueryCompiler, BaseSearchResults
from wagtail.search.index import AutocompleteField, BaseField, SearchField

class ObjectIndexer:
    obj: models.Model
    backend: MySQLSearchBackend
    def __init__(self, obj: models.Model, backend: MySQLSearchBackend) -> None: ...
    def prepare_value(self, value: Any) -> str: ...
    def prepare_field(self, obj: models.Model, field: BaseField) -> list[tuple[str, str, str]]: ...
    @property
    def id(self) -> str: ...
    @property
    def title(self) -> str: ...
    @property
    def body(self) -> str: ...
    @property
    def autocomplete(self) -> str: ...
    def as_vector(self, texts: list[tuple[str, str, str]], for_autocomplete: bool = False) -> str: ...

class Index:
    backend: MySQLSearchBackend
    def __init__(self, backend: MySQLSearchBackend) -> None: ...
    def add_model(self, model: type) -> None: ...
    def refresh(self) -> None: ...
    def delete_stale_model_entries(self, model: type) -> None: ...
    def delete_stale_entries(self) -> None: ...
    def add_item(self, obj: models.Model) -> None: ...
    def add_items(self, model: type, objs: Iterable[models.Model]) -> None: ...
    def delete_item(self, item: models.Model) -> None: ...

class MySQLSearchQueryCompiler(BaseSearchQueryCompiler):
    DEFAULT_OPERATOR: str
    LAST_TERM_IS_PREFIX: bool
    TARGET_SEARCH_FIELD_TYPE: type[SearchField]
    FTS_TABLE_FIELDS: list[str]

class MySQLAutocompleteQueryCompiler(MySQLSearchQueryCompiler):
    LAST_TERM_IS_PREFIX: bool
    TARGET_SEARCH_FIELD_TYPE: type[AutocompleteField]
    FTS_TABLE_FIELDS: list[str]

class MySQLSearchResults(BaseSearchResults):
    supports_facet: bool
    def get_queryset(self, for_count: bool = False) -> QuerySet[models.Model]: ...
    def facet(self, field_name: str) -> dict[str, int]: ...

class MySQLSearchRebuilder:
    index: Index
    def __init__(self, index: Index) -> None: ...
    def start(self) -> Index: ...
    def finish(self) -> None: ...

class MySQLSearchAtomicRebuilder(MySQLSearchRebuilder):
    def __init__(self, index: Index) -> None: ...
    def start(self) -> Index: ...
    def finish(self) -> None: ...

class MySQLSearchBackend(BaseSearchBackend):
    query_compiler_class: type[MySQLSearchQueryCompiler]
    autocomplete_query_compiler_class: type[MySQLAutocompleteQueryCompiler]
    results_class: type[MySQLSearchResults]
    rebuilder_class: type[MySQLSearchRebuilder]
    atomic_rebuilder_class: type[MySQLSearchAtomicRebuilder]
    def __init__(self, params: dict[str, Any]) -> None: ...
    def get_index_for_model(self, model: type) -> Index: ...
    def get_index_for_object(self, obj: models.Model) -> Index: ...
    def reset_index(self) -> None: ...
    def add_type(self, model: type) -> None: ...
    def refresh_index(self) -> None: ...
    def add(self, obj: models.Model) -> None: ...
    def add_bulk(self, model: type, obj_list: Iterable[models.Model]) -> None: ...
    def delete(self, obj: models.Model) -> None: ...

SearchBackend = MySQLSearchBackend
