"""Slack channel implementation using Bot API."""

from __future__ import annotations

import logging
from collections.abc import Callable

import httpx

from agntspace.channels.base import Channel, ChannelMessage

log = logging.getLogger(__name__)


class SlackChannel(Channel):
    """Slack bot channel using Events API + Web API."""

    name = "slack"

    def __init__(self, bot_token: str) -> None:
        self._token = bot_token
        self._base_url = "https://slack.com/api"
        self._connected = False
        self._message_callback: Callable | None = None
        self._chat_id: str | None = None

    async def connect(self) -> None:
        async with httpx.AsyncClient() as client:
            resp = await client.post(
                f"{self._base_url}/auth.test",
                headers={"Authorization": f"Bearer {self._token}"},
            )
            data = resp.json()
            if not data.get("ok"):
                raise ConnectionError(f"Slack bot token invalid: {data.get('error')}")
            log.info("Slack connected: %s (%s)", data.get("user"), data.get("team"))
        self._connected = True

    async def disconnect(self) -> None:
        self._connected = False
        log.info("Slack disconnected")

    async def send_message(self, chat_id: str, text: str) -> None:
        async with httpx.AsyncClient() as client:
            await client.post(
                f"{self._base_url}/chat.postMessage",
                headers={"Authorization": f"Bearer {self._token}"},
                json={"channel": chat_id, "text": text},
            )

    async def send_notification(self, chat_id: str, text: str) -> None:
        await self.send_message(chat_id, f":bell: {text}")

    @property
    def is_connected(self) -> bool:
        return self._connected

    async def handle_event(self, payload: dict) -> str | None:
        """Process a Slack Events API payload."""
        # URL verification challenge
        if payload.get("type") == "url_verification":
            return payload.get("challenge", "")

        event = payload.get("event", {})
        if event.get("type") != "message":
            return None

        # Ignore bot messages
        if event.get("bot_id") or event.get("subtype"):
            return None

        text = event.get("text", "")
        channel_id = event.get("channel", "")
        user = event.get("user", "User")

        if not text or not channel_id:
            return None

        self._chat_id = channel_id

        msg = ChannelMessage(
            channel="slack",
            sender=user,
            text=text,
            metadata={"chat_id": channel_id},
        )

        if self._message_callback:
            response = await self._message_callback(msg)
            if response:
                await self.send_message(channel_id, response)
            return response

        return None
