"""KnowledgeStore — unified facade for the three-tier knowledge system."""

from __future__ import annotations

import logging
from pathlib import Path

from vastian.knowledge.documents import DocumentStore
from vastian.knowledge.structured import StructuredStore
from vastian.knowledge.vector import VectorStore

logger = logging.getLogger(__name__)


class KnowledgeStore:
    """
    Unified knowledge management facade.

    Combines:
    - VectorStore (ChromaDB) for semantic search
    - StructuredStore (FileStore + SQLite) for tasks, logs, relationships
    - DocumentStore (Markdown files) for agent-owned documents
    """

    def __init__(
        self,
        chroma_persist_dir: Path,
        sqlite_path: Path,
        docs_dir: Path,
        state_dir: Path | None = None,
    ) -> None:
        self.vector = VectorStore(persist_dir=chroma_persist_dir)
        self.structured = StructuredStore(db_path=sqlite_path, state_dir=state_dir)
        self.documents = DocumentStore(docs_dir=docs_dir)

    async def initialize(self) -> None:
        """Initialize all storage backends."""
        self.vector.initialize()
        await self.structured.initialize()
        self.documents.initialize()
        logger.info("Knowledge Store initialized")

    # ── Store & Search (Vector + Structured) ─────────

    async def store_entry(
        self,
        content: str,
        author: str,
        tags: list[str] | None = None,
        metadata: dict | None = None,
    ) -> str:
        """
        Store a knowledge entry in both vector and structured stores.

        Returns the entry ID.
        """
        entry_metadata = {
            "author": author,
            "tags": ",".join(tags or []),
            **(metadata or {}),
        }

        # Store in vector DB for semantic search
        entry_id = self.vector.add(content=content, metadata=entry_metadata)

        # Store in structured DB for relational queries
        await self.structured.insert_entry(
            entry_id=entry_id,
            content=content,
            author=author,
            tags=tags or [],
            metadata=metadata or {},
        )

        logger.debug("Stored knowledge entry %s by %s", entry_id, author)
        return entry_id

    async def search(
        self,
        query: str,
        top_k: int = 5,
        author: str | None = None,
        tags: list[str] | None = None,
    ) -> list[dict]:
        """Semantic search over knowledge entries with optional filters."""
        where_filter = {}
        if author:
            where_filter["author"] = author
        if tags:
            where_filter["tags"] = {"$contains": tags[0]}  # ChromaDB single filter

        results = self.vector.search(query=query, top_k=top_k, where=where_filter or None)
        return results

    async def get_by_tags(self, tags: list[str], limit: int = 50) -> list[dict]:
        """Retrieve entries matching any of the given tags from structured store."""
        return await self.structured.get_by_tags(tags=tags, limit=limit)

    # ── Document Management ──────────────────────────

    async def read_document(self, doc_path: str) -> str:
        """Read an agent-owned document."""
        return self.documents.read(doc_path)

    async def write_document(self, doc_path: str, content: str, author: str) -> None:
        """Write/update an agent-owned document."""
        self.documents.write(doc_path, content, author)

        # Also index the document content in the vector store
        self.vector.add(
            content=content[:2000],  # index a summary
            metadata={"author": author, "type": "document", "path": doc_path},
        )

    async def list_documents(self, agent_id: str | None = None) -> list[str]:
        """List all documents, optionally filtered by agent."""
        return self.documents.list_docs(agent_id)

    # ── Structured Queries ───────────────────────────

    async def log_event(
        self,
        event_type: str,
        agent_id: str,
        content: str,
        metadata: dict | None = None,
    ) -> None:
        """Log an event to the structured store (for audit trail)."""
        await self.structured.log_event(
            event_type=event_type,
            agent_id=agent_id,
            content=content,
            metadata=metadata or {},
        )

    async def get_events(
        self,
        agent_id: str | None = None,
        event_type: str | None = None,
        limit: int = 100,
    ) -> list[dict]:
        """Retrieve logged events with optional filters."""
        return await self.structured.get_events(
            agent_id=agent_id,
            event_type=event_type,
            limit=limit,
        )
