"""Small local utility tools."""

from __future__ import annotations

from dataclasses import dataclass, field
import json
from typing import Any


def _json_result(success: bool, **payload: Any) -> str:
    return json.dumps({"success": success, **payload}, ensure_ascii=False, indent=2)


@dataclass(slots=True)
class TodoTool:
    name: str = "todo"
    description: str = "Manage a lightweight task list for the current session."
    toolset: str = "planning"
    always_available: bool = False
    parameters: dict[str, Any] = field(
        default_factory=lambda: {
            "type": "object",
            "properties": {
                "todos": {"type": "array", "items": {"type": "object"}},
                "merge": {"type": "boolean", "default": False},
            },
        }
    )

    async def execute(self, *, todos: list[dict[str, Any]] | None = None, merge: bool = False, **kwargs: Any) -> str:
        metadata = kwargs.get("metadata") if isinstance(kwargs.get("metadata"), dict) else {}
        current = list(metadata.get("todos") or [])
        if todos is None:
            return _json_result(True, todos=current)
        next_todos = [dict(item) for item in todos if isinstance(item, dict)]
        metadata["todos"] = [*current, *next_todos] if merge else next_todos
        return _json_result(True, todos=metadata["todos"])


@dataclass(slots=True)
class ClarifyTool:
    name: str = "clarify"
    description: str = "Ask the user for clarification by returning a structured question."
    toolset: str = "planning"
    always_available: bool = False
    parameters: dict[str, Any] = field(
        default_factory=lambda: {
            "type": "object",
            "properties": {
                "question": {"type": "string"},
                "choices": {"type": "array", "items": {"type": "string"}},
            },
            "required": ["question"],
        }
    )

    async def execute(self, *, question: str, choices: list[str] | None = None, **_: Any) -> str:
        return _json_result(True, question=question, choices=[str(item) for item in (choices or [])])


@dataclass(slots=True)
class SendMessageTool:
    name: str = "send_message"
    description: str = "Return a message payload for an external channel. Actual delivery is handled by configured services."
    toolset: str = "messaging"
    always_available: bool = False
    parameters: dict[str, Any] = field(
        default_factory=lambda: {
            "type": "object",
            "properties": {
                "target": {"type": "string"},
                "message": {"type": "string"},
            },
            "required": ["target", "message"],
        }
    )

    async def execute(self, *, target: str, message: str, **_: Any) -> str:
        return _json_result(True, target=target, message=message, delivered=False)


@dataclass(slots=True)
class DelegateTool:
    name: str = "delegate"
    description: str = "Create a structured delegation request for a sub-agent or teammate."
    toolset: str = "coordination"
    always_available: bool = False
    parameters: dict[str, Any] = field(
        default_factory=lambda: {
            "type": "object",
            "properties": {
                "task": {"type": "string"},
                "agent": {"type": "string"},
                "context": {"type": "object"},
            },
            "required": ["task"],
        }
    )

    async def execute(self, *, task: str, agent: str | None = None, context: dict[str, Any] | None = None, **_: Any) -> str:
        return _json_result(
            True,
            task=task,
            agent=agent or "default",
            context=dict(context or {}),
            queued=False,
            note="Delegation request recorded; runtime execution is handled by configured agent services.",
        )


@dataclass(slots=True)
class SpawnTool:
    name: str = "spawn"
    description: str = "Create a structured request to spawn a bounded subtask."
    toolset: str = "coordination"
    always_available: bool = False
    parameters: dict[str, Any] = field(
        default_factory=lambda: {
            "type": "object",
            "properties": {
                "task": {"type": "string"},
                "role": {"type": "string", "default": "worker"},
                "write_scope": {"type": "array", "items": {"type": "string"}},
            },
            "required": ["task"],
        }
    )

    async def execute(self, *, task: str, role: str = "worker", write_scope: list[str] | None = None, **_: Any) -> str:
        return _json_result(
            True,
            task=task,
            role=role,
            write_scope=[str(item) for item in (write_scope or [])],
            queued=False,
            note="Spawn request recorded; runtime execution is handled by configured agent services.",
        )
