"""Runtime tools for listing and managing skills."""

from __future__ import annotations

from dataclasses import dataclass
import json
from typing import Any

from beaver.tools.base import BaseTool, ToolContext, ToolResult, ToolSpec


def _result(tool_name: str, success: bool, **payload: Any) -> ToolResult:
    return ToolResult(
        success=success,
        tool_name=tool_name,
        content=json.dumps({"success": success, **payload}, ensure_ascii=False, indent=2),
        error=None if success else str(payload.get("error") or "failed"),
    )


@dataclass(slots=True)
class SkillsListTool(BaseTool):
    @property
    def spec(self) -> ToolSpec:
        return ToolSpec(
            name="skills_list",
            description="List available skills with descriptions.",
            input_schema={"type": "object", "properties": {}},
            toolset="skills",
        )

    async def invoke(self, arguments: dict[str, Any], context: ToolContext) -> ToolResult:
        loader = context.get("skills_loader")
        if loader is None:
            return _result(self.spec.name, False, error="skills_loader is unavailable")
        skills = [
            {
                "name": record.name,
                "description": record.description,
                "source": record.source,
                "version": record.version,
                "tool_hints": list(record.tool_hints),
            }
            for record in loader.list_skills(filter_unavailable=False)
        ]
        return _result(self.spec.name, True, skills=skills)


@dataclass(slots=True)
class SkillManageTool(BaseTool):
    @property
    def spec(self) -> ToolSpec:
        return ToolSpec(
            name="skill_manage",
            description="Create a new skill draft. Publishing still goes through the normal review/publish APIs.",
            input_schema={
                "type": "object",
                "properties": {
                    "action": {"type": "string", "enum": ["create_draft"]},
                    "name": {"type": "string"},
                    "description": {"type": "string"},
                    "content": {"type": "string"},
                },
                "required": ["action", "name", "content"],
            },
            toolset="skills",
        )

    async def invoke(self, arguments: dict[str, Any], context: ToolContext) -> ToolResult:
        if arguments.get("action") != "create_draft":
            return _result(self.spec.name, False, error="only create_draft is supported")
        draft_service = context.get("draft_service")
        if draft_service is None:
            return _result(self.spec.name, False, error="draft_service is unavailable")
        name = str(arguments.get("name") or "").strip()
        content = str(arguments.get("content") or "").strip()
        if not name or not content:
            return _result(self.spec.name, False, error="name and content are required")
        draft = draft_service.create_new_skill_draft(
            skill_name=name,
            proposed_content=content,
            proposed_frontmatter={"description": str(arguments.get("description") or name)},
            created_by=context.user_id or "agent",
            reason="created by skill_manage tool",
            trigger_session_id=context.session_id,
        )
        return _result(self.spec.name, True, draft=draft.to_dict())
