#!/usr/bin/env python3
"""
Example of using SearXNG search engine with Local Deep Research.

This demonstrates how to use SearXNG for web search in programmatic mode.
Note: Requires a running SearXNG instance.
"""

import os
from langchain_ollama import ChatOllama
from local_deep_research.search_system import AdvancedSearchSystem
from local_deep_research.web_search_engines.engines.search_engine_searxng import (
    SearXNGSearchEngine,
)

# Re-enable logging
from loguru import logger
import sys

logger.remove()
# diagnose=False: loguru defaults to True, which renders repr() of every
# local in every traceback frame on exception. Users copy this snippet
# into their own scripts, so leaving the default on would propagate the
# credential-in-traceback leak (#4185) wherever the snippet lands.
logger.add(
    sys.stderr,
    level="INFO",
    format="{time} {level} {message}",
    diagnose=False,
)
logger.enable("local_deep_research")


def main():
    """Demonstrate using SearXNG with Local Deep Research."""
    print("=== SearXNG Search Engine Example ===\n")

    # Check if SearXNG URL is configured
    searxng_url = os.getenv("SEARXNG_URL", "http://localhost:8080")
    print(f"Using SearXNG instance at: {searxng_url}")
    print(
        "(Set SEARXNG_URL environment variable to use a different instance)\n"
    )

    # 1. Create LLM
    print("1. Setting up Ollama LLM...")
    llm = ChatOllama(model="gemma3:12b", temperature=0.3)

    # 2. Configure settings
    settings = {
        "search.iterations": 2,
        "search.questions_per_iteration": 3,
        "search.strategy": "source-based",
        "rate_limiting.enabled": False,  # Disable rate limiting for demo
        # SearXNG specific settings
        "search_engines.searxng.base_url": searxng_url,
        "search_engines.searxng.timeout": 30,
        "search_engines.searxng.categories": ["general", "science"],
        "search_engines.searxng.engines": ["google", "duckduckgo", "bing"],
        "search_engines.searxng.language": "en",
        "search_engines.searxng.time_range": "",  # all time
        "search_engines.searxng.safesearch": 0,  # 0=off, 1=moderate, 2=strict
    }

    # 3. Create SearXNG search engine
    print("2. Initializing SearXNG search engine...")
    try:
        search_engine = SearXNGSearchEngine(settings_snapshot=settings)

        # Test the connection
        print("   Testing SearXNG connection...")
        test_results = search_engine.run("test query", research_context={})
        if test_results:
            print(
                f"   ✓ SearXNG is working! Got {len(test_results)} test results."
            )
        else:
            print("   ⚠ SearXNG returned no results for test query.")
    except Exception as e:
        print(f"\n⚠ Error connecting to SearXNG: {e}")
        print("\nPlease ensure SearXNG is running. You can start it with:")
        print("  docker run -p 8888:8080 searxng/searxng")
        print("\nFalling back to mock search engine for demonstration...")

        # Fallback to mock search engine
        class MockSearchEngine:
            def __init__(self, settings_snapshot=None):
                self.settings_snapshot = settings_snapshot or {}

            def run(self, query, research_context=None):
                return [
                    {
                        "title": f"Result for: {query}",
                        "link": "https://example.com/result",
                        "snippet": f"This is a mock result for the query: {query}. "
                        "In a real scenario, SearXNG would provide actual web search results.",
                        "full_content": "Full content would be fetched here...",
                        "rank": 1,
                    }
                ]

        search_engine = MockSearchEngine(settings)

    # 4. Create the search system
    print("3. Creating AdvancedSearchSystem...")
    # Pass programmatic_mode=True to disable database dependencies
    search_system = AdvancedSearchSystem(
        llm=llm,
        search=search_engine,
        settings_snapshot=settings,
        programmatic_mode=True,
    )

    # 5. Run research queries
    queries = [
        "What are the latest developments in quantum computing in 2024?",
        "How does CRISPR gene editing technology work?",
    ]

    for query in queries:
        print(f"\n{'=' * 60}")
        print(f"Research Query: {query}")
        print("=" * 60)

        try:
            result = search_system.analyze_topic(query)

            # Display results
            print("\n=== RESEARCH FINDINGS ===")
            if result.get("formatted_findings"):
                print(result["formatted_findings"])
            else:
                print(
                    "Summary:", result.get("current_knowledge", "No findings")
                )

            # Show metadata
            print("\n=== METADATA ===")
            print(f"• Iterations completed: {result.get('iterations', 0)}")
            print(f"• Total findings: {len(result.get('findings', []))}")

            # Show search sources from all_links_of_system or search_results in findings
            all_links = result.get("all_links_of_system", [])

            # Also check findings for search_results
            for finding in result.get("findings", []):
                if "search_results" in finding and finding["search_results"]:
                    all_links = finding["search_results"]
                    break

            if all_links:
                print(f"• Sources found: {len(all_links)}")
                for i, link in enumerate(
                    all_links[:5], 1
                ):  # Show first 5 sources
                    if isinstance(link, dict):
                        title = link.get("title", "No title")
                        url = link.get("link", "Unknown")
                        print(f"  [{i}] {title}")
                        print(f"      {url}")

            # Show generated questions
            if result.get("questions_by_iteration"):
                print("\n=== RESEARCH QUESTIONS ===")
                for iteration, questions in result[
                    "questions_by_iteration"
                ].items():
                    print(f"Iteration {iteration}:")
                    for q in questions[
                        :2
                    ]:  # Show first 2 questions per iteration
                        print(f"  • {q}")

        except Exception as e:
            logger.exception("Error during research")
            print(f"\n⚠ Error: {e}")

    print("\n✓ SearXNG integration example completed!")
    print(
        "\nNote: For best results, ensure SearXNG is properly configured with multiple search engines."
    )


if __name__ == "__main__":
    main()
