"""MCP tool registrations for Discord bot configuration."""

from mcp.server.fastmcp import Context


def register_tools(mcp, api_fn):
    @mcp.tool()
    async def create_discord_config(
        project_id: str,
        bot_token: str,
        guild_id: str = "",
        enabled: bool = True,
        dm_policy: str = "disabled",
        guild_policy: str = "open",
        require_mention: bool = False,
        history_limit: int = 10,
        ctx: Context = None,
    ) -> dict | str:
        """Register a Discord bot configuration for a project.

        Creates a new Discord bot config so the agent can send messages to
        Discord channels or receive commands from guild members.

        Args:
            project_id: The project this Discord bot belongs to.
            bot_token: Discord bot token (stored securely; masked in API responses).
            guild_id: Discord server (guild) snowflake ID. Leave empty for DM-only bots.
            enabled: Whether the bot is active. Defaults to True.
            dm_policy: DM access policy — 'open', 'pairing', or 'disabled'.
            guild_policy: Guild message policy — 'open', 'allowlist', or 'disabled'.
            require_mention: If True, the bot only responds when @mentioned.
            history_limit: Number of previous messages to include as context (default 10).
        """
        return await api_fn(ctx).create_discord_config(
            project_id=project_id,
            bot_token=bot_token,
            guild_id=guild_id,
            enabled=enabled,
            dm_policy=dm_policy,
            guild_policy=guild_policy,
            require_mention=require_mention,
            history_limit=history_limit,
        )

    @mcp.tool()
    async def list_discord_configs(
        project_id: str | None = None,
        ctx: Context = None,
    ) -> list[dict] | str:
        """List Discord bot configurations, optionally filtered by project.

        Args:
            project_id: Filter to configs for a specific project (optional).
        """
        return await api_fn(ctx).list_discord_configs(project_id=project_id)

    @mcp.tool()
    async def update_discord_config(
        config_id: int,
        bot_token: str | None = None,
        guild_id: str | None = None,
        enabled: bool | None = None,
        dm_policy: str | None = None,
        guild_policy: str | None = None,
        require_mention: bool | None = None,
        history_limit: int | None = None,
        ctx: Context = None,
    ) -> dict | str:
        """Update an existing Discord bot configuration.

        Args:
            config_id: The numeric ID of the Discord config to update.
            bot_token: New bot token (optional).
            guild_id: New guild ID (optional).
            enabled: Enable or disable the bot (optional).
            dm_policy: New DM policy — 'open', 'pairing', or 'disabled' (optional).
            guild_policy: New guild policy — 'open', 'allowlist', or 'disabled' (optional).
            require_mention: Whether to require @mention (optional).
            history_limit: New history limit (optional).
        """
        kwargs = {}
        if bot_token is not None:
            kwargs["bot_token"] = bot_token
        if guild_id is not None:
            kwargs["guild_id"] = guild_id
        if enabled is not None:
            kwargs["enabled"] = enabled
        if dm_policy is not None:
            kwargs["dm_policy"] = dm_policy
        if guild_policy is not None:
            kwargs["guild_policy"] = guild_policy
        if require_mention is not None:
            kwargs["require_mention"] = require_mention
        if history_limit is not None:
            kwargs["history_limit"] = history_limit
        return await api_fn(ctx).update_discord_config(config_id, **kwargs)

    @mcp.tool()
    async def delete_discord_config(
        config_id: int,
        ctx: Context = None,
    ) -> dict | str:
        """Delete a Discord bot configuration and all its channel mappings.

        Args:
            config_id: The numeric ID of the Discord config to delete.
        """
        return await api_fn(ctx).delete_discord_config(config_id)

    @mcp.tool()
    async def list_discord_channels(
        config_id: int,
        ctx: Context = None,
    ) -> list[dict] | str:
        """List channel mappings for a Discord bot configuration.

        Args:
            config_id: The numeric ID of the Discord config.
        """
        return await api_fn(ctx).list_discord_channels(config_id)

    @mcp.tool()
    async def send_discord_message(
        config_id: int,
        channel_id: str,
        content: str = "",
        embed_title: str = "",
        embed_description: str = "",
        ctx: Context = None,
    ) -> dict | str:
        """Send a message to a Discord channel via the configured bot.

        Requires the Discord bot gateway to be running for the given config.
        The agent can call this during task execution to post status updates,
        results, or alerts to a Discord channel.

        Args:
            config_id: The Discord bot configuration to use.
            channel_id: Target Discord channel snowflake ID.
            content: Plain-text message content.
            embed_title: Optional embed title for rich formatting.
            embed_description: Optional embed description.
        """
        return await api_fn(ctx).send_discord_message_to_channel(
            config_id=config_id,
            channel_id=channel_id,
            content=content,
            embed_title=embed_title,
            embed_description=embed_description,
        )

    @mcp.tool()
    async def list_pending_discord_messages(
        project_id: str | None = None,
        limit: int = 50,
        ctx: Context = None,
    ) -> list[dict] | str:
        """List unprocessed inbound Discord messages queued for agent processing.

        Args:
            project_id: Filter to messages for a specific project (optional).
            limit: Maximum number of messages to return (default 50).
        """
        return await api_fn(ctx).list_pending_discord_messages(
            project_id=project_id, limit=limit
        )

    @mcp.tool()
    async def mark_discord_message_processed(
        message_id: int,
        ctx: Context = None,
    ) -> dict | str:
        """Mark an inbound Discord message as processed.

        Call this after the agent has consumed and responded to the message.

        Args:
            message_id: The numeric DB ID of the discord_messages record.
        """
        return await api_fn(ctx).mark_discord_message_processed(message_id)

    @mcp.tool()
    async def list_discord_activity(
        config_id: int,
        event_type: str | None = None,
        limit: int = 50,
        ctx: Context = None,
    ) -> list[dict] | str:
        """List activity logs for a Discord bot configuration.

        Returns a chronological audit trail of Discord bot events such as
        connections, messages received/sent, AI responses, and access denials.

        Args:
            config_id: The Discord bot configuration to query.
            event_type: Filter to a specific event type (optional).
                Valid types: bot_connected, bot_disconnected, message_received,
                message_denied, message_sent, ai_response, command_invoked.
            limit: Maximum number of log entries to return (default 50).
        """
        return await api_fn(ctx).list_discord_activity(
            config_id=config_id, event_type=event_type, limit=limit
        )
