"""Web search, research, and image tools."""

from __future__ import annotations

import logging

from fabledassistant.services.tools._registry import tool

logger = logging.getLogger(__name__)


@tool(
    name="lookup",
    description=(
        "Look up a topic, concept, or factual question. Returns a concise answer from "
        "Wikipedia or web sources. Use for definitions, explanations, 'what is X', "
        "'how does Y work', current events, or version numbers. No note is saved. "
        "For comprehensive written reports saved as notes, use research_topic instead."
    ),
    parameters={
        "query": {"type": "string", "description": "The topic or question to look up"},
    },
    required=["query"],
)
async def lookup_tool(*, user_id, arguments, **_ctx):
    import asyncio

    from fabledassistant.config import Config
    from fabledassistant.services.wikipedia import wiki_summary

    query = arguments.get("query", "").strip()
    if not query:
        return {"success": False, "error": "query is required"}

    searxng_enabled = Config.searxng_enabled()

    async def _searxng_results() -> list[dict]:
        if not searxng_enabled:
            return []
        from fabledassistant.services.research import _search_searxng
        return await _search_searxng(query) or []

    wiki, search_results = await asyncio.gather(
        wiki_summary(query),
        _searxng_results(),
    )

    wiki_payload: dict | None = None
    if wiki:
        wiki_payload = {
            "title": wiki["title"],
            "extract": wiki["extract"],
            "url": wiki["url"],
        }
        thumb_url = wiki.get("thumbnail_url") or ""
        if thumb_url:
            from fabledassistant.services.images import fetch_and_store_image
            record = await fetch_and_store_image(
                url=thumb_url,
                title=wiki["title"],
                source_domain="en.wikipedia.org",
            )
            if record:
                wiki_payload["image"] = {
                    "embed": f"![{wiki['title']}](/api/images/{record.id})",
                    "citation": f"*Source: [Wikipedia]({wiki['url']})*",
                }

    web_payload: list[dict] = []
    if search_results:
        # Sequential fetches: trafilatura/lxml is not safe to run concurrently
        # via run_in_executor — parallel calls can trip a libxml2 double-free.
        from fabledassistant.services.article_fetcher import fetch_article_text

        for r in search_results[:2]:
            url = r.get("url", "")
            if not url:
                continue
            try:
                content = await fetch_article_text(url)
            except Exception:
                content = None
            web_payload.append({
                "url": url,
                "title": r.get("title", url),
                "snippet": r.get("snippet", ""),
                "content": (content or "")[:4000],
            })

    if not wiki_payload and not web_payload:
        return {
            "success": True,
            "type": "lookup",
            "data": {
                "query": query,
                "message": "No results found. You can answer from your own knowledge.",
            },
        }

    data: dict = {
        "query": query,
        "wikipedia": wiki_payload,
        "web": web_payload,
    }
    if wiki_payload and wiki_payload.get("image"):
        data["image_instructions"] = (
            "If an image is relevant to your reply, embed it by writing the wikipedia.image.embed "
            "field verbatim, then the citation field on the next line. Otherwise omit it."
        )
    return {
        "success": True,
        "type": "lookup",
        "data": data,
    }


@tool(
    name="research_topic",
    description=(
        "Deep web research — searches multiple sources, synthesizes findings, and saves the result "
        "as a structured note with sections and citations. Use when the user says 'research', "
        "'look into', or wants a comprehensive write-up. Takes 30–120 seconds. "
        "For a quick factual answer without saving a note, use lookup."
    ),
    parameters={
        "topic": {"type": "string", "description": "The topic or question to research"},
    },
    required=["topic"],
    requires="searxng",
)
async def research_topic_tool(*, user_id, arguments, **_ctx):
    # Research is always intercepted in generation_task.py (round 0) before execute_tool.
    # Reaching here indicates a code path regression.
    topic = arguments.get("topic", "")
    logger.error(
        "research_topic reached execute_tool — should have been intercepted upstream "
        "in generation_task.py. topic=%r",
        topic,
    )
    return {"success": False, "error": "Research could not be started. Please try again."}


@tool(
    name="search_images",
    description="Search and display images inline. Use ONLY when the user explicitly asks to see, show, or find an image or photo. Not for factual questions — use lookup for those.",
    parameters={
        "query": {"type": "string", "description": "The image search query"},
    },
    required=["query"],
    requires="searxng",
)
async def search_images_tool(*, user_id, arguments, **_ctx):
    from fabledassistant.services.images import fetch_and_store_image
    from fabledassistant.services.research import _search_searxng_images

    query = arguments.get("query", "")
    if not query:
        return {"success": False, "error": "query is required"}
    raw_results = await _search_searxng_images(query)
    if not raw_results:
        return {"success": False, "error": f"No images found for '{query}'"}
    images = []
    for r in raw_results[:2]:
        img_url = r.get("img_src", "")
        if not img_url:
            continue
        record = await fetch_and_store_image(
            url=img_url,
            title=r.get("title"),
            source_domain=r.get("source_domain"),
        )
        if record:
            title = record.title or query
            page_url = r.get("page_url", "")
            source_domain = r.get("source_domain", "")
            images.append({
                "embed": f"![{title}](/api/images/{record.id})",
                "citation": f"*Source: [{source_domain or 'image'}]({page_url})*",
                "page_url": page_url,
                "title": title,
            })
    if not images:
        return {"success": False, "error": f"Could not retrieve images for '{query}'"}
    return {
        "success": True,
        "type": "image_search",
        "data": {
            "query": query,
            "images": images,
            "instructions": (
                "Embed each image in your response by writing the 'embed' field verbatim, "
                "then the 'citation' field on the next line. Do not paraphrase or list URLs."
            ),
        },
    }
