"""Quick-capture endpoint for mobile/external clients.

POST /api/quick-capture — sends text through the main LLM tool-calling pipeline
and returns a single synchronous JSON response. No SSE, no conversation ID.
"""

import logging
from datetime import date

from quart import Blueprint, jsonify, request

from fabledassistant.auth import get_current_user_id, login_required
from fabledassistant.config import Config
from fabledassistant.services.llm import stream_chat_with_tools
from fabledassistant.services.tools import execute_tool, get_tools_for_user

logger = logging.getLogger(__name__)

quick_capture_bp = Blueprint("quick_capture", __name__, url_prefix="/api/quick-capture")

# Tools offered to the quick-capture endpoint. Excludes destructive ops,
# read-only queries, and conversational-only tools.
_CAPTURE_TOOL_NAMES = {"create_note", "create_event", "update_note", "research_topic"}

_SYSTEM_PROMPT = """\
Today is {today}. You are a quick-capture assistant. The user has sent a short \
snippet from their mobile device. Create the appropriate item — note, task, or \
calendar event — using the available tools. Always call a tool; never reply \
conversationally."""


@quick_capture_bp.route("", methods=["POST"])
@login_required
async def quick_capture_route():
    """Classify text via native tool-calling and create the appropriate item."""
    uid = get_current_user_id()
    data = await request.get_json(silent=True) or {}
    text = data.get("text", "").strip()
    if not text:
        return jsonify({"error": "text is required"}), 400

    from fabledassistant.services.settings import get_setting
    model = await get_setting(uid, "default_model", Config.OLLAMA_MODEL)

    all_tools = await get_tools_for_user(uid)
    capture_tools = [
        t for t in all_tools if t.get("function", {}).get("name") in _CAPTURE_TOOL_NAMES
    ]

    messages = [
        {"role": "system", "content": _SYSTEM_PROMPT.format(today=date.today().isoformat())},
        {"role": "user", "content": text},
    ]

    # Quick capture is a fast classification path — never think.
    tool_calls: list[dict] = []
    try:
        async for chunk in stream_chat_with_tools(messages, model, tools=capture_tools, think=False, num_ctx=4096):
            if chunk.type == "tool_calls" and chunk.tool_calls:
                tool_calls = chunk.tool_calls
    except Exception:
        logger.warning("Quick-capture LLM call failed for uid=%d", uid, exc_info=True)

    if tool_calls:
        tc = tool_calls[0]
        tool_name = tc.get("function", {}).get("name", "")
        arguments = tc.get("function", {}).get("arguments", {})

        if tool_name == "research_topic" and Config.searxng_enabled():
            from fabledassistant.services.research import run_research_pipeline
            topic = arguments.get("topic", text)
            try:
                note = await run_research_pipeline(topic, uid, model)
                logger.info("Quick-capture uid=%d: research note id=%d '%s'", uid, note.id, note.title)
                return jsonify({
                    "success": True,
                    "type": "note",
                    "message": f"Research note created: {note.title}",
                    "data": {"id": note.id, "title": note.title},
                })
            except Exception as exc:
                logger.exception("Quick-capture research failed: %s", topic)
                return jsonify({"error": f"Research failed: {exc}"}), 500

        result = await execute_tool(uid, tool_name, arguments)
        if result.get("success"):
            item_type = result.get("type", "note")
            title = (result.get("data") or {}).get("title", "")
            logger.info("Quick-capture uid=%d: %s '%s'", uid, item_type, title)
            return jsonify({
                "success": True,
                "type": item_type,
                "message": f"{item_type.capitalize()}: {title}",
                "data": result.get("data"),
            })
        logger.warning("Quick-capture uid=%d: tool '%s' failed: %s", uid, tool_name, result.get("error"))

    # Fallback: create a plain note with the raw text
    result = await execute_tool(uid, "create_note", {"title": text[:80], "body": text})
    if result.get("success"):
        title = (result.get("data") or {}).get("title", "")
        logger.info("Quick-capture uid=%d: fallback note '%s'", uid, title)
        return jsonify({
            "success": True,
            "type": "note",
            "message": f"Note created: {title}",
            "data": result.get("data"),
            "fallback": True,
        })

    return jsonify({"error": "Failed to create item"}), 500
