"""
Marziel AI — Web Search

Provides DuckDuckGo-based web search for augmenting LLM responses
with current information. Uses DuckDuckGo's HTML endpoint (no API key needed).
"""

import json
import logging
import urllib.request
import urllib.parse
from html import unescape
import re

logger = logging.getLogger("marziel.search")

# ── Keywords that indicate the user wants current/live info ──
_CURRENT_INFO_KEYWORDS = {
    # Temporal cues
    "current", "latest", "today", "now", "recent", "2024", "2025", "2026",
    "this week", "this month", "this year", "right now", "breaking",
    "happening", "ongoing", "live", "update", "news",
    # Questions about state of affairs
    "what is the situation", "what's happening", "what is going on",
    "how is", "status of", "state of",
    # Prices, weather, sports, politics
    "price of", "weather", "stock", "score", "election",
    "president of", "prime minister", "who won", "who is the",
    "inflation", "exchange rate", "gdp",
    # Tech
    "latest version", "release date", "new features",
}


def needs_web_search(message: str) -> bool:
    """Determine if a message likely needs current information from the web."""
    lower = message.lower().strip()
    for keyword in _CURRENT_INFO_KEYWORDS:
        if keyword in lower:
            return True
    # Questions about specific countries/regions often need current data
    if any(q in lower for q in ["what is the", "what's the", "how is the"]):
        return True
    return False


def search_duckduckgo(query: str, max_results: int = 5) -> list[dict]:
    """
    Search DuckDuckGo and return results.

    Returns:
        List of dicts with 'title', 'url', 'snippet' keys.
    """
    try:
        # Use DuckDuckGo HTML search
        encoded = urllib.parse.quote_plus(query)
        url = f"https://html.duckduckgo.com/html/?q={encoded}"
        req = urllib.request.Request(url, headers={
            "User-Agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36",
        })
        resp = urllib.request.urlopen(req, timeout=10)
        html = resp.read().decode("utf-8", errors="ignore")

        results = []
        # Parse result blocks from DuckDuckGo HTML
        blocks = re.findall(
            r'<a[^>]*class="result__a"[^>]*href="([^"]*)"[^>]*>(.*?)</a>.*?'
            r'<a[^>]*class="result__snippet"[^>]*>(.*?)</a>',
            html, re.DOTALL
        )

        for href, title, snippet in blocks[:max_results]:
            # Clean up DuckDuckGo redirect URLs
            if "uddg=" in href:
                actual = urllib.parse.unquote(href.split("uddg=")[1].split("&")[0])
            else:
                actual = href

            clean_title = re.sub(r"<[^>]+>", "", unescape(title)).strip()
            clean_snippet = re.sub(r"<[^>]+>", "", unescape(snippet)).strip()

            if clean_title and clean_snippet:
                results.append({
                    "title": clean_title,
                    "url": actual,
                    "snippet": clean_snippet,
                })

        logger.info(f"🔍 DuckDuckGo: {len(results)} results for '{query}'")
        return results

    except Exception as e:
        logger.error(f"Web search failed: {e}")
        return []


def format_search_context(results: list[dict]) -> str:
    """Format search results as context for the LLM system prompt."""
    if not results:
        return ""

    lines = ["Here are current web search results to help answer the question:\n"]
    for i, r in enumerate(results, 1):
        lines.append(f"{i}. **{r['title']}**")
        lines.append(f"   {r['snippet']}")
        lines.append(f"   Source: {r['url']}\n")

    lines.append(
        "Use the above search results to provide an accurate, up-to-date answer. "
        "Cite sources when relevant. If the search results are insufficient, "
        "say so honestly rather than guessing."
    )
    return "\n".join(lines)
