"""Skills endpoint handlers.

Provides REST API for listing and getting skill details.
Skills are loaded from stdlib/skills/_builtin/ and configured directories.
"""

from __future__ import annotations

import logging
from typing import TYPE_CHECKING

from core.tools import get_tool_registry
from server.errors import ErrorCode
from server.transport.schemas import SkillListItem, SkillListResponse, SkillResponse
from server.transport.utils import error_response, get_request_id, get_runtime, json_response

if TYPE_CHECKING:
    from aiohttp import web

logger = logging.getLogger(__name__)


async def handle_list_skills(request: web.Request) -> web.Response:
    """GET /api/v1/skills - List all available skills.

    Query params:
        builtin: "true" to filter to only builtin skills
        tag: Filter by tag (e.g., "builtin", "external")
    """
    runtime = get_runtime(request)
    request_id = get_request_id(request)

    # Get filter params
    builtin_only = request.query.get("builtin", "").lower() == "true"
    tag_filter = request.query.get("tag")

    skills_list: list[SkillListItem] = []
    for skill in runtime.skills.values():
        # Filter by builtin
        if builtin_only and "builtin" not in getattr(skill, "tags", set()):
            continue

        # Filter by tag
        if tag_filter and tag_filter not in getattr(skill, "tags", set()):
            continue

        skills_list.append(SkillListItem(
            id=skill.id,
            name=skill.name,
            description=skill.description or "",
            tags=list(getattr(skill, "tags", set())),
            tools=[f"{skill.id}.{t}" for t in _get_skill_tools(skill)],
        ))

    logger.info(
        "List skills  builtin_only=%s  tag=%s  count=%d  [request_id=%s]",
        builtin_only,
        tag_filter or "all",
        len(skills_list),
        request_id,
    )

    resp = SkillListResponse(skills=skills_list, count=len(skills_list))
    return json_response(request, resp.model_dump(mode="json"))


async def handle_get_skill(request: web.Request) -> web.Response:
    """GET /api/v1/skills/{skill_id} - Get skill details including full instructions."""
    runtime = get_runtime(request)
    skill_id = request.match_info["skill_id"]
    request_id = get_request_id(request)

    skill = runtime.skills.get(skill_id)
    if skill is None:
        logger.warning(
            "Skill not found: %s  [request_id=%s]",
            skill_id,
            request_id,
        )
        return error_response(
            request,
            f"Skill not found: {skill_id}",
            ErrorCode.NOT_FOUND,
            status=404,
        )

    logger.info(
        "Get skill: %s  [request_id=%s]",
        skill_id,
        request_id,
    )

    detail = SkillResponse(
        success=True,
        id=skill.id,
        name=skill.name,
        description=skill.description or "",
        instructions=getattr(skill, "instructions", "") or "",
        tags=list(getattr(skill, "tags", set())),
        tools=[f"{skill.id}.{t}" for t in _get_skill_tools(skill)],
        pathways=getattr(skill, "pathways", []),
    )
    return json_response(request, detail.model_dump(mode="json"))


def _get_skill_tools(skill) -> list[str]:
    """Get list of tool names for a skill."""
    registry = get_tool_registry()
    tool_names = []
    skill_prefix = f"{skill.id}."
    for tool_id in registry.names():
        if tool_id.startswith(skill_prefix):
            # Extract just the tool name (after the skill prefix)
            tool_name = tool_id[len(skill_prefix) :]
            tool_names.append(tool_name)

    return sorted(tool_names)


__all__ = [
    "handle_get_skill",
    "handle_list_skills",
]
