"""Skill 系统基类

定义标准 Skill 接口，支持用户可调用命令（以 / 开头）
"""

from abc import ABC, abstractmethod
from enum import Enum
from typing import Any, Dict, List, Optional

from pydantic import BaseModel, Field

# ============================================================================
# Skill 类型枚举
# ============================================================================


class SkillType(str, Enum):
    """Skill 类型"""
    RIGID = "rigid"  # 严格遵循规范
    FLEXIBLE = "flexible"  # 灵活适应上下文


# ============================================================================
# 标准输入输出模型
# ============================================================================


class SkillArgument(BaseModel):
    """Skill 参数定义"""
    name: str = Field(..., description="参数名称")
    description: str = Field(..., description="参数功能描述")
    type: str = Field(default="string", description="参数类型")
    required: bool = Field(default=False, description="是否必填")
    default: Optional[Any] = Field(default=None, description="默认值")


class SkillContext(BaseModel):
    """Skill 执行上下文"""
    user_id: Optional[str] = Field(default=None, description="用户 ID")
    session_id: Optional[str] = Field(default=None, description="会话 ID")
    source: str = Field(default="cli", description="来源渠道")
    directory: Optional[str] = Field(default=None, description="工作目录")
    metadata: Dict[str, Any] = Field(default_factory=dict, description="额外元数据")


class SkillResult(BaseModel):
    """Skill 执行结果"""
    success: bool = Field(..., description="执行是否成功")
    message: str = Field(..., description="结果消息")
    data: Optional[Any] = Field(default=None, description="返回数据")
    error: Optional[str] = Field(default=None, description="错误信息")
    metadata: Dict[str, Any] = Field(default_factory=dict, description="额外元数据")


# ============================================================================
# Skill 抽象基类
# ============================================================================


class BaseSkill(ABC):
    """标准 Skill 基类

    属性:
        name: Skill 名称（不含 /）
        description: Skill 功能描述
        arguments: 参数定义列表
        category: Skill 分类
        skill_type: Skill 类型（RIGID 或 FLEXIBLE）
    """

    name: str
    description: str
    arguments: List[SkillArgument] = Field(default_factory=list)
    category: str = "general"
    skill_type: SkillType = SkillType.FLEXIBLE

    def __init__(self, **data):
        """初始化 Skill"""
        super().__init__(**data)

    @abstractmethod
    async def execute(self, args: Dict[str, Any], context: SkillContext) -> SkillResult:
        """执行 Skill

        Args:
            args: Skill 参数
            context: 执行上下文

        Returns:
            SkillResult: 执行结果
        """
        pass

    def get_input_schema(self) -> Dict[str, Any]:
        """获取 JSON Schema 格式的输入参数定义"""
        properties = {}
        required = []

        for arg in self.arguments:
            prop = {
                "type": arg.type,
                "description": arg.description,
            }
            if arg.default is not None:
                prop["default"] = arg.default
            properties[arg.name] = prop

            if arg.required:
                required.append(arg.name)

        return {
            "type": "object",
            "properties": properties,
            "required": required
        }

    def to_function_call(self) -> Dict[str, Any]:
        """转换为 Function Call 格式"""
        return {
            "type": "function",
            "function": {
                "name": self.name,
                "description": self.description,
                "parameters": self.get_input_schema()
            }
        }

    def __repr__(self) -> str:
        return f"<{self.__class__.__name__}(name={self.name}, category={self.category})>"


# ============================================================================
# Skill 集合容器
# ============================================================================


class SkillCollection:
    """Skill 集合 - 管理多个 Skill"""

    def __init__(self, skills: Optional[List[BaseSkill]] = None):
        self._skills: Dict[str, BaseSkill] = {}
        if skills:
            for skill in skills:
                self.add(skill)

    def add(self, skill: BaseSkill) -> None:
        """添加 Skill"""
        self._skills[skill.name] = skill

    def get(self, name: str) -> Optional[BaseSkill]:
        """获取 Skill"""
        return self._skills.get(name)

    def remove(self, name: str) -> bool:
        """移除 Skill"""
        if name in self._skills:
            del self._skills[name]
            return True
        return False

    def list_skills(self) -> List[BaseSkill]:
        """列出所有 Skill"""
        return list(self._skills.values())

    def list_by_category(self, category: str) -> List[BaseSkill]:
        """按分类列出 Skill"""
        return [s for s in self._skills.values() if s.category == category]

    @property
    def categories(self) -> List[str]:
        """获取所有分类"""
        return list(set(s.category for s in self._skills.values()))

    @property
    def names(self) -> List[str]:
        """获取所有 Skill 名称"""
        return list(self._skills.keys())

    def __len__(self) -> int:
        return len(self._skills)

    def __contains__(self, name: str) -> bool:
        return name in self._skills
