from typing import Any, ClassVar, Self, TypeVar, overload
from sergo.fields import Field
from sergo.query.base import BaseQuery

_M = TypeVar('_M', bound='Model')

class Options:
    model: type
    fields: dict[str, Field[Any]]
    db_table: str | None
    schema: str | None
    @property
    def writeable_fields(self) -> dict[str, Field[Any]]: ...
    def get_field(self, name: str) -> Field[Any]: ...
    @property
    def primary_key_field(self) -> str: ...

class Manager:
    model: type[Model]
    def __init__(self, query_class: type | None = None) -> None: ...
    @property
    def table_name(self) -> str: ...
    @property
    def query(self) -> str: ...
    def create(self, **kwargs: Any) -> Any: ...
    def update_or_create(self, defaults: dict[str, Any] | None = None, **kwargs: Any) -> tuple[Any, bool]: ...
    def bulk_create(self, data: list[dict[str, Any]], ignore_errors: bool = False) -> list[Any]: ...
    def get(self, **kwargs: Any) -> Any: ...
    def get_queryset(self) -> BaseQuery: ...
    def filter(self, **kwargs: Any) -> BaseQuery: ...
    def all(self) -> BaseQuery: ...
    def first(self) -> Any | None: ...
    def exclude(self, **kwargs: Any) -> BaseQuery: ...
    def order(self, ordering: str) -> BaseQuery: ...
    def count(self) -> int: ...
    def exists(self) -> bool: ...

class ModelBase(type):
    def __new__(cls, name: str, bases: tuple[type, ...], attrs: dict[str, Any]) -> ModelBase: ...

class Model(metaclass=ModelBase):
    objects: ClassVar[Manager]
    _meta: ClassVar[Options]
    id: Any

    def __init__(self, **kwargs: Any) -> None: ...
    def __init_subclass__(cls, **kwargs: Any) -> None: ...
    @classmethod
    def get_serializer_class(cls) -> type: ...
    @classmethod
    def serialize(cls, obj: Any) -> dict[str, Any]: ...
    def update(self, **kwargs: Any) -> Any: ...
    def save(self) -> Any: ...
    def create(self, **kwargs: Any) -> Any: ...
    def delete(self, **kwargs: Any) -> Any: ...
