"""Type stubs for the xa11y native extension module."""

from __future__ import annotations

from collections.abc import Callable, Iterator
from types import TracebackType

# ── Exceptions ───────────────────────────────────────────────────────────────

class XA11yError(Exception):
    """Base exception for all xa11y errors."""

class PermissionDeniedError(XA11yError):
    """Accessibility permissions have not been granted."""

class SelectorNotMatchedError(XA11yError):
    """No element in the tree matched the given selector."""

class ActionNotSupportedError(XA11yError):
    """The requested action is not supported on the target element."""

class TimeoutError(XA11yError):
    """An operation exceeded its timeout."""

class InvalidSelectorError(XA11yError):
    """The selector string has invalid syntax."""

class PlatformError(XA11yError):
    """An OS-level accessibility error occurred."""

# ── Data Classes ─────────────────────────────────────────────────────────────

class Rect:
    """A bounding rectangle in screen coordinates (pixels)."""

    @property
    def x(self) -> int: ...
    @property
    def y(self) -> int: ...
    @property
    def width(self) -> int: ...
    @property
    def height(self) -> int: ...
    def __repr__(self) -> str: ...
    def __eq__(self, other: object) -> bool: ...

# ── EventType ────────────────────────────────────────────────────────────────

class EventType:
    """Accessibility event type constants."""

    FOCUS_CHANGED: str
    VALUE_CHANGED: str
    NAME_CHANGED: str
    STATE_CHANGED: str
    STRUCTURE_CHANGED: str
    WINDOW_OPENED: str
    WINDOW_CLOSED: str
    WINDOW_ACTIVATED: str
    WINDOW_DEACTIVATED: str
    SELECTION_CHANGED: str
    MENU_OPENED: str
    MENU_CLOSED: str
    ALERT: str
    TEXT_CHANGED: str

# ── Event ────────────────────────────────────────────────────────────────────

class Event:
    """An accessibility event delivered to subscribers."""

    @property
    def event_type(self) -> str: ...
    @property
    def app_name(self) -> str: ...
    @property
    def app_pid(self) -> int: ...
    @property
    def target(self) -> Element | None: ...
    def __repr__(self) -> str: ...

# ── Subscription ─────────────────────────────────────────────────────────────

class Subscription:
    """A live event subscription."""

    def try_recv(self) -> Event | None: ...
    def recv(self, timeout: float = 5.0) -> Event: ...
    def wait_for(
        self,
        predicate: Callable[[Event], bool],
        timeout: float = 5.0,
    ) -> Event: ...
    def close(self) -> None: ...
    def __enter__(self) -> Subscription: ...
    def __exit__(
        self,
        exc_type: type[BaseException] | None,
        exc_val: BaseException | None,
        exc_tb: TracebackType | None,
    ) -> bool: ...
    def __iter__(self) -> Iterator[Event]: ...
    def __next__(self) -> Event: ...
    def __repr__(self) -> str: ...

# ── Element ───────────────────────────────────────────────────────────────────

class Element:
    """A live element with lazy navigation."""

    @property
    def role(self) -> str: ...
    @property
    def name(self) -> str | None: ...
    @property
    def value(self) -> str | None: ...
    @property
    def description(self) -> str | None: ...
    @property
    def numeric_value(self) -> float | None: ...
    @property
    def min_value(self) -> float | None: ...
    @property
    def max_value(self) -> float | None: ...
    @property
    def stable_id(self) -> str | None: ...
    @property
    def pid(self) -> int | None: ...
    @property
    def actions(self) -> list[str]: ...
    @property
    def bounds(self) -> Rect | None: ...
    @property
    def enabled(self) -> bool: ...
    @property
    def visible(self) -> bool: ...
    @property
    def focused(self) -> bool: ...
    @property
    def checked(self) -> str | None: ...
    @property
    def selected(self) -> bool: ...
    @property
    def expanded(self) -> bool | None: ...
    @property
    def editable(self) -> bool: ...
    @property
    def focusable(self) -> bool: ...
    @property
    def modal(self) -> bool: ...
    @property
    def required(self) -> bool: ...
    @property
    def busy(self) -> bool: ...
    def children(self) -> list[Element]:
        """Get direct children (lazy — each call queries the provider)."""
    def parent(self) -> Element | None:
        """Get parent element (lazy — each call queries the provider)."""
    def locator(self, selector: str) -> Locator:
        """Create a Locator scoped to this element's subtree."""
    def subscribe(self) -> Subscription:
        """Subscribe to accessibility events for this element (typically an app)."""
    def __repr__(self) -> str: ...
    def __str__(self) -> str: ...

# ── Locator ──────────────────────────────────────────────────────────────

class Locator:
    """A resilient element reference that re-queries on each interaction."""

    @property
    def selector(self) -> str: ...
    def nth(self, n: int) -> Locator: ...
    def first(self) -> Locator: ...
    def child(self, selector: str) -> Locator: ...
    def descendant(self, selector: str) -> Locator: ...
    def exists(self) -> bool: ...
    def count(self) -> int: ...
    def element(self) -> Element: ...
    def elements(self) -> list[Element]: ...
    def press(self) -> None: ...
    def focus(self) -> None: ...
    def blur(self) -> None: ...
    def toggle(self) -> None: ...
    def expand(self) -> None: ...
    def collapse(self) -> None: ...
    def select(self) -> None: ...
    def show_menu(self) -> None: ...
    def scroll_into_view(self) -> None: ...
    def increment(self) -> None: ...
    def decrement(self) -> None: ...
    def set_value(self, value: str) -> None: ...
    def set_numeric_value(self, value: float) -> None: ...
    def type_text(self, text: str) -> None: ...
    def select_text(self, start: int, end: int) -> None: ...
    def scroll_up(self, amount: float = 1.0) -> None: ...
    def scroll_down(self, amount: float = 1.0) -> None: ...
    def scroll_left(self, amount: float = 1.0) -> None: ...
    def scroll_right(self, amount: float = 1.0) -> None: ...
    def wait_visible(self, timeout: float = 5.0) -> Element: ...
    def wait_attached(self, timeout: float = 5.0) -> Element: ...
    def wait_detached(self, timeout: float = 5.0) -> None: ...
    def wait_enabled(self, timeout: float = 5.0) -> Element: ...
    def wait_hidden(self, timeout: float = 5.0) -> None: ...
    def wait_disabled(self, timeout: float = 5.0) -> Element: ...
    def wait_focused(self, timeout: float = 5.0) -> Element: ...
    def wait_unfocused(self, timeout: float = 5.0) -> Element: ...
    def wait_until(
        self, predicate: Callable[[Element | None], bool], timeout: float = 5.0
    ) -> None: ...
    def __repr__(self) -> str: ...

# ── Module-level functions ───────────────────────────────────────────────────

def locator(selector: str) -> Locator:
    """Create a top-level Locator searching from the system root."""

# ── Test helpers ─────────────────────────────────────────────────────────────

def _make_test_locator() -> Locator: ...
