import asyncio
import traceback
from copy import deepcopy

from biblemateagent.stream import stream_output
from biblemateweb import get_translation, chapter2verses, DEFAULT_MESSAGES
from biblemateweb.mcp_tools.elements import TOOL_ELEMENTS
from biblemateweb.mcp_tools.tools import TOOLS
from biblemateweb.api.api import get_api_content
from biblemate.core.systems import get_system_tool_instruction


TOOL_INSTRUCTION_PROMPT = """Please transform the following suggestions into clear, precise, and actionable instructions."""
TOOL_INSTRUCTION_SUFFIX = """

# Remember

* Provide me with the instructions directly.
* Do not start your response, like, 'Here are the insturctions ...'
* Do not ask me if I want to execute the instruction."""

async def run_single_tool(
    selected_tool,
    suggestion,
    MESSAGES=None,
    language="eng",
    developer=False,
    cancel_event=None,
    **kwargs
):
    """
    Run a single tool using the provided suggestion and tool name.
    Extracts the workflow from agent.py for single tool execution.
    """
    if MESSAGES is None:
        MESSAGES = deepcopy(DEFAULT_MESSAGES)

    print(f"\n[Selected Tool: {selected_tool}]\n")

    # tool instruction
    print("\n--- Tool Instruction ---\n")
    selected_tool_description = TOOLS.get(selected_tool, "No description available.")
    tool_instruction_draft = TOOL_INSTRUCTION_PROMPT + "\n\n# Suggestions\n\n"+suggestion+f"\n\n# Tool Description of `{selected_tool}`\n\n"+selected_tool_description+TOOL_INSTRUCTION_SUFFIX
    system_tool_instruction = get_system_tool_instruction(selected_tool, selected_tool_description)
    
    user_request = await stream_output(MESSAGES, tool_instruction_draft, cancel_event, system=system_tool_instruction, **kwargs)
    
    if not user_request or user_request.strip() == "[NO_CONTENT]":
        print("\n[No tool instruction generated. Stopping.]\n")
        return None, None

    print("\n--- Agent Execution ---\n")
    answers = None
    try:
        if selected_tool == "get_direct_text_response":
            answers = await stream_output(MESSAGES, user_request, cancel_event, system="auto", **kwargs)
        else:
            element = TOOL_ELEMENTS.get(selected_tool)
            if isinstance(element, str):
                print(f"Loading {selected_tool}...")
                if not selected_tool == "search_the_whole_bible":
                    user_req = chapter2verses(user_request)
                else:
                    user_req = user_request
                api_query = f"{element}{user_req}"
                answers = await asyncio.to_thread(get_api_content, api_query, language)
                if answers:
                    print(answers)
                else:
                    answers = "[NO_CONTENT]"
                    print(answers)
            elif isinstance(element, dict):
                element_copy = element.copy()
                system = element_copy.pop("system") if "system" in element_copy else None
                answers = await stream_output(MESSAGES, user_request, cancel_event, system=system, **element_copy, **kwargs)
                
    except Exception as e:
        answers = f"[{get_translation('Error')}: {str(e)}]"
        print(f"\n{answers}\n")
        if developer:
            traceback.print_exc()

    return answers, user_request
