from __future__ import annotations

from pathlib import Path
from typing import TYPE_CHECKING

from niannian.brain.cerebellum.wiki_compiler import WikiCompiler
from niannian.brain.cerebellum.wiki_search import WikiSearch
from niannian.brain.cerebellum.wiki_store import WikiStore
from niannian.personas import CEREBELLUM
from niannian.schemas.models import Atom, WikiHit

if TYPE_CHECKING:
    from niannian.storage.base import MemoryStore


class CerebellumWiki:
    """小织 — Wiki 式发散检索；从原子编译概念页，不负责 raw 写入。"""

    def __init__(self, data_dir: Path, *, store: MemoryStore | None = None) -> None:
        self._data_dir = data_dir
        self._data_dir.mkdir(parents=True, exist_ok=True)
        if store is None:
            from niannian.storage.local import LocalMemoryStore

            self._store: MemoryStore = LocalMemoryStore(data_dir.parent)
        else:
            self._store = store
        self._wiki = WikiStore(self._store)
        self._compiler = WikiCompiler(self._store)

    @property
    def store(self) -> MemoryStore:
        return self._store

    @property
    def wiki_store(self) -> WikiStore:
        return self._wiki

    def _load(self) -> dict:
        return self._wiki.pages_map()

    def compile_from_atoms(self, atoms: list[Atom]) -> list[str]:
        """增量：按 tag 聚合成概念页（v2 + graph）。"""
        result = self._compiler.compile_atoms(atoms)
        return list(result.get("touched_page_ids") or [])

    def recall(
        self,
        query: str,
        *,
        project: str | None = None,
        limit: int = 5,
        namespace: str = "subject",
        object_id: str | None = None,
    ) -> list[WikiHit]:
        hits = WikiSearch(self._store).search(
            query,
            namespace=namespace,
            object_id=object_id,
            limit=limit,
        )
        return [
            WikiHit(
                concept=h.title,
                summary=h.summary,
                links=h.links,
                atom_ids=h.atom_ids,
                score=h.score,
                page_id=h.page_id,
                source=h.source,
            )
            for h in hits
        ]

    @staticmethod
    def trace_line(msg: str) -> str:
        return f"[{CEREBELLUM}] {msg}"
