"""
ResourceStore 抽象定义

包含两类存储抽象：
1. ResourceStore - 用于管理 KnowledgeResource 相关文件的存储
   文件存储路径: {user_id}/{context_id}/{resource_id}/original/{filename}
   
2. ResourceEntityStore - 资源类实体（Project, KnowledgeResource, Workset, BusinessSetting, Secret, ModelInstance）的 CRUD
"""

from abc import ABC, abstractmethod
from dataclasses import dataclass
from typing import Optional, List, AsyncIterator
from datetime import datetime
from turbo_agent_core.schema.resources import (
    Project, 
    KnowledgeResource, 
    Workset, 
    BusinessSetting
)
from turbo_agent_core.schema.external import Secret
from turbo_agent_core.schema.basic import ModelInstance


@dataclass
class ResourceInfo:
    """资源文件信息"""
    resource_id: str
    name: str
    path: str  # 完整存储路径
    size: int
    content_type: Optional[str]
    created_at: datetime
    updated_at: datetime


class ResourceStore(ABC):
    """
    KnowledgeResource 文件存储抽象基类。
    
    管理用户上传的资源文件，包括：
    - 原始文件上传/下载
    - 解析后的中间文件（预留）
    - 分块后的数据（预留）
    
    存储结构：
        {user_id}/{context_id}/{resource_id}/
        ├── original/{filename}     # 原始文件
        ├── parsed/                  # 解析结果（预留）
        │   └── content.json
        └── chunks/                  # 分块数据（预留）
            └── chunks.json
    """
    
    @abstractmethod
    async def upload_original(
        self,
        user_id: str,
        context_id: str,
        resource_id: str,
        filename: str,
        data: bytes,
        content_type: Optional[str] = None
    ) -> str:
        """
        上传原始文件。
        
        Args:
            user_id: 用户ID
            context_id: 上下文ID (session_{id} / project_{id} / temp_{id})
            resource_id: 资源ID
            filename: 原始文件名
            data: 文件数据
            content_type: MIME类型
            
        Returns:
            完整存储路径: {user_id}/{context_id}/{resource_id}/original/{filename}
        """
        pass
    
    @abstractmethod
    async def download(self, path: str) -> bytes:
        """
        下载文件。
        
        Args:
            path: 完整存储路径
            
        Returns:
            文件数据
        """
        pass
    
    @abstractmethod
    async def download_stream(self, path: str) -> AsyncIterator[bytes]:
        """
        流式下载文件。
        
        Args:
            path: 完整存储路径
            
        Yields:
            文件数据块
        """
        pass
    
    @abstractmethod
    async def delete_resource(
        self,
        user_id: str,
        context_id: str,
        resource_id: str
    ) -> bool:
        """
        删除整个资源目录（包括原始文件和解析结果）。
        
        Args:
            user_id: 用户ID
            context_id: 上下文ID
            resource_id: 资源ID
            
        Returns:
            是否删除成功
        """
        pass
    
    @abstractmethod
    async def delete_file(self, path: str) -> bool:
        """
        删除指定路径的文件。
        
        Args:
            path: 完整存储路径
            
        Returns:
            是否删除成功
        """
        pass
    
    @abstractmethod
    async def exists(self, path: str) -> bool:
        """
        检查文件是否存在。
        
        Args:
            path: 完整存储路径
            
        Returns:
            文件是否存在
        """
        pass
    
    @abstractmethod
    async def get_size(self, path: str) -> int:
        """
        获取文件大小。
        
        Args:
            path: 完整存储路径
            
        Returns:
            文件大小（字节）
        """
        pass
    
    # ===== 子资源操作（预留接口）=====
    
    async def save_parsed(
        self,
        user_id: str,
        context_id: str,
        resource_id: str,
        data: bytes,
        format: str = "json"
    ) -> str:
        """
        保存解析后的内容（预留）。
        
        Args:
            format: 解析结果格式，默认 json
            
        Returns:
            存储路径
        """
        raise NotImplementedError("Parsed content storage not implemented")
    
    async def get_parsed(
        self,
        user_id: str,
        context_id: str,
        resource_id: str,
        format: str = "json"
    ) -> Optional[bytes]:
        """
        获取解析后的内容（预留）。
        """
        raise NotImplementedError("Parsed content retrieval not implemented")
    
    async def save_chunks(
        self,
        user_id: str,
        context_id: str,
        resource_id: str,
        data: bytes
    ) -> str:
        """
        保存分块后的数据（预留）。
        """
        raise NotImplementedError("Chunks storage not implemented")
    
    async def get_chunks(
        self,
        user_id: str,
        context_id: str,
        resource_id: str
    ) -> Optional[bytes]:
        """
        获取分块后的数据（预留）。
        """
        raise NotImplementedError("Chunks retrieval not implemented")


