"""Coinbase AgentKit integration: Skytale channels as AgentKit actions.

Usage::

    from skytale_sdk.integrations import agentkit

    mgr = agentkit.create_manager(identity=b"my-agent")
    mgr.create("org/ns/chan")
    provider = agentkit.action_provider(mgr)
    # Add provider to your AgentKit agent
"""

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 action_provider(manager: SkytaleChannelManager):
    """Return a Coinbase AgentKit ``ActionProvider`` bound to *manager*.

    Requires ``coinbase-agentkit>=0.1.0``. Install with::

        pip install skytale-sdk[agentkit]

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

    Returns:
        A ``SkytaleActionProvider`` with six actions:
        ``skytale_send``, ``skytale_receive``, ``skytale_channels``,
        ``skytale_create_channel``, ``skytale_invite``, ``skytale_join``.
    """
    from coinbase_agentkit import ActionProvider, WalletProvider, create_action
    from coinbase_agentkit.network import Network
    from pydantic import BaseModel, Field

    class SendSchema(BaseModel):
        channel: str = Field(description="Channel name (org/namespace/service)")
        message: str = Field(description="Message text to send")

    class ReceiveSchema(BaseModel):
        channel: str = Field(description="Channel name")
        timeout: float = Field(default=5.0, description="Seconds to wait")

    class EmptySchema(BaseModel):
        pass

    class ChannelSchema(BaseModel):
        channel: str = Field(description="Channel name (org/namespace/service)")

    class InviteSchema(BaseModel):
        channel: str = Field(description="Channel name")
        max_uses: int = Field(default=1)
        ttl: int = Field(default=3600)

    class JoinSchema(BaseModel):
        channel: str = Field(description="Channel name")
        token: str = Field(description="Invite token (skt_inv_...)")

    class SkytaleActionProvider(ActionProvider[WalletProvider]):
        def __init__(self):
            super().__init__("skytale", [])

        @create_action(
            name="skytale_send",
            description="Send encrypted message to a Skytale channel",
            schema=SendSchema,
        )
        def send(self, args: SendSchema) -> str:
            manager.send(args.channel, args.message)
            return f"Message sent to {args.channel}"

        @create_action(
            name="skytale_receive",
            description="Receive encrypted messages from a Skytale channel",
            schema=ReceiveSchema,
        )
        def receive(self, args: ReceiveSchema) -> str:
            msgs = manager.receive(args.channel, timeout=args.timeout)
            if not msgs:
                return f"No new messages on {args.channel}"
            return "\n".join(f"[{args.channel}] {m}" for m in msgs)

        @create_action(
            name="skytale_channels",
            description="List active Skytale encrypted channels",
            schema=EmptySchema,
        )
        def channels(self, args: EmptySchema) -> str:
            ch = manager.list_channels()
            return ", ".join(ch) if ch else "No active channels"

        @create_action(
            name="skytale_create_channel",
            description="Create MLS-encrypted Skytale channel",
            schema=ChannelSchema,
        )
        def create_channel(self, args: ChannelSchema) -> str:
            manager.create(args.channel)
            return f"Channel {args.channel} created"

        @create_action(
            name="skytale_invite",
            description="Create invite token for Skytale channel",
            schema=InviteSchema,
        )
        def invite(self, args: InviteSchema) -> str:
            token = manager.invite(args.channel, max_uses=args.max_uses, ttl=args.ttl)
            return f"Invite token for {args.channel}: {token}"

        @create_action(
            name="skytale_join",
            description="Join Skytale channel with invite token",
            schema=JoinSchema,
        )
        def join(self, args: JoinSchema) -> str:
            manager.join_with_token(args.channel, args.token)
            return f"Joined channel {args.channel}"

        def supports_network(self, network: Network) -> bool:
            return True  # Skytale is network-agnostic

    return SkytaleActionProvider()
