"""
Query system for pixel-to-content mapping.

This module provides data structures for querying rendered content,
enabling interactive features like link clicking, word definition lookup,
and text selection.
"""

from __future__ import annotations
from dataclasses import dataclass
from typing import Optional, Tuple, List, Any, TYPE_CHECKING

if TYPE_CHECKING:
    from pyWebLayout.core.base import Queriable


@dataclass
class QueryResult:
    """
    Result of querying a point on a rendered page.

    This encapsulates all information about what was found at a pixel location,
    including geometry, content, and interaction capabilities.
    """
    # What was found
    object: 'Queriable'  # The object at this point
    object_type: str  # "link", "text", "image", "button", "word", "empty"

    # Geometry
    bounds: Tuple[int, int, int, int]  # (x, y, width, height) in page coordinates

    # Content (for text/words)
    text: Optional[str] = None
    word_index: Optional[int] = None  # Index in abstract document structure
    block_index: Optional[int] = None  # Block index in document

    # Interaction (for links/buttons)
    is_interactive: bool = False
    link_target: Optional[str] = None  # URL or internal reference
    callback: Optional[Any] = None  # Interaction callback

    # Hierarchy (for debugging/traversal)
    parent_line: Optional[Any] = None
    parent_page: Optional[Any] = None

    def to_dict(self) -> dict:
        """Convert to dictionary for serialization"""
        return {
            'object_type': self.object_type,
            'bounds': self.bounds,
            'text': self.text,
            'is_interactive': self.is_interactive,
            'link_target': self.link_target,
            'word_index': self.word_index,
            'block_index': self.block_index
        }


@dataclass
class SelectionRange:
    """
    Represents a range of selected text between two points.
    """
    start_point: Tuple[int, int]
    end_point: Tuple[int, int]
    results: List[QueryResult]  # All query results in the range

    @property
    def text(self) -> str:
        """Get concatenated text from all results"""
        return " ".join(r.text for r in self.results if r.text)

    @property
    def bounds_list(self) -> List[Tuple[int, int, int, int]]:
        """Get list of all bounding boxes for highlighting"""
        return [r.bounds for r in self.results]

    def to_dict(self) -> dict:
        """Convert to dictionary for serialization"""
        return {
            'start': self.start_point,
            'end': self.end_point,
            'text': self.text,
            'word_count': len(self.results),
            'bounds': self.bounds_list
        }
