"""MCP Server for Docmost."""

import os
import asyncio
from typing import Any

from mcp.server import Server
from mcp.server.stdio import stdio_server
from mcp.types import Tool, TextContent

from .client import DocmostClient, DocmostConfig


server = Server("docmost")
client: DocmostClient | None = None


def get_client() -> DocmostClient:
    """Get or create Docmost client."""
    global client
    if client is None:
        config = DocmostConfig(
            base_url=os.environ.get("DOCMOST_URL", "https://your-docmost-instance.com"),
            auth_token=os.environ["DOCMOST_AUTH_TOKEN"],
        )
        client = DocmostClient(config)
    return client


def format_page_info(page: dict) -> str:
    """Format page info for display."""
    lines = [
        f"📄 **{page.get('title', 'Untitled')}**",
        f"- ID: {page.get('id')}",
        f"- Slug: {page.get('slugId')}",
        f"- Space ID: {page.get('spaceId')}",
        f"- Created: {page.get('createdAt')}",
        f"- Updated: {page.get('updatedAt')}",
    ]
    if page.get("parentPageId"):
        lines.append(f"- Parent: {page.get('parentPageId')}")
    return "\n".join(lines)


def extract_text_from_content(content: dict) -> str:
    """Extract plain text from Docmost content structure."""
    if not content:
        return ""

    def extract_node(node: dict) -> str:
        text_parts = []
        if node.get("text"):
            text_parts.append(node["text"])
        if node.get("content"):
            for child in node["content"]:
                text_parts.append(extract_node(child))
        return " ".join(text_parts)

    return extract_node(content)


@server.list_tools()
async def list_tools() -> list[Tool]:
    """List available tools."""
    return [
        Tool(
            name="docmost_get_page",
            description="Get page information and content by ID or slug. Returns title, metadata, and full content.",
            inputSchema={
                "type": "object",
                "properties": {
                    "page_id": {
                        "type": "string",
                        "description": "Page ID (UUID) or slug ID (e.g., 'yQQmTbt8it')",
                    },
                    "include_content": {
                        "type": "boolean",
                        "description": "Whether to include page content (default: true)",
                        "default": True,
                    },
                },
                "required": ["page_id"],
            },
        ),
        Tool(
            name="docmost_list_pages",
            description="List pages in a space or under a parent page.",
            inputSchema={
                "type": "object",
                "properties": {
                    "space_id": {
                        "type": "string",
                        "description": "Space ID to list pages from",
                    },
                    "parent_page_id": {
                        "type": "string",
                        "description": "Optional: Parent page ID to list children",
                    },
                    "page": {
                        "type": "integer",
                        "description": "Page number for pagination (default: 1)",
                        "default": 1,
                    },
                },
                "required": [],
            },
        ),
        Tool(
            name="docmost_recent_pages",
            description="Get recently updated pages in a space.",
            inputSchema={
                "type": "object",
                "properties": {
                    "space_id": {
                        "type": "string",
                        "description": "Space ID to get recent pages from",
                    },
                },
                "required": ["space_id"],
            },
        ),
        Tool(
            name="docmost_create_page",
            description="Create a new page in Docmost.",
            inputSchema={
                "type": "object",
                "properties": {
                    "title": {"type": "string", "description": "Page title"},
                    "space_id": {"type": "string", "description": "Space ID where the page will be created"},
                    "parent_page_id": {"type": "string", "description": "Optional: Parent page ID for nested pages"},
                    "content_text": {"type": "string", "description": "Optional: Initial page content as plain text"},
                },
                "required": ["title", "space_id"],
            },
        ),
        Tool(
            name="docmost_update_page",
            description="Update an existing page's title or content.",
            inputSchema={
                "type": "object",
                "properties": {
                    "page_id": {"type": "string", "description": "Page ID to update"},
                    "title": {"type": "string", "description": "New page title"},
                    "content_text": {"type": "string", "description": "New page content as plain text"},
                },
                "required": ["page_id"],
            },
        ),
        Tool(
            name="docmost_delete_page",
            description="Delete a page from Docmost.",
            inputSchema={
                "type": "object",
                "properties": {
                    "page_id": {"type": "string", "description": "Page ID to delete"},
                },
                "required": ["page_id"],
            },
        ),
        Tool(
            name="docmost_list_spaces",
            description="List all spaces in the workspace.",
            inputSchema={
                "type": "object",
                "properties": {
                    "limit": {"type": "integer", "description": "Maximum results (default: 50)", "default": 50},
                    "page": {"type": "integer", "description": "Page number (default: 1)", "default": 1},
                },
                "required": [],
            },
        ),
        Tool(
            name="docmost_get_space",
            description="Get space information by ID or slug.",
            inputSchema={
                "type": "object",
                "properties": {
                    "space_id": {"type": "string", "description": "Space ID or slug"},
                },
                "required": ["space_id"],
            },
        ),
        Tool(
            name="docmost_get_current_user",
            description="Get information about the currently authenticated user.",
            inputSchema={"type": "object", "properties": {}, "required": []},
        ),
        Tool(
            name="docmost_list_members",
            description="List all members in the workspace.",
            inputSchema={
                "type": "object",
                "properties": {
                    "limit": {"type": "integer", "description": "Maximum results (default: 50)", "default": 50},
                },
                "required": [],
            },
        ),
        Tool(
            name="docmost_list_comments",
            description="List comments on a page.",
            inputSchema={
                "type": "object",
                "properties": {
                    "page_id": {"type": "string", "description": "Page ID to get comments from"},
                    "limit": {"type": "integer", "description": "Maximum results (default: 50)", "default": 50},
                },
                "required": ["page_id"],
            },
        ),
        Tool(
            name="docmost_add_comment",
            description="Add a comment to a page.",
            inputSchema={
                "type": "object",
                "properties": {
                    "page_id": {"type": "string", "description": "Page ID to comment on"},
                    "content": {"type": "string", "description": "Comment text"},
                    "parent_comment_id": {"type": "string", "description": "Optional: Parent comment ID for replies"},
                },
                "required": ["page_id", "content"],
            },
        ),
        Tool(
            name="docmost_get_page_history",
            description="Get revision history of a page.",
            inputSchema={
                "type": "object",
                "properties": {
                    "page_id": {"type": "string", "description": "Page ID"},
                    "limit": {"type": "integer", "description": "Maximum revisions to return (default: 20)", "default": 20},
                },
                "required": ["page_id"],
            },
        ),
    ]



