"""
Parser for all Notion property types.

Handles the Notion API response format for page properties.
Reference: https://developers.notion.com/reference/property-value-object
"""

from typing import Any


def parse_property(prop_data: dict[str, Any]) -> Any:
    """
    Parse a single Notion property value into a Python-native value.

    Args:
        prop_data: A property value object from the Notion API.

    Returns:
        The parsed value (str, number, bool, list, or None).
    """
    prop_type = prop_data.get("type")
    if not prop_type:
        return None

    value = prop_data.get(prop_type)

    match prop_type:
        case "title":
            return _rich_text_to_str(value)
        case "rich_text":
            return _rich_text_to_str(value)
        case "number":
            return value
        case "checkbox":
            return value
        case "select":
            return value.get("name") if value else None
        case "multi_select":
            return [item.get("name") for item in (value or [])]
        case "status":
            return value.get("name") if value else None
        case "date":
            return _parse_date(value)
        case "people":
            return [_parse_person(p) for p in (value or [])]
        case "files":
            return [_parse_file(f) for f in (value or [])]
        case "url":
            return value
        case "email":
            return value
        case "phone_number":
            return value
        case "formula":
            return _parse_formula(value)
        case "relation":
            return [item.get("id") for item in (value or [])]
        case "rollup":
            return _parse_rollup(value)
        case "created_time":
            return value
        case "last_edited_time":
            return value
        case "created_by":
            return _parse_person(value) if value else None
        case "last_edited_by":
            return _parse_person(value) if value else None
        case "unique_id":
            return _parse_unique_id(value)
        case "verification":
            return value
        case "button":
            return None  # buttons have no value
        case _:
            return str(value) if value is not None else None


def parse_all_properties(properties: dict[str, Any]) -> dict[str, Any]:
    """
    Parse all properties of a Notion page.

    Args:
        properties: The "properties" dict from a Notion page object.

    Returns:
        A dict mapping property names to parsed values.
    """
    result = {}
    for name, prop_data in properties.items():
        result[name] = parse_property(prop_data)
    return result


def get_page_title(properties: dict[str, Any]) -> str:
    """
    Extract the title from page properties.

    The title property is the one with type "title".

    Args:
        properties: The "properties" dict from a Notion page object.

    Returns:
        The page title as a string.
    """
    for prop_data in properties.values():
        if prop_data.get("type") == "title":
            return _rich_text_to_str(prop_data.get("title", []))
    return ""


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 _parse_date(value: dict | None) -> str | None:
    """Parse a date property value."""
    if not value:
        return None
    start = value.get("start", "")
    end = value.get("end")
    if end:
        return f"{start} ~ {end}"
    return start


def _parse_person(person: dict) -> str:
    """Parse a person/user object to a display string."""
    name = person.get("name")
    if name:
        return name
    return person.get("id", "")


def _parse_file(file_obj: dict) -> str:
    """Parse a file object to its URL."""
    name = file_obj.get("name", "")
    file_data = file_obj.get("file") or file_obj.get("external")
    url = file_data.get("url", "") if file_data else ""
    return url or name


def _parse_formula(value: dict | None) -> Any:
    """Parse a formula result."""
    if not value:
        return None
    formula_type = value.get("type")
    return value.get(formula_type) if formula_type else None


def _parse_rollup(value: dict | None) -> Any:
    """Parse a rollup result."""
    if not value:
        return None
    rollup_type = value.get("type")
    if rollup_type == "array":
        return [parse_property(item) for item in value.get("array", [])]
    return value.get(rollup_type) if rollup_type else None


def _parse_unique_id(value: dict | None) -> str | None:
    """Parse a unique_id property."""
    if not value:
        return None
    prefix = value.get("prefix", "")
    number = value.get("number", "")
    if prefix:
        return f"{prefix}-{number}"
    return str(number)
