"""
Block parser for the Notion API response format.

Converts Notion block objects (from the API) to markdown-like text.
Reference: https://developers.notion.com/reference/block
"""

from typing import Any


def render_block(block: dict[str, Any]) -> str:
    """
    Render a Notion API block object to markdown-like text.

    Args:
        block: A block object from the Notion API.

    Returns:
        Rendered text string.
    """
    block_type = block.get("type", "")
    data = block.get(block_type, {})

    text = _rich_text_to_str(data.get("rich_text"))

    match block_type:
        # Headings
        case "heading_1":
            return f"# {text}"
        case "heading_2":
            return f"## {text}"
        case "heading_3":
            return f"### {text}"

        # Lists
        case "bulleted_list_item":
            return f"- {text}"
        case "numbered_list_item":
            return f"1. {text}"
        case "to_do":
            checked = data.get("checked", False)
            checkbox = "[x]" if checked else "[ ]"
            return f"{checkbox} {text}"

        # Text blocks
        case "paragraph":
            return text
        case "quote":
            return f"> {text}"
        case "callout":
            icon = ""
            icon_data = data.get("icon")
            if icon_data:
                icon = icon_data.get("emoji", "")
            return f"{icon} {text}" if icon else text
        case "toggle":
            return f"▸ {text}"

        # Code
        case "code":
            language = data.get("language", "")
            return f"```{language}\n{text}\n```"
        case "equation":
            expression = data.get("expression", "")
            return f"$$ {expression} $$"

        # Media
        case "image":
            url = _get_file_url(data)
            caption = _rich_text_to_str(data.get("caption"))
            return f"![{caption}]({url})" if url else f"[Image: {caption}]"
        case "video":
            url = _get_file_url(data)
            return f"[Video: {url}]" if url else "[Video]"
        case "file":
            url = _get_file_url(data)
            caption = _rich_text_to_str(data.get("caption"))
            name = data.get("name", caption or "file")
            return f"[File: {name}]({url})" if url else f"[File: {name}]"
        case "pdf":
            url = _get_file_url(data)
            return f"[PDF]({url})" if url else "[PDF]"
        case "audio":
            url = _get_file_url(data)
            return f"[Audio: {url}]" if url else "[Audio]"

        # Embeds & links
        case "bookmark":
            url = data.get("url", "")
            caption = _rich_text_to_str(data.get("caption"))
            label = caption or url
            return f"[{label}]({url})" if url else ""
        case "embed":
            url = data.get("url", "")
            return f"[Embed: {url}]" if url else "[Embed]"
        case "link_preview":
            url = data.get("url", "")
            return f"[Link: {url}]" if url else ""
        case "link_to_page":
            page_id = data.get("page_id", data.get("database_id", ""))
            return f"[Link to page: {page_id}]"

        # Structural
        case "divider":
            return "---"
        case "table_of_contents":
            return "[Table of Contents]"
        case "breadcrumb":
            return ""
        case "column_list" | "column":
            return ""
        case "synced_block":
            return ""
        case "template":
            return ""
        case "table":
            return "[Table]"
        case "table_row":
            cells = data.get("cells", [])
            row = " | ".join(_rich_text_to_str(cell) for cell in cells)
            return f"| {row} |" if row else ""

        # Child references
        case "child_page":
            title = data.get("title", "")
            return f"[Child page: {title}]"
        case "child_database":
            title = data.get("title", "")
            return f"[Child database: {title}]"

        case _:
            return text


def blocks_to_text(blocks: list[dict[str, Any]], separator: str = "\n") -> str:
    """
    Convert a list of Notion API block objects to text.

    Args:
        blocks: List of block objects from the Notion API.
        separator: Text to join lines with.

    Returns:
        Combined text content.
    """
    lines = []
    for block in blocks:
        text = render_block(block)
        if text:
            lines.append(text)
    return separator.join(lines)


def _rich_text_to_str(rich_text: list | None) -> str:
    """Convert a Notion rich_text array to plain text."""
    if not rich_text:
        return ""
    return "".join(item.get("plain_text", "") for item in rich_text)


def _get_file_url(data: dict) -> str:
    """Extract URL from a file-type block data."""
    file_type = data.get("type", "")
    file_data = data.get(file_type, {})
    return file_data.get("url", "") if isinstance(file_data, dict) else ""