@server.call_tool()
async def call_tool(name: str, arguments: dict[str, Any]) -> list[TextContent]:
    """Handle tool calls."""
    docmost = get_client()

    try:
        # ==================== Page Tools ====================
        if name == "docmost_get_page":
            page_id = arguments["page_id"]
            include_content = arguments.get("include_content", True)

            resp = await docmost.get_page_info(page_id)
            page_data = resp.get("data", resp)

            output = format_page_info(page_data)

            if include_content and page_data.get("content"):
                content_text = extract_text_from_content(page_data["content"])
                output += f"\n\n**Content:**\n{content_text}"

            return [TextContent(type="text", text=output)]

        elif name == "docmost_list_pages":
            space_id = arguments.get("space_id")
            parent_page_id = arguments.get("parent_page_id")
            page_num = arguments.get("page", 1)

            if not space_id:
                return [TextContent(type="text", text="❌ space_id is required")]

            resp = await docmost.get_sidebar_pages(space_id, parent_page_id, page_num)
            pages = resp.get("data", {}).get("items", [])

            if not pages:
                return [TextContent(type="text", text="No pages found.")]

            output = "📚 Pages:\n\n"
            for i, pg in enumerate(pages, 1):
                output += f"{i}. **{pg.get('title', 'Untitled')}** (Slug: {pg.get('slugId')})\n"
                if pg.get("hasChildren"):
                    output += "   └─ Has children\n"

            return [TextContent(type="text", text=output)]

        elif name == "docmost_recent_pages":
            space_id = arguments["space_id"]
            resp = await docmost.get_recent_pages(space_id)
            pages = resp.get("data", {}).get("items", resp.get("data", []))

            if not pages:
                return [TextContent(type="text", text="No recent pages found.")]

            output = "🕐 Recent Pages:\n\n"
            for i, pg in enumerate(pages, 1):
                output += f"{i}. **{pg.get('title', 'Untitled')}** (Slug: {pg.get('slugId')})\n"
                output += f"   Updated: {pg.get('updatedAt')}\n"

            return [TextContent(type="text", text=output)]

        elif name == "docmost_create_page":
            title = arguments["title"]
            space_id = arguments["space_id"]
            parent_page_id = arguments.get("parent_page_id")
            content_text = arguments.get("content_text")

            content = None
            if content_text:
                content = {
                    "type": "doc",
                    "content": [{"type": "paragraph", "content": [{"type": "text", "text": content_text}]}]
                }

            resp = await docmost.create_page(title, space_id, parent_page_id, content)
            page = resp.get("data", resp)

            return [TextContent(type="text", text=f"✅ Page created!\n{format_page_info(page)}")]

        elif name == "docmost_update_page":
            page_id = arguments["page_id"]
            title = arguments.get("title")
            content_text = arguments.get("content_text")

            content = None
            if content_text:
                content = {
                    "type": "doc",
                    "content": [{"type": "paragraph", "content": [{"type": "text", "text": content_text}]}]
                }

            await docmost.update_page(page_id, title, content)
            return [TextContent(type="text", text="✅ Page updated!")]

        elif name == "docmost_delete_page":
            page_id = arguments["page_id"]
            await docmost.delete_page(page_id)
            return [TextContent(type="text", text=f"✅ Page '{page_id}' deleted.")]

        # ==================== Space Tools ====================
        elif name == "docmost_list_spaces":
            limit = arguments.get("limit", 50)
            page_num = arguments.get("page", 1)

            resp = await docmost.list_spaces(limit, page_num)
            spaces = resp.get("data", {}).get("items", [])

            if not spaces:
                return [TextContent(type="text", text="No spaces found.")]

            output = "🗂️ Spaces:\n\n"
            for i, space in enumerate(spaces, 1):
                output += f"{i}. **{space.get('name')}** (Slug: {space.get('slug')})\n"
                output += f"   - ID: {space.get('id')}\n"
                if space.get("description"):
                    output += f"   - {space.get('description')}\n"

            return [TextContent(type="text", text=output)]

        elif name == "docmost_get_space":
            space_id = arguments["space_id"]
            resp = await docmost.get_space_info(space_id)
            space = resp.get("data", resp)

            output = f"🗂️ **{space.get('name')}**\n"
            output += f"- ID: {space.get('id')}\n"
            output += f"- Slug: {space.get('slug')}\n"
            if space.get("description"):
                output += f"- Description: {space.get('description')}\n"

            return [TextContent(type="text", text=output)]

        # ==================== User Tools ====================
        elif name == "docmost_get_current_user":
            resp = await docmost.get_current_user()
            user = resp.get("data", resp)

            output = f"👤 **{user.get('name', user.get('email'))}**\n"
            output += f"- ID: {user.get('id')}\n"
            output += f"- Email: {user.get('email')}\n"
            if user.get("role"):
                output += f"- Role: {user.get('role')}\n"

            return [TextContent(type="text", text=output)]

        elif name == "docmost_list_members":
            limit = arguments.get("limit", 50)
            resp = await docmost.list_workspace_members(limit)
            members = resp.get("data", {}).get("items", [])

            if not members:
                return [TextContent(type="text", text="No members found.")]

            output = "👥 Members:\n\n"
            for i, m in enumerate(members, 1):
                output += f"{i}. **{m.get('name', m.get('email'))}** - {m.get('role', 'member')}\n"

            return [TextContent(type="text", text=output)]

        # ==================== Comment Tools ====================
        elif name == "docmost_list_comments":
            page_id = arguments["page_id"]
            limit = arguments.get("limit", 50)

            resp = await docmost.list_comments(page_id, limit)
            comments = resp.get("data", {}).get("items", [])

            if not comments:
                return [TextContent(type="text", text="No comments.")]

            output = "💬 Comments:\n\n"
            for i, c in enumerate(comments, 1):
                output += f"{i}. {c.get('content', '')}\n"
                output += f"   - At: {c.get('createdAt')}\n"

            return [TextContent(type="text", text=output)]

        elif name == "docmost_add_comment":
            page_id = arguments["page_id"]
            content = arguments["content"]
            parent_id = arguments.get("parent_comment_id")

            await docmost.create_comment(page_id, content, parent_id)
            return [TextContent(type="text", text="✅ Comment added!")]

        # ==================== History ====================
        elif name == "docmost_get_page_history":
            page_id = arguments["page_id"]
            limit = arguments.get("limit", 20)

            resp = await docmost.get_page_history(page_id, limit)
            history = resp.get("data", {}).get("items", [])

            if not history:
                return [TextContent(type="text", text="No history.")]

            output = "📜 History:\n\n"
            for i, h in enumerate(history, 1):
                output += f"{i}. {h.get('createdAt')}\n"

            return [TextContent(type="text", text=output)]

        else:
            return [TextContent(type="text", text=f"Unknown tool: {name}")]

    except Exception as e:
        return [TextContent(type="text", text=f"❌ Error: {str(e)}")]


async def run():
    """Run the MCP server."""
    async with stdio_server() as (read_stream, write_stream):
        await server.run(read_stream, write_stream, server.create_initialization_options())


def main():
    """Entry point."""
    asyncio.run(run())


if __name__ == "__main__":
    main()