class ResourceEntityStore(ABC):
    """
    资源类实体的配置存储抽象类。
    
    包含 Project, KnowledgeResource, Workset, BusinessSetting, Secret, ModelInstance 的 CRUD。
    所有方法均支持 **kwargs 参数，用于实现侧传入鉴权信息。
    """

    # ========== Project CRUD ==========
    @abstractmethod
    async def get_project(self, project_id: str, **kwargs) -> Optional[Project]:
        """
        根据 ID 获取 Project。

        Args:
            project_id: Project 唯一标识
            **kwargs: 实现侧可传入 user_id, org_id 等鉴权信息
        """
        pass

    @abstractmethod
    async def save_project(self, project: Project, **kwargs) -> str:
        """
        保存 Project，返回 Project ID。

        Args:
            project: Project 实例
            **kwargs: 实现侧可传入 user_id, org_id 等鉴权信息
        """
        pass

    @abstractmethod
    async def list_projects(
        self, 
        org_id: Optional[str] = None,
        skip: int = 0, 
        limit: int = 20, 
        **kwargs
    ) -> List[Project]:
        """
        列出 Projects。

        Args:
            org_id: 可选的组织ID过滤
            skip: 跳过的记录数
            limit: 返回的最大记录数
            **kwargs: 实现侧可传入 user_id, org_id 等鉴权信息
        """
        pass

    @abstractmethod
    async def delete_project(self, project_id: str, **kwargs) -> bool:
        """
        删除 Project。

        Args:
            project_id: Project 唯一标识
            **kwargs: 实现侧可传入 user_id, org_id 等鉴权信息
        """
        pass

    # ========== KnowledgeResource CRUD ==========
    @abstractmethod
    async def get_knowledge_resource(
        self, 
        resource_id: str, 
        **kwargs
    ) -> Optional[KnowledgeResource]:
        """
        根据 ID 获取 KnowledgeResource。

        Args:
            resource_id: Resource 唯一标识
            **kwargs: 实现侧可传入 user_id, org_id 等鉴权信息
        """
        pass

    @abstractmethod
    async def save_knowledge_resource(
        self, 
        resource: KnowledgeResource, 
        **kwargs
    ) -> str:
        """
        保存 KnowledgeResource，返回 Resource ID。

        Args:
            resource: KnowledgeResource 实例
            **kwargs: 实现侧可传入 user_id, org_id 等鉴权信息
        """
        pass

    @abstractmethod
    async def list_knowledge_resources(
        self, 
        project_id: Optional[str] = None, 
        skip: int = 0, 
        limit: int = 20, 
        **kwargs
    ) -> List[KnowledgeResource]:
        """
        列出 KnowledgeResources。

        Args:
            project_id: 可选的项目ID过滤
            skip: 跳过的记录数
            limit: 返回的最大记录数
            **kwargs: 实现侧可传入 user_id, org_id 等鉴权信息
        """
        pass

    @abstractmethod
    async def delete_knowledge_resource(
        self, 
        resource_id: str, 
        **kwargs
    ) -> bool:
        """
        删除 KnowledgeResource。

        Args:
            resource_id: Resource 唯一标识
            **kwargs: 实现侧可传入 user_id, org_id 等鉴权信息
        """
        pass

    # ========== Workset CRUD ==========
    @abstractmethod
    async def get_workset(self, workset_id: str, **kwargs) -> Optional[Workset]:
        """
        根据 ID 获取 Workset。

        Args:
            workset_id: Workset 唯一标识
            **kwargs: 实现侧可传入 user_id, org_id 等鉴权信息
        """
        pass

    @abstractmethod
    async def save_workset(self, workset: Workset, **kwargs) -> str:
        """
        保存 Workset，返回 Workset ID。

        Args:
            workset: Workset 实例
            **kwargs: 实现侧可传入 user_id, org_id 等鉴权信息
        """
        pass

    @abstractmethod
    async def list_worksets(
        self, 
        project_id: Optional[str] = None,
        owner_id: Optional[str] = None,
        skip: int = 0, 
        limit: int = 20, 
        **kwargs
    ) -> List[Workset]:
        """
        列出 Worksets。

        Args:
            project_id: 可选的项目ID过滤
            owner_id: 可选的所有者ID过滤
            skip: 跳过的记录数
            limit: 返回的最大记录数
            **kwargs: 实现侧可传入 user_id, org_id 等鉴权信息
        """
        pass

    @abstractmethod
    async def delete_workset(self, workset_id: str, **kwargs) -> bool:
        """
        删除 Workset。

        Args:
            workset_id: Workset 唯一标识
            **kwargs: 实现侧可传入 user_id, org_id 等鉴权信息
        """
        pass

    # ========== BusinessSetting CRUD ==========
    @abstractmethod
    async def get_business_setting(
        self, 
        setting_id: str, 
        **kwargs
    ) -> Optional[BusinessSetting]:
        """
        根据 ID 获取 BusinessSetting。

        Args:
            setting_id: Setting 唯一标识
            **kwargs: 实现侧可传入 user_id, org_id 等鉴权信息
        """
        pass

    @abstractmethod
    async def save_business_setting(
        self, 
        setting: BusinessSetting, 
        **kwargs
    ) -> str:
        """
        保存 BusinessSetting，返回 Setting ID。

        Args:
            setting: BusinessSetting 实例
            **kwargs: 实现侧可传入 user_id, org_id 等鉴权信息
        """
        pass

    @abstractmethod
    async def list_business_settings(
        self, 
        project_id: Optional[str] = None,
        skip: int = 0, 
        limit: int = 20, 
        **kwargs
    ) -> List[BusinessSetting]:
        """
        列出 BusinessSettings。

        Args:
            project_id: 可选的项目ID过滤
            skip: 跳过的记录数
            limit: 返回的最大记录数
            **kwargs: 实现侧可传入 user_id, org_id 等鉴权信息
        """
        pass

    @abstractmethod
    async def delete_business_setting(
        self, 
        setting_id: str, 
        **kwargs
    ) -> bool:
        """
        删除 BusinessSetting。

        Args:
            setting_id: Setting 唯一标识
            **kwargs: 实现侧可传入 user_id, org_id 等鉴权信息
        """
        pass

    # ========== Secret CRUD（来自 external.py，但属于 Resource）==========
    @abstractmethod
    async def get_secret(self, secret_id: str, **kwargs) -> Optional[Secret]:
        """
        根据 ID 获取 Secret。

        Args:
            secret_id: Secret 唯一标识
            **kwargs: 实现侧可传入 user_id, org_id 等鉴权信息
        """
        pass

    @abstractmethod
    async def save_secret(self, secret: Secret, **kwargs) -> str:
        """
        保存 Secret，返回 Secret ID。

        Args:
            secret: Secret 实例
            **kwargs: 实现侧可传入 user_id, org_id 等鉴权信息
        """
        pass

    @abstractmethod
    async def list_secrets(
        self, 
        platform_id: Optional[str] = None,
        skip: int = 0, 
        limit: int = 20, 
        **kwargs
    ) -> List[Secret]:
        """
        列出 Secrets。

        Args:
            platform_id: 可选的平台ID过滤
            skip: 跳过的记录数
            limit: 返回的最大记录数
            **kwargs: 实现侧可传入 user_id, org_id 等鉴权信息
        """
        pass

    @abstractmethod
    async def delete_secret(self, secret_id: str, **kwargs) -> bool:
        """
        删除 Secret。

        Args:
            secret_id: Secret 唯一标识
            **kwargs: 实现侧可传入 user_id, org_id 等鉴权信息
        """
        pass

    # ========== ModelInstance CRUD（来自 basic.py）==========
    @abstractmethod
    async def get_model_instance(
        self, 
        instance_id: str, 
        **kwargs
    ) -> Optional[ModelInstance]:
        """
        根据 ID 获取 ModelInstance。

        Args:
            instance_id: ModelInstance 唯一标识
            **kwargs: 实现侧可传入 user_id, org_id 等鉴权信息
        """
        pass

    @abstractmethod
    async def save_model_instance(
        self, 
        instance: ModelInstance, 
        model_id: str, 
        **kwargs
    ) -> str:
        """
        保存 ModelInstance，返回 Instance ID。

        Args:
            instance: ModelInstance 实例
            model_id: 关联的 Model ID
            **kwargs: 实现侧可传入 user_id, org_id 等鉴权信息
        """
        pass

    @abstractmethod
    async def delete_model_instance(
        self, 
        instance_id: str, 
        **kwargs
    ) -> bool:
        """
        删除 ModelInstance。

        Args:
            instance_id: ModelInstance 唯一标识
            **kwargs: 实现侧可传入 user_id, org_id 等鉴权信息
        """
        pass

    @abstractmethod
    async def list_model_instances(
        self, 
        model_id: Optional[str] = None,
        project_id: Optional[str] = None,
        skip: int = 0, 
        limit: int = 20, 
        **kwargs
    ) -> List[ModelInstance]:
        """
        列出 ModelInstances。

        Args:
            model_id: 可选的 Model ID 过滤
            project_id: 可选的项目ID过滤
            skip: 跳过的记录数
            limit: 返回的最大记录数
            **kwargs: 实现侧可传入 user_id, org_id 等鉴权信息
        """
        pass

    @abstractmethod
    async def update_model_instance(
        self, 
        instance_id: str, 
        instance: ModelInstance, 
        **kwargs
    ) -> bool:
        """
        更新 ModelInstance。

        Args:
            instance_id: ModelInstance 唯一标识
            instance: 更新的 ModelInstance 数据
            **kwargs: 实现侧可传入 user_id, org_id 等鉴权信息
        """
        pass

    # ========== ModelSpace 管理（模型空间）==========
    @abstractmethod
    async def create_model_space(
        self, 
        space: "ModelSpace", 
        creator_id: str,
        **kwargs
    ) -> str:
        """
        创建模型空间。

        Args:
            space: ModelSpace 实例
            creator_id: 创建者ID
            **kwargs: 实现侧可传入 user_id, org_id 等鉴权信息
        """
        pass

    @abstractmethod
    async def get_model_space(
        self, 
        space_id: str, 
        **kwargs
    ) -> Optional["ModelSpace"]:
        """
        获取模型空间详情。

        Args:
            space_id: 模型空间ID
            **kwargs: 实现侧可传入 user_id, org_id 等鉴权信息
        """
        pass

    @abstractmethod
    async def update_model_space(
        self, 
        space_id: str, 
        space: "ModelSpace", 
        **kwargs
    ) -> bool:
        """
        更新模型空间。

        Args:
            space_id: 模型空间ID
            space: 更新的 ModelSpace 数据
            **kwargs: 实现侧可传入 user_id, org_id 等鉴权信息
        """
        pass

    @abstractmethod
    async def delete_model_space(
        self, 
        space_id: str, 
        **kwargs
    ) -> bool:
        """
        删除模型空间。

        Args:
            space_id: 模型空间ID
            **kwargs: 实现侧可传入 user_id, org_id 等鉴权信息
        """
        pass

    @abstractmethod
    async def list_model_spaces(
        self, 
        project_id: Optional[str] = None,
        user_id: Optional[str] = None,
        skip: int = 0, 
        limit: int = 20, 
        **kwargs
    ) -> List["ModelSpace"]:
        """
        列出模型空间。

        Args:
            project_id: 可选的项目ID过滤
            user_id: 可选的用户ID过滤
            skip: 跳过的记录数
            limit: 返回的最大记录数
            **kwargs: 实现侧可传入 user_id, org_id 等鉴权信息
        """
        pass
