"""Document creation MCP tool for TokenMoulds."""

from __future__ import annotations

from datetime import datetime
from pathlib import Path
from typing import Any, Dict, Optional

from tokenmoulds.emitters import WordDocumentEmitter
from tokenmoulds.ir import build_document_ir
from tokenmoulds.mcp.injector import inject_content
from tokenmoulds.mcp.tools.token_utils import convert_dtcg_to_internal, normalize_tokens
from tokenmoulds.styles import create_style_resolver_from_tokens
from tokenmoulds.templates import get_bundled_template_bytes

# JSON Schema for create_document tool
DOCUMENT_TOOL_SCHEMA: Dict[str, Any] = {
    "type": "object",
    "properties": {
        "title": {
            "type": "string",
            "description": "Document title",
        },
        "content": {
            "type": "array",
            "description": "Document content blocks",
            "items": {
                "type": "object",
                "properties": {
                    "type": {
                        "type": "string",
                        "enum": [
                            "heading1",
                            "heading2",
                            "heading3",
                            "heading4",
                            "paragraph",
                            "bullet_list",
                            "numbered_list",
                            "table",
                            "quote",
                        ],
                        "description": "Content block type",
                    },
                    "text": {
                        "type": "string",
                        "description": "Text content (for headings, paragraphs, quotes)",
                    },
                    "items": {
                        "type": "array",
                        "items": {"type": "string"},
                        "description": "List items (for bullet_list, numbered_list)",
                    },
                    "rows": {
                        "type": "array",
                        "items": {
                            "type": "array",
                            "items": {"type": "string"},
                        },
                        "description": "Table rows including header row (for table)",
                    },
                },
                "required": ["type"],
            },
        },
        "brand": {
            "type": "string",
            "description": "Brand identifier (optional, uses default if not specified)",
        },
        "filename": {
            "type": "string",
            "description": "Output filename without extension (optional, auto-generated if not specified)",
        },
    },
    "required": ["title", "content"],
}


async def create_document(
    arguments: Dict[str, Any],
    tokens: Optional[Dict[str, Any]],
    output_path: Path,
) -> Dict[str, Any]:
    """Create a styled Word document.

    Two modes:
    - With tokens: Generate custom template via emitter pipeline
    - Without tokens: Use bundled template (276 styles, professional defaults)

    Args:
        arguments: Tool arguments from MCP call
        tokens: Loaded design tokens (optional)
        output_path: Directory for output file

    Returns:
        Result dictionary with file path and metadata
    """
    title = arguments.get("title", "Untitled Document")
    content_blocks = arguments.get("content", [])
    filename = arguments.get("filename")

    # Generate filename if not provided
    if not filename:
        timestamp = datetime.now().strftime("%Y%m%d_%H%M%S")
        safe_title = "".join(c if c.isalnum() or c in " -_" else "" for c in title)
        safe_title = safe_title.replace(" ", "_")[:30]
        filename = f"{safe_title}_{timestamp}"

    output_file = output_path / f"{filename}.docx"

    try:
        # Step 1: Acquire template (Mode A or Mode B)
        if tokens is not None:
            # Mode B: Custom template from tokens
            template_bytes, styles_count, style_context = _build_custom_template(
                tokens, arguments
            )
            template_mode = "custom"
        else:
            # Mode A: Bundled template (fallback)
            template_bytes = get_bundled_template_bytes("word")
            styles_count = 276
            template_mode = "bundled"
            style_context = {"table_style": "LightGrid-Accent1"}

        # Step 2: Inject content using injector (follows emitter patterns)
        document_bytes = inject_content(template_bytes, content_blocks, style_context)

        # Step 3: Write to file
        output_file.parent.mkdir(parents=True, exist_ok=True)
        output_file.write_bytes(document_bytes)

        return {
            "success": True,
            "file_path": str(output_file.absolute()),
            "filename": output_file.name,
            "title": title,
            "content_blocks": len(content_blocks),
            "styles_applied": styles_count,
            "template_mode": template_mode,
            "brand_used": arguments.get("brand", "default"),
            "message": f"Document created with {styles_count} themed styles. Zero Office defaults.",
        }

    except Exception as e:
        return {
            "error": f"Failed to create document: {str(e)}",
            "title": title,
            "attempted_output": str(output_file),
        }


def _build_custom_template(
    tokens: Dict[str, Any],
    arguments: Dict[str, Any],
) -> tuple[bytes, int, Dict[str, Any]]:
    """Build custom template from tokens using emitter pipeline.

    Returns:
        Tuple of (template_bytes, styles_count, style_context)
    """
    # Normalize tokens
    token_payload = _extract_and_normalize_tokens(tokens)

    # Build Document IR
    org_id = arguments.get("brand", "mcp_generated")
    document_ir = build_document_ir(token_payload, org_id, locale="US")

    # Create style resolver for full coverage
    style_resolver = create_style_resolver_from_tokens(
        token_payload,
        body_color=document_ir.body_style.color,
        heading_color=(
            document_ir.heading_styles[0].color
            if document_ir.heading_styles
            else document_ir.body_style.color
        ),
    )

    # Build template via emitter
    emitter = WordDocumentEmitter(
        document_ir,
        template_root=None,
        embed_fonts=False,  # Don't embed for MCP (use system fonts)
        style_resolver=style_resolver,
    )
    template_bytes = emitter.build_package()
    styles_count = len(style_resolver.resolve_all())

    # Extract style context from tokens for content injection
    table_style = (
        token_payload.get("styles", {})
        .get("table", {})
        .get("base", {})
        .get("style_id", "LightGrid-Accent1")
    )
    style_context = {"table_style": table_style}

    return template_bytes, styles_count, style_context


def _extract_and_normalize_tokens(tokens: Dict[str, Any]) -> Dict[str, Any]:
    """Extract token payload and normalize with defaults.

    Preserves the original document.py behavior: DTCG conversion + normalization.
    """
    # Check if it's a DTCG file with $type markers
    if any(key.startswith("$") for key in tokens.keys()):
        payload = convert_dtcg_to_internal(tokens)
    elif "tokens" in tokens:
        payload = tokens["tokens"]
    elif "typography" in tokens or "colors" in tokens:
        payload = tokens
    else:
        payload = tokens

    return normalize_tokens(payload)
