from typing import Any, Collection, Dict, List, Optional, Sequence, Tuple, Union

from django.db.migrations.operations.base import Operation
from django.db.models.indexes import Index
from django.db.models.manager import Manager

from django.db.models.fields import Field

class ModelOperation(Operation):
    name: str = ...
    def __init__(self, name: str) -> None: ...
    def name_lower(self) -> str: ...

class CreateModel(ModelOperation):
    fields: Sequence[Tuple[str, Field]] = ...
    options: Any = ...
    bases: Optional[Sequence[Union[type, str]]] = ...
    managers: Optional[Sequence[Tuple[str, Manager]]] = ...
    def __init__(
        self,
        name: str,
        fields: Sequence[Tuple[str, Field]],
        options: Optional[Dict[str, Any]] = ...,
        bases: Optional[Sequence[Union[type, str]]] = ...,
        managers: Optional[Sequence[Tuple[str, Manager]]] = ...,
    ) -> None: ...
    def model_to_key(self, model: str) -> List[str]: ...

class DeleteModel(ModelOperation): ...

class RenameModel(ModelOperation):
    old_name: Any = ...
    new_name: Any = ...
    def __init__(self, old_name: str, new_name: str) -> None: ...
    def old_name_lower(self) -> str: ...
    def new_name_lower(self) -> str: ...

class AlterModelTable(ModelOperation):
    table: Optional[str] = ...
    def __init__(self, name: str, table: Optional[str]) -> None: ...

class ModelOptionOperation(ModelOperation): ...
class FieldRelatedOptionOperation(ModelOptionOperation): ...

class AlterUniqueTogether(FieldRelatedOptionOperation):
    option_name: str = ...
    unique_together: Collection[Sequence[str]] = ...
    def __init__(self, name: str, unique_together: Optional[Collection[Sequence[str]]]) -> None: ...

class AlterIndexTogether(FieldRelatedOptionOperation):
    option_name: str = ...
    index_together: Collection[Sequence[str]] = ...
    def __init__(self, name: str, index_together: Optional[Collection[Sequence[str]]]) -> None: ...

class AlterOrderWithRespectTo(FieldRelatedOptionOperation):
    order_with_respect_to: str = ...
    def __init__(self, name: str, order_with_respect_to: str) -> None: ...

class AlterModelOptions(ModelOptionOperation):
    ALTER_OPTION_KEYS: Any = ...
    options: Dict[str, str] = ...
    def __init__(self, name: str, options: Dict[str, Any]) -> None: ...

class AlterModelManagers(ModelOptionOperation):
    managers: Any = ...
    def __init__(self, name: Any, managers: Any) -> None: ...

class IndexOperation(Operation):
    option_name: str = ...
    def model_name_lower(self): ...

class AddIndex(IndexOperation):
    model_name: str = ...
    index: Index = ...
    def __init__(self, model_name: str, index: Union[str, Index]) -> None: ...

class RemoveIndex(IndexOperation):
    model_name: str = ...
    name: str = ...
    def __init__(self, model_name: str, name: Union[str, Index]) -> None: ...
