# 中文注释：
# 文件：echobot/agent/tools/message.py
# 说明：智能体工具层，实现文件、Shell、网络与消息等工具调用能力。

"""Message Tool - 消息发送工具
=================================================

此模块提供消息发送工具，允许 Agent 向用户发送消息。

功能说明：
- 发送消息到指定的聊天渠道
- 支持设置默认目标渠道和聊天 ID
- 通过回调函数与消息总线集成

使用示例：
    tool = MessageTool(send_callback=bus.publish_outbound)
    tool.set_context("telegram", "12345")
    await tool.execute(content="Hello!")

    # 指定目标发送
    await tool.execute(
        content="Hello!",
        channel="telegram",
        chat_id="12345"
    )
"""

from typing import Any, Callable, Awaitable

from echobot.agent.tools.base import Tool
from echobot.bus.events import OutboundMessage


class MessageTool(Tool):
    """
    消息发送工具

    允许 Agent 向用户发送消息。

    设计特点：
    - 支持默认目标（通过 set_context 设置）
    - 支持指定目标（参数覆盖）
    - 通过回调函数与消息总线集成

    工具元数据：
    - 名称：message
    - 描述：Send a message to the user.
    - 参数：content（消息内容）、channel（可选渠道）、chat_id（可选聊天 ID）
    """

    def __init__(
        self,
        send_callback: Callable[[OutboundMessage], Awaitable[None]] | None = None,
        default_channel: str = "",
        default_chat_id: str = "",
    ):
        """
        初始化消息工具

        Args:
            send_callback: 发送回调函数（接收 OutboundMessage）
            default_channel: 默认消息渠道
            default_chat_id: 默认聊天 ID
        """
        self._send_callback = send_callback
        self._default_channel = default_channel
        self._default_chat_id = default_chat_id

    def set_context(self, channel: str, chat_id: str) -> None:
        """
        设置当前消息上下文

        用于在处理消息时设置默认发送目标。

        Args:
            channel: 渠道名称
            chat_id: 聊天 ID
        """
        self._default_channel = channel
        self._default_chat_id = chat_id

    def set_send_callback(self, callback: Callable[[OutboundMessage], Awaitable[None]]) -> None:
        """
        设置发送回调函数

        Args:
            callback: 回调函数
        """
        self._send_callback = callback

    @property
    def name(self) -> str:
        return "message"

    @property
    def description(self) -> str:
        return "Send a message to the user. Use this when you want to communicate something."

    @property
    def parameters(self) -> dict[str, Any]:
        return {
            "type": "object",
            "properties": {
                "content": {"type": "string", "description": "The message content to send"},
                "channel": {
                    "type": "string",
                    "description": "Optional: target channel (telegram, discord, etc.)",
                },
                "chat_id": {"type": "string", "description": "Optional: target chat/user ID"},
            },
            "required": ["content"],
        }

    async def execute(self, **kwargs: Any) -> str:
        """
        发送消息

        Args:
            **kwargs: 工具参数（content 必选，channel/chat_id 可选）
                - content: 消息内容（必选）
                - channel: 可选目标渠道（覆盖默认）
                - chat_id: 可选聊天 ID（覆盖默认）

        Returns:
            str: 发送结果或错误信息
        """
        content = kwargs.get("content")
        channel = kwargs.get("channel") or self._default_channel
        chat_id = kwargs.get("chat_id") or self._default_chat_id

        if not content:
            return "Error: No message content specified"

        if not channel or not chat_id:
            return "Error: No target channel/chat specified"

        if not self._send_callback:
            return "Error: Message sending not configured"

        msg = OutboundMessage(channel=channel, chat_id=chat_id, content=content)

        try:
            await self._send_callback(msg)
            return f"Message sent to {channel}:{chat_id}"
        except Exception as e:
            return f"Error sending message: {str(e)}"
