"""RAGMemory — injects relevant knowledge base context into agent conversations."""
from __future__ import annotations

from typing import Any

from logos_adk.memory import Memory, MemoryEntry
from logos_adk.rag.knowledge_base import KnowledgeBase
from logos_adk.state import AgentState
from logos_adk.types import Message, Response


class RAGMemory(Memory):
    """Memory strategy that retrieves context from a KnowledgeBase.

    Read-only: ``commit`` is a no-op because the knowledge base
    is populated via ``KnowledgeBase.ingest``, not from conversation turns.
    """

    def __init__(
        self,
        knowledge_base: KnowledgeBase,
        limit: int = 5,
        filter: dict[str, Any] | None = None,
        learning: Any | None = None,
    ) -> None:
        self.knowledge_base = knowledge_base
        self.limit = limit
        self.filter = filter
        self.learning = learning

    def _last_user_query(self, messages: list[Message]) -> str:
        for message in reversed(messages):
            if message.role == "user" and message.content:
                return message.content
        return ""

    async def remember(
        self,
        messages: list[Message],
        state: AgentState,
        session_id: str | None = None,
    ) -> list[MemoryEntry]:
        query = self._last_user_query(messages)
        if not query:
            return []

        chunks = await self.knowledge_base.search(
            query,
            limit=max(self.limit * 2, self.limit) if self.learning is not None else self.limit,
            filter=self.filter,
        )
        entries = [
            MemoryEntry(
                content=chunk.content,
                metadata={**chunk.metadata, "document_id": chunk.document_id},
            )
            for chunk in chunks
        ]
        if self.learning is None:
            return entries[: self.limit]
        lexical_scores = {entry.id: 1.0 for entry in entries}
        ranked_entries = self.learning.rerank_entries(entries, lexical_scores=lexical_scores)
        resolved_limit = self.learning.resolve_context_limit(ranked_entries, base_limit=self.limit)
        state.metadata["adk_rag_context_limit"] = resolved_limit
        return ranked_entries[:resolved_limit]

    async def commit(
        self,
        messages: list[Message],
        response: Response,
        state: AgentState,
        session_id: str | None = None,
    ) -> None:
        pass
