"""
cvc.agent.skills — Skill system for CVC Agent.

Skills are reusable patterns/templates defined as markdown files
with YAML frontmatter. They can be auto-invoked based on prompt
patterns or manually triggered via the /skill command.

Skill definition: .cvc/skills/<name>/skill.md
Frontmatter:
    name: skill-name
    description: What this skill does
    tools: [read_file, grep]  # Allowed tools (optional)
    auto_invoke: ["regex pattern"]  # Auto-trigger patterns (optional)
"""

from __future__ import annotations

import logging
import re
from dataclasses import dataclass, field
from pathlib import Path
from typing import Any

logger = logging.getLogger("cvc.agent.skills")


@dataclass
class Skill:
    """A loaded CVC skill."""
    name: str
    description: str
    content: str  # The skill's instruction content
    tools: list[str] = field(default_factory=list)  # Allowed tools
    auto_invoke_patterns: list[str] = field(default_factory=list)
    path: Path | None = None

    def matches(self, prompt: str) -> bool:
        """Check if this skill should auto-invoke for the given prompt."""
        for pattern in self.auto_invoke_patterns:
            try:
                if re.search(pattern, prompt, re.IGNORECASE):
                    return True
            except re.error:
                pass
        return False


def discover_skills(workspace: str | Path) -> list[Skill]:
    """Discover skills from project and user directories."""
    skills = []
    search_dirs = [
        Path(workspace) / ".cvc" / "skills",
        Path.home() / ".cvc" / "skills",
    ]

    for search_dir in search_dirs:
        if not search_dir.is_dir():
            continue
        # Skills can be directories with skill.md or standalone .md files
        for item in sorted(search_dir.iterdir()):
            skill = None
            if item.is_dir():
                skill_file = item / "skill.md"
                if skill_file.exists():
                    skill = _load_skill(skill_file, item.name)
            elif item.suffix == ".md":
                skill = _load_skill(item, item.stem)
            if skill:
                skills.append(skill)

    return skills


def _load_skill(skill_file: Path, name: str) -> Skill | None:
    """Load a skill from a markdown file with optional YAML frontmatter."""
    try:
        text = skill_file.read_text(encoding="utf-8")
    except Exception as e:
        logger.warning("Failed to read skill %s: %s", skill_file, e)
        return None

    # Parse YAML frontmatter (between --- markers)
    frontmatter = {}
    content = text
    if text.startswith("---"):
        parts = text.split("---", 2)
        if len(parts) >= 3:
            try:
                import yaml
                frontmatter = yaml.safe_load(parts[1]) or {}
            except Exception:
                # Fallback: simple key: value parsing
                for line in parts[1].strip().splitlines():
                    if ":" in line:
                        k, v = line.split(":", 1)
                        frontmatter[k.strip()] = v.strip()
            content = parts[2].strip()

    return Skill(
        name=frontmatter.get("name", name),
        description=frontmatter.get("description", content[:100]),
        content=content,
        tools=frontmatter.get("tools", []),
        auto_invoke_patterns=frontmatter.get("auto_invoke", []),
        path=skill_file,
    )


def find_matching_skills(skills: list[Skill], prompt: str) -> list[Skill]:
    """Find skills that should auto-invoke for a given prompt."""
    return [s for s in skills if s.matches(prompt)]
