import os
import slack_sdk

from blocks_control_sdk.activity_providers.base import AgentActivityProvider
from blocks_control_sdk.blocks_events.context import BLOCKS_EVENT__PROVIDER, BLOCKS_EVENT__SLACK__TYPE
from blocks_control_sdk.control.agent_base import LLM, NotifyMessageArgs, NotifyCompleteArgs, NotifyToolCallArgs
from blocks_control_sdk.tools.blocks import get_task_header, to_slack_blocks_with_dashboard_button
from blocks_control_sdk.tools.slack import send_message__slack_with_header, update_message__slack
from blocks_control_sdk.utils import patch_blocks_runtime_config


class SlackActivityProvider(AgentActivityProvider):
    def setup(self, input: dict, llm_provider: LLM) -> None:
        super().setup(input, llm_provider)
        event = input.get("event", {})
        channel = event.get("channel", "")
        ts = event.get("ts", "")

        SLACK_TOKEN = os.getenv("SLACK_TOKEN")

        client = slack_sdk.WebClient(token=SLACK_TOKEN)
        initial_slack_comment_ts = input.get("$blocks.provider.comment_id")

        message_header = to_slack_blocks_with_dashboard_button(get_task_header())
        blocks_comment = None
        if initial_slack_comment_ts:
            blocks_comment = client.chat_update(
                channel=channel,
                blocks=message_header,
                thread_ts=ts,
                ts=initial_slack_comment_ts,
                unfurl_links=False,
                unfurl_media=False
            )
        else:
            blocks_comment = client.chat_postMessage(
                channel=channel,
                blocks=message_header,
                thread_ts=ts,
                unfurl_links=False,
                unfurl_media=False
            )

        blocks_comment_ts = blocks_comment.get("ts")

        patch_blocks_runtime_config({
            "event_provider": BLOCKS_EVENT__PROVIDER.SLACK.value,
            "event_type": BLOCKS_EVENT__SLACK__TYPE.MENTION.value,
            "llm_provider": llm_provider.value,
            "metadata": {
                "slack_channel": channel,
                "slack_ts": ts,
                "blocks_comment_ts": blocks_comment_ts
            }
        })

    def on_message(self, notification: NotifyMessageArgs) -> None:
        summary = self._prepare_progress_summary(notification)
        if summary:
            send_message__slack_with_header(summary, urgency_level_between_zero_to_10=6)

    def on_complete(self, notification: NotifyCompleteArgs) -> None:
        message = notification.last_message
        if message:
            final_message_slack = to_slack_blocks_with_dashboard_button(message)
            update_message__slack(final_message_slack, include_user_message=True)

    def on_tool_call(self, notification: NotifyToolCallArgs) -> None:
        pass

    def check(self, messages: list) -> None:
        user_messages = self._get_user_messages(messages)
        if not user_messages:
            return

        event = self.input.get("event", {})
        channel = event.get("channel", "")
        ts = event.get("ts", "")

        SLACK_TOKEN = os.getenv("SLACK_TOKEN")
        client = slack_sdk.WebClient(token=SLACK_TOKEN)

        text_fallback = get_task_header()
        slack_blocks_message = to_slack_blocks_with_dashboard_button(text_fallback)
        slack_message_result = client.chat_postMessage(
            channel=channel,
            text=text_fallback,
            blocks=slack_blocks_message,
            thread_ts=ts,
            unfurl_links=False,
            unfurl_media=False
        )

        new_comment_ts = slack_message_result.get("ts")
        patch_blocks_runtime_config({"metadata": {"blocks_comment_ts": new_comment_ts}}, deep_patch=True)
