from blocks_control_sdk.activity_providers.base import AgentActivityProvider
from blocks_control_sdk.blocks_events.context import BLOCKS_EVENT__PROVIDER, BLOCKS_EVENT__LINEAR__TYPE
from blocks_control_sdk.control.agent_base import LLM, NotifyMessageArgs, NotifyCompleteArgs, NotifyToolCallArgs, NotifyInterruptArgs
from blocks_control_sdk.tools.blocks import get_task_header
from blocks_control_sdk.tools.linear import (
    create_agent_activity,
    create_linear_issue_comment,
    create_response_activity,
    update_linear_issue_comment,
    is_agent_session_active,
    update_message__linear,
    notify_linear_progress,
    notify_linear_tool_call,
)
from blocks_control_sdk.utils import patch_blocks_runtime_config


class LinearActivityProvider(AgentActivityProvider):
    def setup(self, input: dict, llm_provider: LLM) -> None:
        super().setup(input, llm_provider)
        issue = input.get("issue", {})
        issue_id = issue.get("id")
        issue_identifier = issue.get("identifier")

        parent_id = input.get("$blocks.trigger.subject_id") or input.get("new_comment", {}).get("parentId")
        initial_linear_comment_id = input.get("$blocks.provider.comment_id")

        agent_session_id = input.get("$blocks.linear.agent_session_id")
        use_agent_session = is_agent_session_active() or bool(agent_session_id)

        linear_comment_id = None

        if use_agent_session:
            print("Using Linear Agent Session pattern")
        else:
            issue_header = get_task_header()
            if initial_linear_comment_id:
                linear_comment_result = update_linear_issue_comment(initial_linear_comment_id, body=issue_header)
            else:
                linear_comment_result = create_linear_issue_comment(issue_id, body=issue_header, parent_id=parent_id)

            if linear_comment_result and linear_comment_result.get("comment"):
                linear_comment_id = linear_comment_result["comment"].get("id")

        patch_blocks_runtime_config({
            "event_provider": BLOCKS_EVENT__PROVIDER.LINEAR.value,
            "event_type": BLOCKS_EVENT__LINEAR__TYPE.ISSUE.value,
            "llm_provider": llm_provider.value,
            "metadata": {
                "comment_id": linear_comment_id,
                "issue_id": issue_id,
                "issue_identifier": issue_identifier,
                "agent_session_id": agent_session_id,
                "use_agent_session": use_agent_session
            }
        })

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

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

    def on_tool_call(self, notification: NotifyToolCallArgs) -> None:
        notify_linear_tool_call(notification.tool_name, notification.serialized_args)

    def on_interrupt(self, notification: NotifyInterruptArgs) -> None:
        try:
            if is_agent_session_active():
                print(f"Emitting stop response activity for Linear agent session")
                create_response_activity("Work has been stopped.")
        except Exception as e:
            print(f"Error emitting Linear stop response activity: {e}")

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

        if is_agent_session_active():
            create_agent_activity({"type": "thought", "body": "Processing your message..."})
            return

        issue = self.input.get("issue", {})
        issue_id = issue.get("id")

        if self.trigger_alias == "linear.assign":
            parent_id = self.input.get("$blocks.provider.comment_id")
        else:
            parent_id = self.input.get("$blocks.trigger.subject_id") or self.input.get("new_comment", {}).get("parentId")

        issue_header = get_task_header()
        linear_comment_result = create_linear_issue_comment(issue_id, body=issue_header, parent_id=parent_id)

        new_comment_id = None
        if linear_comment_result and linear_comment_result.get("comment"):
            new_comment_id = linear_comment_result["comment"].get("id")

        patch_blocks_runtime_config({"metadata": {"comment_id": new_comment_id}}, deep_patch=True)
