"""Long-term memory tools."""

from __future__ import annotations

from dataclasses import dataclass
from typing import Any

from memnixa.config import AppConfig
from memnixa.gateway.messages import InboundMessageContext
from memnixa.memory import resolve_allowed_memory_scopes
from memnixa.session import SessionStore
from memnixa.tools.base import Tool


@dataclass(slots=True)
class SearchMemoryTool(Tool):
    """Search the scoped long-term memory store."""

    session: SessionStore
    config: AppConfig
    inbound: InboundMessageContext
    name: str = "memory_search"
    description: str = (
        "Search durable long-term memory for relevant preferences, decisions, goals, "
        "constraints, and prior facts related to the current user/session/project."
    )
    parameters: dict[str, Any] = None  # type: ignore[assignment]

    def __post_init__(self) -> None:
        self.parameters = {
            "type": "object",
            "properties": {
                "query": {"type": "string", "minLength": 1},
                "limit": {"type": "integer", "minimum": 1, "maximum": 10},
            },
            "required": ["query"],
            "additionalProperties": False,
        }

    def execute(self, arguments: dict[str, Any]):
        query = str(arguments.get("query") or "").strip()
        limit = int(arguments.get("limit") or self.config.memory.retrieval_limit or 5)
        scopes = resolve_allowed_memory_scopes(inbound=self.inbound, config=self.config)
        results = self.session.search_memory(query, scopes=scopes, limit=limit)
        return self.success(
            {
                "query": query,
                "results": results,
            }
        )


@dataclass(slots=True)
class GetMemoryTool(Tool):
    """Return one long-term memory item by id."""

    session: SessionStore
    name: str = "memory_get"
    description: str = (
        "Fetch one long-term memory item by id after memory_search returns a relevant result."
    )
    parameters: dict[str, Any] = None  # type: ignore[assignment]

    def __post_init__(self) -> None:
        self.parameters = {
            "type": "object",
            "properties": {
                "id": {"type": "integer", "minimum": 1},
            },
            "required": ["id"],
            "additionalProperties": False,
        }

    def execute(self, arguments: dict[str, Any]):
        memory_id = int(arguments.get("id") or 0)
        item = self.session.get_memory_item(memory_id)
        if item is None:
            return self.failure("memory_not_found", f"Memory item '{memory_id}' was not found.")
        self.session.mark_memory_recalled([memory_id])
        return self.success(
            {
                "id": item.id,
                "scope_type": item.scope_type,
                "scope_id": item.scope_id,
                "memory_type": item.memory_type,
                "content": item.content,
                "confidence": item.confidence,
                "metadata": item.metadata,
                "updated_at": item.updated_at,
            }
        )
