"""Builds system prompt and session prompt for Claude Code sessions.

Uses mercury_get_agent_context to fetch agent identity, then constructs
prompts that mirror Mercury's generate_agent_prompt() structure.
"""

from typing import Any, Dict, List

from mercury_launcher.log import get_logger

logger = get_logger("context_builder")


def build_system_prompt(context: Dict[str, Any]) -> str:
    """Build the system prompt appendix from agent context.

    This is appended to Claude Code's default system prompt via
    ClaudeAgentOptions.system_prompt.
    """
    name = context.get("name", "Agent")
    role = context.get("agent_role", "")
    custom_prompt = context.get("system_prompt", "")
    connected = context.get("connected_agents", [])
    tasks = context.get("open_tasks", [])
    toolkits = context.get("composio_toolkits", [])

    parts = []

    # Identity
    parts.append(f"You are {name}, a {role}." if role else f"You are {name}.")
    if custom_prompt:
        parts.append(custom_prompt)

    # Mercury communication protocol
    parts.append(_MERCURY_PROTOCOL)

    # Connected agents
    if connected:
        lines = ["People you are connected to:"]
        for agent in connected:
            peer_name = agent.get("name", "Unknown")
            peer_role = agent.get("agent_role", "")
            peer_type = agent.get("type", "agent")
            type_label = " [human]" if peer_type == "human" else ""
            line = f"  - {peer_name}"
            if peer_role:
                line += f" ({peer_role})"
            line += type_label
            edge_desc = agent.get("edge_description", "")
            if edge_desc:
                line += f" — {edge_desc}"
            lines.append(line)
        lines.append(
            "To contact any of these people, use the mercury_send_message tool."
        )
        parts.append("\n".join(lines))

    # Composio toolkits
    if toolkits:
        toolkit_names = ", ".join(toolkits)
        parts.append(
            f"You have access to these Composio toolkits: {toolkit_names}. "
            "Use the COMPOSIO_SEARCH_TOOLS MCP tool to find and execute actions from these toolkits."
        )

    # Open tasks
    if tasks:
        lines = ["Your open tasks:"]
        for task in tasks:
            task_name = task.get("name", "Untitled")
            task_status = task.get("status", "open")
            lines.append(f"  - {task_name} [{task_status}]")
        parts.append("\n".join(lines))

    return "\n\n".join(parts)


def build_session_prompt(messages: List[Dict[str, Any]]) -> str:
    """Build the session prompt from incoming messages.

    This becomes the initial user message that triggers Claude Code to act.
    """
    if not messages:
        return "You have no new messages. Check for open tasks or wait for messages."

    parts = ["You have new messages on Mercury. Process each and respond.\n"]

    # Group messages by thread
    by_thread: Dict[str, list] = {}
    for msg in messages:
        tid = msg.get("thread_id", "unknown")
        by_thread.setdefault(tid, []).append(msg)

    for thread_id, thread_msgs in by_thread.items():
        parts.append(f"--- Thread {thread_id} ---")
        for msg in thread_msgs:
            sender = msg.get("sender_name", "Unknown")
            content = msg.get("content", "")
            parts.append(f"[{sender}]: {content}")
        parts.append("")

    parts.append(
        "Reply to each message using the mercury_send_message tool. "
        "Include the thread_id when replying to keep the conversation on the same thread."
    )

    return "\n".join(parts)


# Condensed Mercury protocol for Claude Code sessions.
# Much shorter than the full MERCURY_SYSTEM_PROMPT since Claude Code
# already has strong agentic behavior — we just need Mercury-specific rules.
_MERCURY_PROTOCOL = """\
MERCURY COMMUNICATION:
- You communicate with other agents and humans via Mercury, an agent orchestration platform.
- Use mercury_send_message to send messages. Always include thread_id to reply on existing threads.
- Use mercury_wait_for_messages to check for new messages after replying.
- Use mercury_list_agents to see who you're connected to.
- Be concise and actionable. Do the work, send the result, stop.
- Never claim you did something without actually using a tool to do it.
- If you need information from another agent, message them and wait for their reply.

CONVERSATION HISTORY:
- You only see NEW messages in your initial prompt — not the full conversation.
- BEFORE responding to a message, call mercury_read_thread with the thread_id to see prior messages on that thread. This gives you the context you need to respond properly.
- Use mercury_list_threads to see all your active conversations across all connections.
- If a message references something you don't have context for, read the thread first."""
