"""
Skills 发现和加载器
"""

import re
from pathlib import Path
from typing import Optional
from dataclasses import dataclass

import yaml


# 默认 Skills 搜索路径（项目级优先，用户级兜底）
DEFAULT_SKILL_PATHS = [
    Path.cwd() / ".claude" / "skills",
    Path.home() / ".claude" / "skills",
]


@dataclass
class SkillMetadata:
    """Skill 元数据（Level 1）"""
    name: str
    description: str
    skill_path: Path

    def to_prompt_line(self) -> str:
        return f"- **{self.name}**: {self.description}"


@dataclass
class SkillContent:
    """Skill 完整内容（Level 2）"""
    metadata: SkillMetadata
    instructions: str


class SkillLoader:
    """Skills 加载器"""

    def __init__(self, skill_paths: list[Path] | None = None):
        self.skill_paths = skill_paths or DEFAULT_SKILL_PATHS
        self._metadata_cache: dict[str, SkillMetadata] = {}

    def scan_skills(self) -> list[SkillMetadata]:
        """Level 1: 扫描所有 Skills 元数据"""
        skills = []
        seen_names = set()

        for base_path in self.skill_paths:
            if not base_path.exists():
                continue

            for skill_dir in base_path.iterdir():
                if not skill_dir.is_dir():
                    continue

                skill_md = skill_dir / "SKILL.md"
                if not skill_md.exists():
                    continue

                metadata = self._parse_skill_metadata(skill_md)
                if metadata and metadata.name not in seen_names:
                    skills.append(metadata)
                    seen_names.add(metadata.name)
                    self._metadata_cache[metadata.name] = metadata

        return skills

    def _parse_skill_metadata(self, skill_md_path: Path) -> Optional[SkillMetadata]:
        try:
            content = skill_md_path.read_text(encoding="utf-8")
        except Exception:
            return None

        frontmatter_match = re.match(
            r'^---\s*\n(.*?)\n---\s*\n',
            content,
            re.DOTALL
        )

        if not frontmatter_match:
            return None

        try:
            frontmatter = yaml.safe_load(frontmatter_match.group(1))
            name = frontmatter.get("name", "")
            description = frontmatter.get("description", "")

            if not name:
                return None

            return SkillMetadata(
                name=name,
                description=description,
                skill_path=skill_md_path.parent,
            )
        except yaml.YAMLError:
            return None

    def load_skill(self, skill_name: str) -> Optional[SkillContent]:
        """Level 2: 加载 Skill 完整内容"""
        metadata = self._metadata_cache.get(skill_name)
        if not metadata:
            self.scan_skills()
            metadata = self._metadata_cache.get(skill_name)

        if not metadata:
            return None

        skill_md = metadata.skill_path / "SKILL.md"
        try:
            content = skill_md.read_text(encoding="utf-8")
        except Exception:
            return None

        body_match = re.match(
            r'^---\s*\n.*?\n---\s*\n(.*)$',
            content,
            re.DOTALL
        )
        instructions = body_match.group(1).strip() if body_match else content

        return SkillContent(
            metadata=metadata,
            instructions=instructions,
        )

    def build_system_prompt(self, base_prompt: str = "") -> str:
        """构建包含 Skills 列表的 system prompt"""
        skills = self.scan_skills()

        if skills:
            skills_section = "## Available Skills\n\n"
            skills_section += "You have access to the following specialized skills:\n\n"
            for skill in skills:
                skills_section += skill.to_prompt_line() + "\n"
            skills_section += "\n"
            skills_section += "### How to Use Skills\n\n"
            skills_section += "1. **Discover**: Review the skills list above\n"
            skills_section += "2. **Load**: When a user request matches a skill's description, "
            skills_section += "use `load_skill(skill_name)` to get detailed instructions\n"
            skills_section += "3. **Execute**: Follow the skill's instructions, which may include "
            skills_section += "running scripts via `bash`\n\n"
            skills_section += "**Important**: Only load a skill when it's relevant to the user's request. "
            skills_section += "Script code never enters the context - only their output does.\n"
        else:
            skills_section = "## Skills\n\nNo skills currently available.\n"

        if base_prompt:
            return f"{base_prompt}\n\n{skills_section}"
        else:
            return f"You are a helpful coding assistant.\n\n{skills_section}"
