"""Slack API tools."""

from pydantic_ai import RunContext
from pydantic_ai.toolsets import FunctionToolset

from pydanticai_multiagent.dependencies import BaseDeps

slack_toolset: FunctionToolset[BaseDeps] = FunctionToolset()


@slack_toolset.tool
async def send_message(
    ctx: RunContext[BaseDeps],
    channel: str,
    message: str,
) -> str:
    """Send a message to a Slack channel.

    Args:
        ctx: The run context with dependencies.
        channel: Channel name or ID (e.g., '#general' or 'C1234567890').
        message: The message text to send.
    """
    # In production, use actual Slack API
    response = await ctx.deps.http_client.post(
        "https://slack.com/api/chat.postMessage",
        json={
            "channel": channel,
            "text": message,
        },
    )
    data = response.json()

    if data.get("ok"):
        return f"Message sent to {channel} successfully."
    else:
        return f"Failed to send message: {data.get('error', 'Unknown error')}"


@slack_toolset.tool
async def get_channel_history(
    ctx: RunContext[BaseDeps],
    channel: str,
    limit: int = 10,
) -> str:
    """Get recent messages from a Slack channel.

    Args:
        ctx: The run context with dependencies.
        channel: Channel ID (e.g., 'C1234567890').
        limit: Number of messages to retrieve.
    """
    response = await ctx.deps.http_client.get(
        "https://slack.com/api/conversations.history",
        params={
            "channel": channel,
            "limit": limit,
        },
    )
    data = response.json()

    if not data.get("ok"):
        return f"Failed to get history: {data.get('error', 'Unknown error')}"

    messages = data.get("messages", [])
    if not messages:
        return "No messages found in channel."

    formatted = []
    for msg in messages:
        user = msg.get("user", "Unknown")
        text = msg.get("text", "")[:200]
        formatted.append(f"[{user}]: {text}")

    return "\n".join(formatted)


@slack_toolset.tool
async def search_messages(
    ctx: RunContext[BaseDeps],
    query: str,
    limit: int = 10,
) -> str:
    """Search for messages across Slack.

    Args:
        ctx: The run context with dependencies.
        query: Search query string.
        limit: Maximum number of results.
    """
    response = await ctx.deps.http_client.get(
        "https://slack.com/api/search.messages",
        params={
            "query": query,
            "count": limit,
        },
    )
    data = response.json()

    if not data.get("ok"):
        return f"Search failed: {data.get('error', 'Unknown error')}"

    matches = data.get("messages", {}).get("matches", [])
    if not matches:
        return f"No messages found matching: {query}"

    formatted = []
    for match in matches:
        channel = match.get("channel", {}).get("name", "unknown")
        user = match.get("username", "Unknown")
        text = match.get("text", "")[:150]
        formatted.append(f"[#{channel}] {user}: {text}")

    return "\n\n".join(formatted)


@slack_toolset.tool
async def list_channels(
    ctx: RunContext[BaseDeps],
    limit: int = 20,
) -> str:
    """List available Slack channels.

    Args:
        ctx: The run context with dependencies.
        limit: Maximum number of channels to list.
    """
    response = await ctx.deps.http_client.get(
        "https://slack.com/api/conversations.list",
        params={
            "limit": limit,
            "types": "public_channel,private_channel",
        },
    )
    data = response.json()

    if not data.get("ok"):
        return f"Failed to list channels: {data.get('error', 'Unknown error')}"

    channels = data.get("channels", [])
    if not channels:
        return "No channels found."

    formatted = []
    for ch in channels:
        name = ch.get("name", "unknown")
        purpose = ch.get("purpose", {}).get("value", "No description")[:50]
        members = ch.get("num_members", 0)
        formatted.append(f"#{name} ({members} members) - {purpose}")

    return "\n".join(formatted)
