from typing import TypeVar

from pandas.core.indexes.api import Index
from typing_extensions import TypeAlias

from pandas._libs.indexing import _NDFrameIndexerBase
from pandas._typing import (
    MaskType,
    Scalar,
    ScalarT,
)

_IndexSliceTuple: TypeAlias = tuple[
    Index | MaskType | Scalar | list[ScalarT] | slice | tuple[Scalar, ...], ...
]

_IndexSliceUnion: TypeAlias = slice | _IndexSliceTuple

_IndexSliceUnionT = TypeVar(
    "_IndexSliceUnionT", bound=_IndexSliceUnion  # pyrefly: ignore
)

class _IndexSlice:
    def __getitem__(self, arg: _IndexSliceUnionT) -> _IndexSliceUnionT: ...

IndexSlice: _IndexSlice

class IndexingMixin:
    @property
    def iloc(self) -> _iLocIndexer: ...
    @property
    def loc(self) -> _LocIndexer: ...
    @property
    def at(self) -> _AtIndexer: ...
    @property
    def iat(self) -> _iAtIndexer: ...

class _NDFrameIndexer(_NDFrameIndexerBase):
    axis = ...
    def __call__(self, axis=...): ...
    def __getitem__(self, key): ...
    def __setitem__(self, key, value) -> None: ...

class _LocationIndexer(_NDFrameIndexer):
    def __getitem__(self, key): ...

class _LocIndexer(_LocationIndexer): ...
class _iLocIndexer(_LocationIndexer): ...

class _ScalarAccessIndexer(_NDFrameIndexerBase):
    def __getitem__(self, key): ...
    def __setitem__(self, key, value) -> None: ...

class _AtIndexer(_ScalarAccessIndexer): ...
class _iAtIndexer(_ScalarAccessIndexer): ...
