"""Session search tool for recalling past conversations.

Searches past session JSONL files and returns matching conversations.
Simpler than hermes version - no SQLite, just grep through JSONL files.
"""

import json
import re
from datetime import datetime
from pathlib import Path
from typing import Any

from kyber.agent.tools.base import Tool
from kyber.agent.tools.registry import registry


SESSIONS_DIR = Path.home() / ".kyber" / "sessions"
MAX_RESULTS = 5
MAX_CONTEXT_MESSAGES = 10


def _format_timestamp(ts: str) -> str:
    """Convert ISO timestamp to human-readable date."""
    try:
        dt = datetime.fromisoformat(ts.replace("Z", "+00:00"))
        return dt.strftime("%B %d, %Y at %I:%M %p")
    except Exception:
        return ts or "unknown"


def _search_sessions(query: str, limit: int = 3) -> list[dict[str, Any]]:
    """Search session JSONL files for query matches."""
    if not SESSIONS_DIR.exists():
        return []

    query_lower = query.lower()
    query_terms = set(query_lower.split())
    results = []

    for session_file in SESSIONS_DIR.glob("*.jsonl"):
        try:
            messages = []
            with open(session_file, "r", encoding="utf-8") as f:
                for line in f:
                    line = line.strip()
                    if line:
                        try:
                            messages.append(json.loads(line))
                        except json.JSONDecodeError:
                            continue

            if not messages:
                continue

            # Find matches
            all_content = " ".join(m.get("content", "") for m in messages).lower()
            score = sum(1 for term in query_terms if term in all_content)

            if score == 0:
                continue

            # Get context around first match
            match_idx = 0
            for i, m in enumerate(messages):
                content = m.get("content", "").lower()
                if any(term in content for term in query_terms):
                    match_idx = i
                    break

            start = max(0, match_idx - 3)
            end = min(len(messages), match_idx + MAX_CONTEXT_MESSAGES)
            context = messages[start:end]

            results.append({
                "session_id": session_file.stem,
                "match_count": score,
                "context": context,
                "first_match_idx": match_idx,
            })

        except Exception:
            continue

    # Sort by match count, take top N
    results.sort(key=lambda x: x["match_count"], reverse=True)
    return results[:limit]


class SessionSearchTool(Tool):
    """Search past conversations for relevant context."""

    @property
    def name(self) -> str:
        return "session_search"

    @property
    def description(self) -> str:
        return (
            "Search your long-term memory of past conversations. This is your recall -- "
            "every past session is searchable.\n\n"
            "USE THIS PROACTIVELY when:\n"
            "- The user says 'we did this before', 'remember when', 'last time', 'as I mentioned'\n"
            "- The user asks about a topic you worked on before but don't have in current context\n"
            "- The user references a project, person, or concept that seems familiar but isn't in memory\n"
            "- You want to check if you've solved a similar problem before\n"
            "- The user asks 'what did we do about X?' or 'how did we fix Y?'\n\n"
            "Don't hesitate to search -- it's fast and cheap. Better to search and confirm "
            "than to guess or ask the user to repeat themselves."
        )

    @property
    def parameters(self) -> dict[str, Any]:
        return {
            "type": "object",
            "properties": {
                "query": {
                    "type": "string",
                    "description": "Search query — keywords to find in past sessions.",
                },
                "limit": {
                    "type": "integer",
                    "description": "Max sessions to return (default: 3, max: 5).",
                    "default": 3,
                },
            },
            "required": ["query"],
        }

    @property
    def toolset(self) -> str:
        return "memory"

    async def execute(self, query: str, limit: int = 3, **kwargs) -> str:
        if not query or not query.strip():
            return json.dumps({"success": False, "error": "Query cannot be empty."}, ensure_ascii=False)

        query = query.strip()
        limit = min(limit, MAX_RESULTS)

        results = _search_sessions(query, limit)

        if not results:
            return json.dumps({
                "success": True,
                "query": query,
                "results": [],
                "count": 0,
                "message": "No matching sessions found.",
            }, ensure_ascii=False)

        # Format results
        formatted = []
        for r in results:
            context_text = []
            for msg in r["context"]:
                role = msg.get("role", "unknown").upper()
                content = msg.get("content", "")
                # Truncate long messages
                if len(content) > 500:
                    content = content[:250] + "\n...[truncated]...\n" + content[-250:]
                context_text.append(f"[{role}]: {content}")

            formatted.append({
                "session_id": r["session_id"],
                "match_count": r["match_count"],
                "conversation": "\n\n".join(context_text),
            })

        return json.dumps({
            "success": True,
            "query": query,
            "results": formatted,
            "count": len(formatted),
        }, ensure_ascii=False)


# Self-register
registry.register(SessionSearchTool())
