"""smolagents integration: expose Skytale channels as Hugging Face agent tools.

Usage::

    from skytale_sdk.integrations import _smolagents as skytale_sm

    mgr = skytale_sm.create_manager(identity=b"my-agent")
    mgr.create("org/ns/chan")
    agent = CodeAgent(tools=skytale_sm.tools(mgr), model=model)
"""

from __future__ import annotations

from skytale_sdk.channels import SkytaleChannelManager


def create_manager(**kwargs) -> SkytaleChannelManager:
    """Create a ``SkytaleChannelManager`` with the given options.

    Accepts the same keyword arguments as ``SkytaleChannelManager``.

    Returns:
        A configured channel manager.
    """
    return SkytaleChannelManager(**kwargs)


def tools(manager: SkytaleChannelManager) -> list:
    """Return smolagents ``Tool`` instances bound to *manager*.

    Requires ``smolagents>=1.0.0``. Install with::

        pip install skytale-sdk[smolagents]

    Args:
        manager: A ``SkytaleChannelManager`` managing the channels.

    Returns:
        List of six ``Tool`` subclass instances:
        ``SkytaleSendTool``, ``SkytaleReceiveTool``, ``SkytaleChannelsTool``,
        ``SkytaleCreateChannelTool``, ``SkytaleInviteTool``, ``SkytaleJoinTool``.
    """
    from smolagents import Tool

    class SkytaleSendTool(Tool):
        name = "skytale_send"
        description = (
            "Send an encrypted message to a Skytale channel. "
            "Messages are end-to-end encrypted using the MLS protocol."
        )
        inputs = {
            "channel": {
                "type": "string",
                "description": "Channel name in org/namespace/service format",
            },
            "message": {
                "type": "string",
                "description": "Message text to send",
            },
        }
        output_type = "string"

        def __init__(self):
            super().__init__()
            self._manager = manager

        def forward(self, channel: str, message: str) -> str:
            self._manager.send(channel, message)
            return f"Message sent to {channel}"

    class SkytaleReceiveTool(Tool):
        name = "skytale_receive"
        description = (
            "Receive encrypted messages from a Skytale channel. "
            "Returns all messages received since the last check."
        )
        inputs = {
            "channel": {
                "type": "string",
                "description": "Channel name in org/namespace/service format",
            },
            "timeout": {
                "type": "number",
                "description": "Seconds to wait for messages (default 5)",
                "nullable": True,
            },
        }
        output_type = "string"

        def __init__(self):
            super().__init__()
            self._manager = manager

        def forward(self, channel: str, timeout: float = 5.0) -> str:
            msgs = self._manager.receive(channel, timeout=timeout or 5.0)
            if not msgs:
                return f"No new messages on {channel}"
            return "\n".join(f"[{channel}] {m}" for m in msgs)

    class SkytaleChannelsTool(Tool):
        name = "skytale_channels"
        description = "List all active Skytale encrypted channels."
        inputs = {}
        output_type = "string"

        def __init__(self):
            super().__init__()
            self._manager = manager

        def forward(self) -> str:
            channels = self._manager.list_channels()
            if not channels:
                return "No active channels"
            return ", ".join(channels)

    class SkytaleCreateChannelTool(Tool):
        name = "skytale_create_channel"
        description = (
            "Create a new MLS-encrypted Skytale channel and start "
            "listening for messages."
        )
        inputs = {
            "channel": {
                "type": "string",
                "description": "Channel name in org/namespace/service format",
            },
        }
        output_type = "string"

        def __init__(self):
            super().__init__()
            self._manager = manager

        def forward(self, channel: str) -> str:
            self._manager.create(channel)
            return f"Channel {channel} created"

    class SkytaleInviteTool(Tool):
        name = "skytale_invite"
        description = (
            "Create an invite token for a Skytale channel. Share the "
            "token with another agent so they can join."
        )
        inputs = {
            "channel": {
                "type": "string",
                "description": "Channel name in org/namespace/service format",
            },
            "max_uses": {
                "type": "integer",
                "description": "How many times the token can be used (default 1)",
                "nullable": True,
            },
            "ttl": {
                "type": "integer",
                "description": "Token lifetime in seconds (default 3600)",
                "nullable": True,
            },
        }
        output_type = "string"

        def __init__(self):
            super().__init__()
            self._manager = manager

        def forward(self, channel: str, max_uses: int = 1, ttl: int = 3600) -> str:
            token = self._manager.invite(channel, max_uses=max_uses, ttl=ttl)
            return f"Invite token for {channel}: {token}"

    class SkytaleJoinTool(Tool):
        name = "skytale_join"
        description = (
            "Join a Skytale channel using an invite token. The MLS key "
            "exchange happens automatically."
        )
        inputs = {
            "channel": {
                "type": "string",
                "description": "Channel name in org/namespace/service format",
            },
            "token": {
                "type": "string",
                "description": "Invite token (skt_inv_...) from the channel owner",
            },
        }
        output_type = "string"

        def __init__(self):
            super().__init__()
            self._manager = manager

        def forward(self, channel: str, token: str) -> str:
            self._manager.join_with_token(channel, token)
            return f"Joined channel {channel}"

    return [
        SkytaleSendTool(),
        SkytaleReceiveTool(),
        SkytaleChannelsTool(),
        SkytaleCreateChannelTool(),
        SkytaleInviteTool(),
        SkytaleJoinTool(),
    ]
