"""
统一结果格式定义
提供标准化的操作结果类型，确保不同方法返回格式一致
"""
from typing import Generic, TypeVar, Optional, Any, Dict, List
from dataclasses import dataclass, field
from enum import Enum


T = TypeVar('T')


class ResultStatus(Enum):
    """结果状态枚举"""
    SUCCESS = "success"
    FAILED = "failed"
    PARTIAL = "partial"  # 部分成功
    SKIPPED = "skipped"  # 跳过


@dataclass
class Result(Generic[T]):
    """
    通用结果类
    
    提供统一的操作结果格式：
    - success: 操作是否成功
    - data: 返回的数据
    - message: 描述信息
    - error: 错误信息（失败时）
    - metadata: 额外的元数据
    """
    success: bool
    data: Optional[T] = None
    message: str = ""
    error: Optional[str] = None
    metadata: Dict[str, Any] = field(default_factory=dict)
    status: ResultStatus = ResultStatus.SUCCESS
    
    def __post_init__(self):
        """自动设置状态"""
        if self.status == ResultStatus.SUCCESS and not self.success:
            self.status = ResultStatus.FAILED
    
    @classmethod
    def ok(cls, data: Optional[T] = None, message: str = "", **metadata) -> "Result[T]":
        """
        创建成功结果
        
        Args:
            data: 返回数据
            message: 描述信息
            **metadata: 额外元数据
            
        Returns:
            Result对象
        """
        return cls(
            success=True,
            data=data,
            message=message,
            status=ResultStatus.SUCCESS,
            metadata=metadata
        )
    
    @classmethod
    def fail(cls, error: str, message: str = "", **metadata) -> "Result[T]":
        """
        创建失败结果
        
        Args:
            error: 错误信息
            message: 描述信息
            **metadata: 额外元数据
            
        Returns:
            Result对象
        """
        return cls(
            success=False,
            error=error,
            message=message,
            status=ResultStatus.FAILED,
            metadata=metadata
        )
    
    @classmethod
    def partial(cls, data: Optional[T] = None, message: str = "", **metadata) -> "Result[T]":
        """
        创建部分成功结果
        
        Args:
            data: 返回数据
            message: 描述信息
            **metadata: 额外元数据
            
        Returns:
            Result对象
        """
        return cls(
            success=True,
            data=data,
            message=message,
            status=ResultStatus.PARTIAL,
            metadata=metadata
        )
    
    @classmethod
    def skip(cls, message: str = "", **metadata) -> "Result[T]":
        """
        创建跳过结果
        
        Args:
            message: 描述信息
            **metadata: 额外元数据
            
        Returns:
            Result对象
        """
        return cls(
            success=True,
            message=message,
            status=ResultStatus.SKIPPED,
            metadata=metadata
        )
    
    def is_ok(self) -> bool:
        """是否成功"""
        return self.success and self.status == ResultStatus.SUCCESS
    
    def is_partial(self) -> bool:
        """是否部分成功"""
        return self.success and self.status == ResultStatus.PARTIAL
    
    def is_skip(self) -> bool:
        """是否被跳过"""
        return self.status == ResultStatus.SKIPPED


@dataclass
class OperationResult(Result[bool]):
    """
    操作结果（布尔型）
    用于简单的成功/失败操作
    """
    pass


@dataclass
class IndexResult:
    """
    索引操作结果
    专门用于索引构建和加载操作
    """
    success: bool
    index: Optional[Any] = None  # VectorStoreIndex
    nodes_count: int = 0
    index_type: str = ""  # "vector", "bm25", "hybrid"
    message: str = ""
    error: Optional[str] = None
    duration: float = 0.0  # 操作耗时（秒）
    metadata: Dict[str, Any] = field(default_factory=dict)
    
    @classmethod
    def ok(
        cls,
        index: Any,
        nodes_count: int,
        index_type: str,
        message: str = "",
        duration: float = 0.0,
        **metadata
    ) -> "IndexResult":
        """创建成功的索引结果"""
        return cls(
            success=True,
            index=index,
            nodes_count=nodes_count,
            index_type=index_type,
            message=message,
            duration=duration,
            metadata=metadata
        )
    
    @classmethod
    def fail(
        cls,
        error: str,
        index_type: str,
        message: str = "",
        **metadata
    ) -> "IndexResult":
        """创建失败的索引结果"""
        return cls(
            success=False,
            error=error,
            index_type=index_type,
            message=message,
            metadata=metadata
        )
    
    @classmethod
    def skip(
        cls,
        index_type: str,
        message: str = "",
        **metadata
    ) -> "IndexResult":
        """创建跳过的索引结果（索引已存在等情况）"""
        return cls(
            success=True,
            index=None,
            nodes_count=0,
            index_type=index_type,
            message=message,
            metadata=metadata
        )


@dataclass
class QueryResult:
    """
    查询结果
    统一查询操作的返回格式
    """
    success: bool
    response: Optional[Any] = None  # 查询响应对象
    results: List[Any] = field(default_factory=list)  # 检索结果列表
    query_text: str = ""
    retrieval_mode: str = ""  # "vector", "bm25", "hybrid"
    message: str = ""
    error: Optional[str] = None
    duration: float = 0.0  # 查询耗时（秒）
    metadata: Dict[str, Any] = field(default_factory=dict)
    
    @classmethod
    def ok(
        cls,
        response: Any,
        query_text: str,
        retrieval_mode: str,
        results: Optional[List[Any]] = None,
        message: str = "",
        duration: float = 0.0,
        **metadata
    ) -> "QueryResult":
        """创建成功的查询结果"""
        return cls(
            success=True,
            response=response,
            results=results or [],
            query_text=query_text,
            retrieval_mode=retrieval_mode,
            message=message,
            duration=duration,
            metadata=metadata
        )
    
    @classmethod
    def fail(
        cls,
        error: str,
        query_text: str,
        retrieval_mode: str = "",
        message: str = "",
        **metadata
    ) -> "QueryResult":
        """创建失败的查询结果"""
        return cls(
            success=False,
            error=error,
            query_text=query_text,
            retrieval_mode=retrieval_mode,
            message=message,
            metadata=metadata
        )
