"""L1 Backend 抽象层基类：定义 BackendProtocol 与 WindowGeometry。

所有具体后端（xdotool / OpenCV / CDP）均实现 BackendProtocol，
上层 Actions / Flow 通过 Protocol 解耦具体实现，便于切换或回滚。
"""

from __future__ import annotations

from abc import ABC, abstractmethod
from dataclasses import dataclass


@dataclass
class WindowGeometry:
    """窗口几何信息（绝对坐标 + 宽高）。

    所有字段默认值 0，避免构造时必填字段顺序问题。
    """

    x: int = 0
    y: int = 0
    width: int = 0
    height: int = 0


class BackendProtocol(ABC):
    """UI 自动化后端协议（L1 抽象）。

    子类必须实现所有 abstract 方法；capabilities 属性提供该后端
    支持的能力集合（如 click / type / key / screenshot / window）。
    """

    @abstractmethod
    async def click(self, x: int, y: int) -> None:
        """在绝对坐标 (x, y) 处左键单击。"""

    @abstractmethod
    async def type_text(self, text: str) -> None:
        """输入文本（不解析修饰键组合，原样输入）。"""

    @abstractmethod
    async def key_press(self, key: str, repeat: int = 1) -> None:
        """按键，支持 repeat 重复。"""

    @abstractmethod
    async def screenshot(self) -> bytes:
        """截图并返回 PNG 字节流（不落盘）。"""

    @abstractmethod
    async def get_window_geometry(self, window_title: str) -> WindowGeometry:
        """按窗口标题查找窗口并返回几何信息。"""

    @abstractmethod
    async def activate_window(self, window_title: str) -> None:
        """激活指定窗口（使其获得焦点）。"""

    @property
    def capabilities(self) -> set[str]:
        """返回后端支持的能力集合。子类可覆盖。"""
        return {"click", "type", "key", "screenshot", "window"}
