"""
Phase 79: RAG Pipeline MCP Microservice Tools.

Exposes the Phase 62 RAG pipeline (source-based) as MCP tools.
"""

import asyncio
import json

from mcp.types import TextContent, Tool, ToolAnnotations

_SAFE_READ = ToolAnnotations(readOnlyHint=True, destructiveHint=False, idempotentHint=True, openWorldHint=False)
_SAFE_WRITE = ToolAnnotations(readOnlyHint=False, destructiveHint=False, idempotentHint=False, openWorldHint=False)
_DESTRUCTIVE = ToolAnnotations(readOnlyHint=False, destructiveHint=True, idempotentHint=False, openWorldHint=False)

TOOLS = [
    Tool(
        name="rag_add_source",
        description="Register a data source for RAG retrieval (channel, file, or knowledge_base).",
        inputSchema={
            "type": "object",
            "properties": {
                "name": {"type": "string", "description": "Unique source name"},
                "source_type": {
                    "type": "string",
                    "description": "channel, file, or knowledge_base",
                    "enum": ["channel", "file", "knowledge_base"],
                },
                "path_or_config": {"type": "string", "description": "Channel name, file path, or config string"},
            },
            "required": ["name", "source_type", "path_or_config"],
        },
        annotations=_SAFE_WRITE,
    ),
    Tool(
        name="rag_list_sources",
        description="List all registered RAG data sources.",
        inputSchema={"type": "object", "properties": {}},
        annotations=_SAFE_READ,
    ),
    Tool(
        name="rag_remove_source",
        description="Remove a registered RAG data source.",
        inputSchema={
            "type": "object",
            "properties": {
                "name": {"type": "string", "description": "Source name to remove"},
            },
            "required": ["name"],
        },
        annotations=_DESTRUCTIVE,
    ),
    Tool(
        name="rag_query",
        description="Query all registered sources for relevant context. Returns ranked chunks.",
        inputSchema={
            "type": "object",
            "properties": {
                "question": {"type": "string", "description": "Natural language query"},
                "sources": {
                    "type": "array",
                    "items": {"type": "string"},
                    "description": "Filter to specific source names (omit for all)",
                },
                "max_chunks": {"type": "integer", "description": "Max chunks to return (default: 5)"},
            },
            "required": ["question"],
        },
        annotations=_SAFE_READ,
    ),
    Tool(
        name="rag_build_prompt",
        description="Build a prompt with RAG context injected. Queries sources then formats for LLM consumption.",
        inputSchema={
            "type": "object",
            "properties": {
                "question": {"type": "string", "description": "The question or task to build context for"},
                "max_chunks": {"type": "integer", "default": 3},
            },
            "required": ["question"],
        },
        annotations=_SAFE_READ,
    ),
]


# ── Handlers ───────────────────────────────────────────────────────────────


async def _handle_add_source(args: dict) -> list[TextContent]:
    from brynq.rag_pipeline import add_source
    try:
        src = await asyncio.to_thread(
            add_source,
            name=args["name"],
            source_type=args["source_type"],
            path_or_config=args["path_or_config"],
        )
        return [TextContent(
            type="text",
            text=f"RAG source added: {src['name']} (type: {src['source_type']})",
        )]
    except Exception as e:
        return [TextContent(type="text", text=f"Error: {e}")]


async def _handle_list_sources(args: dict) -> list[TextContent]:
    from brynq.rag_pipeline import list_sources
    try:
        sources = await asyncio.to_thread(list_sources)
        if not sources:
            return [TextContent(type="text", text="No RAG sources registered.")]
        lines = [f"RAG sources ({len(sources)}):"]
        for s in sources:
            lines.append(f"  {s['name']} ({s['source_type']}): {s.get('path_or_config', '')}")
        return [TextContent(type="text", text="\n".join(lines))]
    except Exception as e:
        return [TextContent(type="text", text=f"Error: {e}")]


async def _handle_remove_source(args: dict) -> list[TextContent]:
    from brynq.rag_pipeline import remove_source
    try:
        removed = await asyncio.to_thread(remove_source, name=args["name"])
        if removed:
            return [TextContent(type="text", text=f"RAG source '{args['name']}' removed.")]
        return [TextContent(type="text", text=f"RAG source '{args['name']}' not found.")]
    except Exception as e:
        return [TextContent(type="text", text=f"Error: {e}")]


async def _handle_query(args: dict) -> list[TextContent]:
    from brynq.rag_pipeline import query_context
    try:
        results = await asyncio.to_thread(
            query_context,
            question=args["question"],
            sources=args.get("sources"),
            max_chunks=args.get("max_chunks", 5),
        )
        if not results:
            return [TextContent(type="text", text="No relevant context found.")]
        return [TextContent(type="text", text=json.dumps(results, indent=2, default=str))]
    except Exception as e:
        return [TextContent(type="text", text=f"Error: {e}")]


async def _handle_build_prompt(args: dict) -> list[TextContent]:
    from brynq.rag_pipeline import query_context, build_prompt
    try:
        chunks = await asyncio.to_thread(
            query_context,
            question=args["question"],
            max_chunks=args.get("max_chunks", 3),
        )
        prompt = build_prompt(args["question"], chunks)
        return [TextContent(type="text", text=prompt)]
    except Exception as e:
        return [TextContent(type="text", text=f"Error: {e}")]


HANDLERS = {
    "rag_add_source": _handle_add_source,
    "rag_list_sources": _handle_list_sources,
    "rag_remove_source": _handle_remove_source,
    "rag_query": _handle_query,
    "rag_build_prompt": _handle_build_prompt,
}
