"""soagila_restore — post-compaction context recovery.

Pair for ``soagila_snapshot``. Call this as the FIRST action after a
conversation compaction event so Claude can rebuild the detailed context
that the summariser threw away.
"""

from __future__ import annotations

import json
import logging

from mcp.types import TextContent, Tool

logger = logging.getLogger(__name__)

_SNAPSHOT_TAG = "__soagila_snapshot__"


def get_definition() -> Tool:
    return Tool(
        name="soagila_restore",
        description=(
            "POST-COMPACTION CONTEXT RECOVERY — Call this tool IMMEDIATELY "
            "as your FIRST action when a conversation has just been "
            "compacted by Anthropic's summariser. It pulls back the most "
            "recent snapshot you saved with soagila_snapshot and returns "
            "the full structured context (decisions, code changes, open "
            "questions, next actions, artifacts). Use the returned data to "
            "reconstruct your working knowledge of the session so you can "
            "answer the user as if the compaction never happened.\n\n"
            "WHEN TO CALL:\n"
            "1. You see 'Compacting our conversation' or similar UI hint\n"
            "2. A new reply feels disconnected from earlier context\n"
            "3. You need to resume work after a long break\n"
            "4. The user asks you to 'catch up' or 'remember where we were'\n\n"
            "WHAT IT DOES: fetches the most recent snapshot for this "
            "project, decrypts it with the per-project AES key, and returns "
            "the original JSON payload including session summary, all "
            "decisions, all code changes, all open questions, and the "
            "ordered next-action list."
        ),
        inputSchema={
            "type": "object",
            "properties": {
                "snapshot_id": {
                    "type": "string",
                    "description": "Optional specific snapshot to load. If omitted, returns the most recent one.",
                },
                "limit": {
                    "type": "integer",
                    "description": "How many recent snapshots to list if no id is given. Default: 1 (most recent only).",
                    "minimum": 1,
                    "maximum": 10,
                },
            },
        },
    )


async def handle(arguments: dict) -> list[TextContent]:
    snapshot_id = (arguments.get("snapshot_id") or "").strip()
    limit = max(1, min(int(arguments.get("limit", 1)), 10))

    try:
        from soagila.core.tcmg.episodic_memory import get as ep_get
        from soagila.db.sqlite_init import get_db

        if snapshot_id:
            mem = await ep_get(snapshot_id)
            if mem is None:
                return [TextContent(
                    type="text",
                    text=json.dumps({
                        "error": f"Snapshot '{snapshot_id}' not found.",
                    }),
                )]
            snapshots = [mem]
        else:
            # Query snapshots by classification + topic
            db = await get_db()
            cursor = await db.execute(
                """
                SELECT id FROM episodic_memories
                WHERE classification = 'snapshot'
                   OR source_type = 'snapshot'
                ORDER BY created_at DESC
                LIMIT ?
                """,
                (limit,),
            )
            rows = await cursor.fetchall()
            if not rows:
                return [TextContent(
                    type="text",
                    text=json.dumps({
                        "status": "no_snapshots",
                        "message": (
                            "No snapshots found for this project. Either "
                            "this is a fresh session or snapshots were "
                            "never taken. Call soagila_recall for general "
                            "memory retrieval instead."
                        ),
                    }, indent=2),
                )]
            snapshots = []
            for row in rows:
                mem = await ep_get(str(row[0]))
                if mem is not None:
                    snapshots.append(mem)

        # Unpack the JSON payload from each snapshot's (now-decrypted) content
        results = []
        for mem in snapshots:
            parsed: dict | None = None
            try:
                parsed = json.loads(mem.content)
            except Exception:
                parsed = None
            results.append({
                "snapshot_id": mem.id,
                "created_at": getattr(mem, "created_at", None),
                "topic_tags": getattr(mem, "topic_tags", []),
                "payload": parsed if parsed else mem.content,
                "structured": parsed is not None,
            })

        return [TextContent(
            type="text",
            text=json.dumps({
                "status": "restored",
                "count": len(results),
                "snapshots": results,
                "next_step": (
                    "Read each snapshot's payload carefully. Use "
                    "`session_summary`, `decisions`, `code_changes`, "
                    "`open_questions`, and `next_actions` to rebuild your "
                    "working context before replying to the user."
                ),
            }, indent=2, default=str),
        )]
    except Exception as exc:  # noqa: BLE001
        logger.error("restore failed: %s", exc, exc_info=True)
        return [TextContent(
            type="text",
            text=json.dumps({"error": f"Restore failed: {exc}"}),
        )]