#  Copyright (c) yibocat 2025 All Rights Reserved
#  Python: 3.12.7
#  Date: 2025/8/18 18:23
#  Author: yibow
#  Email: yibocat@yeah.net
#  Software: AxisFuzzy

from typing import Any, Optional, Union, Tuple, Iterator, Dict, overload, List
import numpy as np

from .backend import FuzzarrayBackend
from .fuzznums import Fuzznum
from .triangular import OperationTNorm

class Fuzzarray:

    # 基础属性
    @property
    def backend(self) -> FuzzarrayBackend: ...
    @property
    def md(self) -> np.ndarray: ...
    @property
    def nmd(self) -> np.ndarray: ...
    @property
    def shape(self) -> Tuple[int, ...]: ...
    @property
    def ndim(self) -> int: ...
    @property
    def size(self) -> int: ...
    @property
    def mtype(self) -> str: ...
    @property
    def q(self) -> Optional[int]: ...
    @property
    def kwargs(self) -> Dict[str, Any]: ...
    @property
    def dtype(self) -> Any: ...
    @property
    def score(self) -> float: ...
    @property
    def acc(self) -> float: ...
    @property
    def ind(self) -> float: ...

    # --- 核心、与 mtype 无关的方法 ---
    def __init__(self,
                 data: Optional[Union[np.ndarray, list, tuple, Fuzznum]] = ...,
                 backend: Optional[FuzzarrayBackend] = ...,
                 mtype: Optional[str] = ...,
                 q: Optional[int] = ...,
                 shape: Optional[Tuple[int, ...]] = ...,
                 **kwargs: Any) -> None: ...

    def copy(self) -> 'Fuzzarray': ...
    def execute_vectorized_op(self, op_name: str, other: Any = ...) -> Any: ...

    # --- 索引与迭代 ---
    def __len__(self) -> int: ...
    @overload
    def __getitem__(self, key: Union[int, Tuple[int, ...]]) -> Union[Fuzznum, Fuzzarray]: ...
    @overload
    def __getitem__(self, key: Any) -> 'Fuzzarray': ...
    def __getitem__(self, key: Any) -> Union[Fuzznum, 'Fuzzarray']: ...
    def __setitem__(self, key: Any, value: Fuzznum) -> None: ...
    def __iter__(self) -> Iterator['Fuzzarray']: ...

    # --- Mixin 系统注入的通用方法 (mtype-agnostic) ---
    def reshape(self, *shape: int) -> 'Fuzzarray': ...
    def flatten(self) -> 'Fuzzarray': ...
    def squeeze(self, axis: Union[int, Tuple[int, ...], None] = ...) -> Union[Fuzznum, 'Fuzzarray']: ...
    def ravel(self) -> 'Fuzzarray': ...
    def transpose(self, *axes) -> 'Fuzzarray': ...
    @property
    def T(self) -> 'Fuzzarray': ...
    def broadcast_to(self, *shape: int) -> 'Fuzzarray': ...
    def item(self, *args) -> Fuzznum: ...
    def any(self) -> bool: ...
    def all(self) -> bool: ...
    def concat(self, *others: 'Fuzzarray', axis: int = ...) -> 'Fuzzarray': ...
    def stack(self, *others: 'Fuzzarray', axis: int = ...) -> 'Fuzzarray': ...
    def append(self, item: Union[Fuzznum, 'Fuzzarray', List[Fuzznum]], axis: Optional[int] = ..., inplace: bool = ...) -> Union['Fuzzarray', None]: ...
    def pop(self, index: int = ..., inplace: bool = ...) -> Union[Fuzznum, Tuple[Fuzznum, 'Fuzzarray'], None]: ...

    # --- Extension 系统注入的方法 (mtype-specific but common API) ---
    # 我们在这里声明它们，但返回类型是 Any，因为具体实现依赖 mtype
    def to_csv(self, *args: Any, **kwargs: Any) -> None: ...
    def to_json(self, *args: Any, **kwargs: Any) -> None: ...
    def to_npy(self, *args: Any, **kwargs: Any) -> None: ...
    def distance(self, other: 'Fuzzarray', *args: Any, **kwargs: Any) -> Union[np.ndarray, float]: ...
    def sum(self, axis: Optional[int] = ...) -> Any: ...
    def mean(self, axis: Optional[int] = ...) -> Any: ...
    def max(self, axis: Optional[int] = ...) -> Any: ...
    def min(self, axis: Optional[int] = ...) -> Any: ...
    def prod(self, axis: Optional[int] = ...) -> Any: ...
    def var(self, axis: Optional[int] = ...) -> Any: ...
    def std(self, axis: Optional[int] = ...) -> Any: ...

    # --- 动态属性的回退 ---
    def __getattr__(self, name: str) -> Any: ...

    # --- 运算符重载 ---
    def __add__(self, other: Any) -> 'Fuzzarray': ...
    def __radd__(self, other: Any) -> 'Fuzzarray': ...
    def __sub__(self, other: Any) -> 'Fuzzarray': ...
    def __mul__(self, other: Any) -> 'Fuzzarray': ...
    def __rmul__(self, other: Any) -> 'Fuzzarray': ...
    def __truediv__(self, other: Any) -> 'Fuzzarray': ...
    def __pow__(self, power: Any, modulo: Optional[Any] = ...) -> 'Fuzzarray': ...
    def __gt__(self, other: Any) -> np.ndarray: ...
    def __lt__(self, other: Any) -> np.ndarray: ...
    def __ge__(self, other: Any) -> np.ndarray: ...
    def __le__(self, other: Any) -> np.ndarray: ...
    def __eq__(self, other: Any) -> np.ndarray: ...
    def __ne__(self, other: Any) -> np.ndarray: ...
    def __and__(self, other: Any) -> 'Fuzzarray': ...
    def __or__(self, other: Any) -> 'Fuzzarray': ...
    def __invert__(self) -> 'Fuzzarray': ...
    def __lshift__(self, other: Any) -> 'Fuzzarray': ...
    def __rshift__(self, other: Any) -> 'Fuzzarray': ...
    def __xor__(self, other: Any) -> 'Fuzzarray': ...
    def equivalent(self, other: Any) -> 'Fuzzarray': ...
    def __matmul__(self, other: Any) -> 'Fuzzarray': ...


    def __contains__(self, item: Any) -> bool: ...
    def _fallback_vectorized_op(self, operation: Any, other: Any, tnorm: OperationTNorm) -> Any: ...
    def __repr__(self) -> str: ...
    def __str__(self) -> str: ...
    def __format__(self, format_spec: str = ...) -> Any: ...
    def __bool__(self) -> bool: ...
    def __getstate__(self) -> Dict[str, Any]: ...
    def __setstate__(self, state: Dict[str, Any]) -> None: ...

# --- 工厂函数 ---
def fuzzarray(data: Optional[Any] = ..., 
              backend: Optional[FuzzarrayBackend] = ..., 
              mtype: Optional[str] = ..., 
              q: Optional[int] = ..., 
              shape: Optional[Tuple[int, ...]] = ..., 
              **mtype_kwargs: Any) -> Fuzzarray: ...
