"""
Phase 91: The Brainiac Knowledge Engine
Provides the tools for Crawler Agents and Librarian Agents to scrape the web and embed into ChromaDB.
"""
import os
import json
import hashlib
from pathlib import Path
from typing import List, Dict, Any

try:
    import chromadb
    import requests
    from bs4 import BeautifulSoup
    HAS_DEPS = True
except ImportError:
    HAS_DEPS = False

class BrainiacEngine:
    def __init__(self, db_path: str = "state/broker/brainiac_chroma"):
        self.db_path = Path(db_path)
        self.db_path.mkdir(parents=True, exist_ok=True)
        if HAS_DEPS:
            self.client = chromadb.PersistentClient(path=str(self.db_path))
            self.collection = self.client.get_or_create_collection(name="brynq_knowledge_graph")

    def fetch_url(self, url: str) -> str:
        """Scrape raw text from a URL."""
        if not HAS_DEPS: return "Error: requests and beautifulsoup4 required."
        try:
            response = requests.get(url, timeout=15)
            response.raise_for_status()
            soup = BeautifulSoup(response.text, "html.parser")
            # Strip script and style elements
            for script in soup(["script", "style", "nav", "footer"]):
                script.extract()
            text = soup.get_text(separator="\n")
            lines = (line.strip() for line in text.splitlines())
            chunks = (phrase.strip() for line in lines for phrase in line.split("  "))
            return "\n".join(chunk for chunk in chunks if chunk)
        except Exception as e:
            return f"Error fetching {url}: {str(e)}"

    def embed_knowledge(self, content: str, source: str, metadata: dict = None) -> str:
        """Embed synthesized knowledge into ChromaDB."""
        if not HAS_DEPS: return "Error: chromadb required."
        if metadata is None: metadata = {}
        metadata["source"] = source
        
        doc_id = hashlib.md5(content.encode()).hexdigest()
        
        try:
            self.collection.add(
                documents=[content],
                metadatas=[metadata],
                ids=[doc_id]
            )
            return f"Knowledge embedded successfully. ID: {doc_id}"
        except Exception as e:
            return f"Error embedding knowledge: {str(e)}"

    def semantic_search(self, query: str, n_results: int = 3) -> List[Dict[str, Any]]:
        """Search the Brainiac knowledge graph for answers."""
        if not HAS_DEPS: return [{"error": "chromadb required."}]
        try:
            results = self.collection.query(
                query_texts=[query],
                n_results=n_results
            )
            
            output = []
            for i in range(len(results['documents'][0])):
                output.append({
                    "content": results['documents'][0][i],
                    "metadata": results['metadatas'][0][i] if results['metadatas'] else {},
                    "distance": results['distances'][0][i] if 'distances' in results else 0
                })
            return output
        except Exception as e:
            return [{"error": f"Search failed: {str(e)}"}]
