"""Service discovery and role inspection tools."""

from __future__ import annotations

from typing import Any

from fastmcp.exceptions import ToolError
from mcp.types import ToolAnnotations

from mcp_eregistrations_ds.ds_client import (
    DSClient,
    DSClientError,
    DSNotFoundError,
    translate_error,
)
from mcp_eregistrations_ds.server import mcp


@mcp.tool(annotations=ToolAnnotations(readOnlyHint=True))
async def service_list(
    instance: str | None = None,
) -> dict[str, Any]:
    """List published services on the DS instance.

    Args:
        instance: Instance profile name.

    Returns:
        dict with services (list of service_id, name, description), count.
    """
    try:
        async with DSClient.for_instance(instance) as client:
            data = await client.get("/backend/services")
    except DSClientError as e:
        raise translate_error(e, resource_type="service") from e

    services = data if isinstance(data, list) else []
    return {
        "services": [
            {
                "service_id": s.get("service_id"),
                "name": s.get("name"),
                "description": s.get("description"),
                "camunda_process_id": s.get("camunda_process_id"),
                "is_publicly_visible": s.get("is_publicly_visible"),
            }
            for s in services
        ],
        "count": len(services),
    }


@mcp.tool(annotations=ToolAnnotations(readOnlyHint=True))
async def service_get(
    service_id: str,
    instance: str | None = None,
) -> dict[str, Any]:
    """Get full details of a single service.

    Args:
        service_id: Service UUID.
        instance: Instance profile name.

    Returns:
        dict with service_id, name, description, camunda_process_id,
        service_attributes, properties.
    """
    try:
        async with DSClient.for_instance(instance) as client:
            try:
                data: dict[str, Any] = await client.get(
                    f"/backend/services/{service_id}"
                )
            except DSNotFoundError:
                raise ToolError(
                    f"Service '{service_id}' not found. "
                    "Use service_list to find valid service IDs."
                )
    except DSClientError as e:
        raise translate_error(e, resource_type="service", resource_id=service_id) from e

    return data


@mcp.tool(annotations=ToolAnnotations(readOnlyHint=True))
async def service_roles(
    service_id: str,
    status: str | None = None,
    instance: str | None = None,
) -> dict[str, Any]:
    """List workflow roles for a service.

    Roles are fetched from Camunda but shortname originates from
    BPA service design. It is a short code (e.g. "DR"), distinct
    from the Camunda activityId used by file_jump_to_role.

    Args:
        service_id: Service UUID. Use "all" for roles across all services.
        status: Filter by process status (e.g. "filepending").
        instance: Instance profile name.

    Returns:
        dict with roles (list of role_name, shortname, sort_order),
        count, service_id.
    """
    params: dict[str, Any] = {}
    if status:
        params["status"] = status

    try:
        async with DSClient.for_instance(instance) as client:
            data = await client.get(
                f"/backend/services/{service_id}/roles", params=params
            )
    except DSClientError as e:
        raise translate_error(
            e, resource_type="service_roles", resource_id=service_id
        ) from e

    raw_roles = data if isinstance(data, list) else []
    roles = [
        {
            "role_name": r.get("roleName"),
            "shortname": r.get("shortname"),
            "sort_order": r.get("sortOrder"),
        }
        for r in raw_roles
    ]
    return {
        "roles": roles,
        "count": len(roles),
        "service_id": service_id,
    }
