"""API client methods for Discord bot configuration."""

from __future__ import annotations

from peon_mcp.common.base_client import BaseAPIClient


class DiscordClient(BaseAPIClient):
    """Discord bot configuration API client methods."""

    async def list_discord_configs(self) -> list[dict] | str:
        return await self._paginate_all("/api/discord/configs")

    async def create_discord_config(
        self,
        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,
    ) -> dict | str:
        return await self._request(
            "POST",
            "/api/discord/configs",
            json={
                "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,
            },
        )

    async def get_discord_config(self, config_id: int) -> dict | str:
        return await self._request("GET", f"/api/discord/configs/{config_id}")

    async def update_discord_config(
        self,
        config_id: int,
        **kwargs,
    ) -> dict | str:
        return await self._request(
            "PUT", f"/api/discord/configs/{config_id}", json=kwargs
        )

    async def delete_discord_config(self, config_id: int) -> dict | str:
        return await self._request("DELETE", f"/api/discord/configs/{config_id}")

    async def list_discord_channels(self, config_id: int) -> list[dict] | str:
        return await self._request(
            "GET", f"/api/discord/configs/{config_id}/channels"
        )

    async def create_channel_mapping(
        self,
        config_id: int,
        channel_id: str,
        channel_name: str = "",
        allowed_user_ids: list[str] | None = None,
        allowed_role_ids: list[str] | None = None,
        enabled: bool = True,
    ) -> dict | str:
        return await self._request(
            "POST",
            f"/api/discord/configs/{config_id}/channels",
            json={
                "channel_id": channel_id,
                "channel_name": channel_name,
                "allowed_user_ids": allowed_user_ids or [],
                "allowed_role_ids": allowed_role_ids or [],
                "enabled": enabled,
            },
        )

    async def update_channel_mapping(
        self,
        config_id: int,
        mapping_id: int,
        **kwargs,
    ) -> dict | str:
        return await self._request(
            "PUT",
            f"/api/discord/configs/{config_id}/channels/{mapping_id}",
            json=kwargs,
        )

    async def delete_channel_mapping(
        self, config_id: int, mapping_id: int
    ) -> dict | str:
        return await self._request(
            "DELETE",
            f"/api/discord/configs/{config_id}/channels/{mapping_id}",
        )

    async def send_discord_message_to_channel(
        self,
        config_id: int,
        channel_id: str,
        content: str = "",
        embed_title: str = "",
        embed_description: str = "",
    ) -> dict | str:
        return await self._request(
            "POST",
            f"/api/discord/configs/{config_id}/send",
            json={
                "channel_id": channel_id,
                "content": content,
                "embed_title": embed_title,
                "embed_description": embed_description,
            },
        )

    # ------------------------------------------------------------------
    # Inbound messages
    # ------------------------------------------------------------------

    async def receive_inbound_message(
        self,
        config_id: int,
        channel_id: str,
        user_id: str,
        content: str,
        username: str = "",
        message_id: str = "",
        replied_to: str = "",
    ) -> dict | str:
        return await self._request(
            "POST",
            "/api/discord/messages/inbound",
            json={
                "config_id": config_id,
                "channel_id": channel_id,
                "user_id": user_id,
                "username": username,
                "content": content,
                "message_id": message_id,
                "replied_to": replied_to,
            },
        )

    async def list_pending_discord_messages(
        self,
        project_id: str | None = None,
        limit: int = 50,
    ) -> list[dict] | str:
        params: dict = {"limit": limit}
        if project_id:
            params["project_id"] = project_id
        return await self._request("GET", "/api/discord/messages/pending", params=params)

    async def ack_discord_message(
        self,
        message_id: int,
        status: str = "processed",
    ) -> dict | str:
        return await self._request(
            "POST",
            f"/api/discord/messages/{message_id}/ack",
            params={"status": status},
        )

    async def mark_discord_message_processed(self, message_id: int) -> dict | str:
        return await self._request(
            "PUT", f"/api/discord/messages/{message_id}/processed"
        )

    # ------------------------------------------------------------------
    # Activity logs
    # ------------------------------------------------------------------

    async def log_discord_activity(
        self,
        config_id: int,
        event_type: str,
        channel_id: str = "",
        user_id: str = "",
        detail: str = "",
    ) -> dict | str:
        return await self._request(
            "POST",
            "/api/discord/activity",
            json={
                "config_id": config_id,
                "event_type": event_type,
                "channel_id": channel_id,
                "user_id": user_id,
                "detail": detail,
            },
        )

    async def list_discord_activity(
        self,
        config_id: int,
        event_type: str | None = None,
        limit: int = 50,
        offset: int = 0,
    ) -> list[dict] | str:
        params: dict = {"limit": limit, "offset": offset}
        if event_type:
            params["event_type"] = event_type
        return await self._paginate_all(
            f"/api/discord/configs/{config_id}/activity", params=params
        )

    # ------------------------------------------------------------------
    # Project-scoped channel mappings
    # ------------------------------------------------------------------

    async def list_project_channels(self, project_id: str) -> list[dict] | str:
        return await self._request(
            "GET", f"/api/projects/{project_id}/discord/channels"
        )

    async def create_project_channel_mapping(
        self,
        project_id: str,
        discord_config_id: int,
        channel_id: str,
        channel_name: str = "",
        allowed_user_ids: list[str] | None = None,
        allowed_role_ids: list[str] | None = None,
        subscribed_events: list[str] | None = None,
        enabled: bool = True,
    ) -> dict | str:
        return await self._request(
            "POST",
            f"/api/projects/{project_id}/discord/channels",
            json={
                "discord_config_id": discord_config_id,
                "channel_id": channel_id,
                "channel_name": channel_name,
                "allowed_user_ids": allowed_user_ids or [],
                "allowed_role_ids": allowed_role_ids or [],
                "subscribed_events": subscribed_events or [],
                "enabled": enabled,
            },
        )

    async def update_project_channel_mapping(
        self,
        project_id: str,
        mapping_id: int,
        **kwargs,
    ) -> dict | str:
        return await self._request(
            "PUT",
            f"/api/projects/{project_id}/discord/channels/{mapping_id}",
            json=kwargs,
        )

    async def delete_project_channel_mapping(
        self,
        project_id: str,
        mapping_id: int,
    ) -> dict | str:
        return await self._request(
            "DELETE",
            f"/api/projects/{project_id}/discord/channels/{mapping_id}",
        )
