"""Skill 基类和注册表。"""

from abc import ABC, abstractmethod
from typing import Any, Optional

from pydantic import BaseModel, Field


class SkillContext(BaseModel):
    """Skill 执行上下文。"""

    session_name: str = Field(..., description="会话名称")
    user_id: str = Field(..., description="用户 ID")
    session_state: dict[str, Any] = Field(default_factory=dict, description="会话状态")
    args: list[str] = Field(default_factory=list, description="参数列表")


class SkillResult(BaseModel):
    """Skill 执行结果。"""

    success: bool = Field(..., description="是否成功")
    output: str = Field(..., description="输出内容")
    metadata: dict[str, Any] = Field(default_factory=dict, description="额外元数据")


class SkillBase(ABC):
    """Skill 基类。"""

    name: str
    description: str
    triggers: list[str] = []

    @abstractmethod
    async def execute(self, ctx: SkillContext) -> SkillResult:
        """执行 Skill。"""
        pass

    def matches(self, content: str) -> bool:
        """检查是否匹配触发条件。"""
        content_stripped = content.strip()
        for trigger in self.triggers:
            if content_stripped.startswith(trigger):
                return True
        return False

    def parse_args(self, content: str) -> list[str]:
        """从内容中解析参数。"""
        content_stripped = content.strip()
        for trigger in self.triggers:
            if content_stripped.startswith(trigger):
                args_str = content_stripped[len(trigger):].strip()
                if args_str:
                    return args_str.split()
                return []
        return []


class SkillRegistry:
    """Skill 注册表。"""

    def __init__(self) -> None:
        self._skills: dict[str, SkillBase] = {}

    def register(self, skill: SkillBase) -> None:
        """注册 Skill。"""
        self._skills[skill.name] = skill

    def get(self, name: str) -> Optional[SkillBase]:
        """获取指定名称的 Skill。"""
        return self._skills.get(name)

    def find_matching(self, content: str) -> Optional[SkillBase]:
        """查找匹配内容的 Skill。"""
        for skill in self._skills.values():
            if skill.matches(content):
                return skill
        return None

    def list_skills(self) -> list[str]:
        """列出所有注册的 Skill 名称。"""
        return list(self._skills.keys())
