from typing import Any, Dict, List, Optional, Tuple, Union
from typing import TYPE_CHECKING
if TYPE_CHECKING:
    from PIL import Image as PILImage
from .selector import UiObject
from .types import DeviceInfo, DiscoveredDevice, OcrResult, ProjectInfo, FileInfo, ShellResponse
from .adb import AdbClient

class Screenshot: ...

class Device:
    @property
    def device_info(self) -> Any: ...

    @property
    def info(self) -> Any: ...

    @property
    def serial(self) -> Any: ...

    @property
    def settings(self) -> Any: ...

    @property
    def wlan_ip(self) -> Any: ...

    def __call__(self, **kwargs) -> 'UiObject':
        """
        创建 UI 元素选择器
        
        Example:
            >>> d(text="Settings").click()
            >>> d(resourceId="com.example:id/btn", clickable=True).wait(timeout=10)
            >>> d(className="android.widget.EditText").set_text("hello")
        """
        ...

    def __enter__(self) -> "'Device'":
        ...

    def __exit__(self, *args) -> 'None':
        ...

    def __init__(self, host: 'str' = '127.0.0.1', port: 'int' = 61140, serial: 'Optional[str]' = None, adb=None) -> None:
        """
        Initialize self.  See help(type(self)) for accurate signature.
        """
        ...

    def __repr__(self) -> 'str':
        """
        Return repr(self).
        """
        ...

    def adb_shell(self, cmd: 'str') -> 'ShellResponse':
        """
        通过 ADB 执行 Shell 命令（不需要引擎运行）
        
        仅在 USB 连接模式下可用。
        """
        ...

    def alive(self) -> 'bool':
        """
        检测引擎是否可达
        """
        ...

    def app_clear(self, package: 'str') -> 'None':
        """
        清除指定应用的数据缓存
        """
        ...

    def app_current(self) -> 'Dict[str, str]':
        """
        获取当前前台应用信息
        """
        ...

    def app_info(self, package: 'str') -> 'Dict':
        """
        获取应用详细信息（通过 dumpsys package）
        """
        ...

    def app_install(self, apk_path: 'str') -> 'None':
        """
        安装 APK（设备本地路径）
        """
        ...

    def app_list(self, filter: 'Optional[str]' = None) -> 'List[str]':
        """
        列出已安装的非系统应用包名
        """
        ...

    def app_running(self, package: 'str') -> 'bool':
        """
        检查应用是否在运行
        """
        ...

    def app_start(self, package: 'str', activity: 'Optional[str]' = None, stop: 'bool' = False) -> 'None':
        """
        启动应用
        """
        ...

    def app_stop(self, package: 'str') -> 'None':
        """
        强制停止应用
        """
        ...

    def app_uninstall(self, package: 'str') -> 'None':
        """
        卸载应用
        """
        ...

    def app_wait(self, package: 'str', timeout: 'float' = 20) -> 'bool':
        """
        等待应用出现在前台
        """
        ...

    def bring_to_top(self, package: 'str') -> 'bool':
        """
        将指定应用移到前台
        """
        ...

    def clear_text(self) -> 'None':
        """
        清空当前输入框（全选 + 删除）
        """
        ...

    def click(self, x: 'int', y: 'int', count: 'int' = 1, interval: 'int' = 50) -> 'None':
        """
        点击指定坐标
        
        Args:
            x, y: 坐标
            count: 点击次数
            interval: 连续点击间隔 (毫秒)
        """
        ...

    def click_double(self, x: 'int', y: 'int') -> 'None':
        """
        双击坐标（与 double_click 等同，保持与引擎脚本 API 一致）
        """
        ...

    def click_scaled(self, x: 'int', y: 'int', base_w: 'int' = 1080, base_h: 'int' = 2400) -> 'None':
        """
        分辨率自适应点击 — 传入基准分辨率坐标, 自动换算到当前设备
        
        Args:
            x, y: 基准分辨率下的 x, y 坐标
            base_w, base_h: 基准屏幕宽高
        """
        ...

    def click_target(self, t: 'Any') -> 'None':
        """
        点击识别目标对象的中心点 (支持 ResOcr / ResYolo / ResFindImage)
        """
        ...

    def color_at_points(self, points: 'List[Tuple[int, int]]') -> 'List[Tuple[int, int, int]]':
        """
        批量获取多个坐标点的像素颜色
        
        Args:
            points: 坐标点列表 [(x1,y1), (x2,y2), ...]
        
        Returns:
            对应的 RGB 颜色列表 [(r,g,b), ...]
        """
        ...

    def disconnect(self) -> 'None':
        """
        断开连接（清理端口转发等资源）
        """
        ...

    def double_click(self, x: 'int', y: 'int') -> 'None':
        """
        双击指定坐标
        """
        ...

    def drag(self, fx: 'int', fy: 'int', tx: 'int', ty: 'int', duration: 'float' = 0.5) -> 'None':
        """
        拖拽（从起点按住滑到终点）
        """
        ...

    def dump_hierarchy(self, compressed: 'bool' = False) -> 'str':
        """
        获取 UI 控件树 XML
        """
        ...

    def engine_info(self) -> 'Dict[str, Any]':
        """
        获取引擎基本信息
        """
        ...

    def file_exists(self, path: 'str') -> 'bool':
        """
        检查文件或目录是否存在
        """
        ...

    def file_last_modified(self, path: 'str') -> 'float':
        """
        获取文件最后修改时间戳（Unix 秒）
        """
        ...

    def find_color(self, rgb: 'str', points: 'str' = '', threshold: 'int' = 3, max_counts: 'int' = 3) -> 'str':
        """
        多色找色
        
        Args:
            rgb: 主色 RGB 字符串，如 "255,0,0"
            points: 偏移点和颜色（换行分隔），与 ExportApi 格式相同
            threshold: 颜色容差
            max_counts: 最多返回数量
        
        Returns:
            找色结果字符串（与 ExportApi 原始格式相同）
        """
        ...

    def find_image(self, template: 'str', threshold: 'float' = 0.8) -> 'Optional[Tuple[int, int]]':
        """
        模板匹配 — 在屏幕上查找图片
        
        Args:
            template: 模板图片路径（设备本地路径）；多个模板用 ; 分隔
            threshold: 匹配阈值 (0~1)
        
        Returns:
            匹配中心坐标 (x, y)，未找到返回 None
        """
        ...

    def foreground(self) -> 'Dict[str, str]':
        """
        获取当前前台应用信息
        
        Returns:
            {"package": "com.xxx", "activity": ".MainActivity"}
        """
        ...

    def foreground_package(self) -> 'str':
        """
        获取当前前台应用包名
        """
        ...

    def freeze_rotation(self, freeze: 'bool' = True) -> 'None':
        """
        冻结/解冻屏幕旋转
        """
        ...

    def gesture(self, points: 'list[tuple[int, int]]', duration: 'int' = 500) -> 'None':
        """
        执行手势轨迹
        
        Args:
            points: 坐标点列表 [(x1, y1), (x2, y2), ...]
            duration: 手势总时长 (毫秒)
        """
        ...

    def get_touch_mode(self) -> 'Dict[str, Any]':
        """
        获取当前触控模式
        """
        ...

    def healthcheck(self) -> 'Dict[str, Any]':
        """
        健康检查，返回引擎状态
        """
        ...

    def http_get(self, url: 'str') -> 'str':
        """
        在设备端发起 HTTP GET 请求
        """
        ...

    def image_ocr(self, path: 'str') -> 'List[OcrResult]':
        """
        对设备上的图片文件进行 OCR 识别
        """
        ...

    def is_net_online(self) -> 'bool':
        """
        检查设备网络是否连通
        """
        ...

    def key_back(self) -> 'None':
        """
        注入返回键
        """
        ...

    def key_code(self, code: 'int') -> 'None':
        """
        按下指定 Android KeyCode
        
        Args:
            code: Android KeyCode 整数值
        """
        ...

    def key_confirm(self) -> 'None':
        """
        模拟回车/确认键（常用于提交表单）
        """
        ...

    def key_home(self) -> 'None':
        """
        注入 Home 键
        """
        ...

    def key_menu(self) -> 'None':
        """
        注入菜单键
        """
        ...

    def list_files(self, path: 'str' = '/sdcard') -> 'List[FileInfo]':
        """
        列出目录内容
        
        Args:
            path: 设备目录路径
        
        Returns:
            文件信息列表
        """
        ...

    def list_projects(self) -> 'List[ProjectInfo]':
        """
        列出设备上的脚本项目
        """
        ...

    def long_click(self, x: 'int', y: 'int', duration: 'float' = 0.5) -> 'None':
        """
        长按指定坐标
        
        Args:
            x, y: 坐标
            duration: 按住时长（秒）
        """
        ...

    def long_press(self, x: 'int', y: 'int', duration: 'int' = 500) -> 'None':
        """
        长按指定坐标
        
        Args:
            x, y: 坐标
            duration: 按住时长 (毫秒)
        """
        ...

    def media_scan(self, path: 'str') -> 'None':
        """
        通知系统媒体扫描（用于使新增图片出现在相册）
        """
        ...

    def media_scan_file(self, path: 'str') -> 'bool':
        """
        通知安卓系统扫描新文件, 多个路径以分号分隔
        """
        ...

    def mkdir(self, path: 'str') -> 'None':
        """
        创建目录（递归创建）
        """
        ...

    def multi_click(self, x: 'int', y: 'int', count: 'int' = 2, interval: 'int' = 100) -> 'None':
        """
        多次点击指定坐标（在设备端直接连续执行，比 Python 侧循环更精准）
        
        Args:
            x, y: 坐标
            count: 点击次数
            interval: 每次点击间隔（毫秒）
        """
        ...

    def ocr(self, image: 'Optional[str]' = None, x: 'Optional[float]' = None, y: 'Optional[float]' = None, w: 'Optional[float]' = None, h: 'Optional[float]' = None, use_gpu: 'bool' = False) -> 'List[OcrResult]':
        """
        屏幕 或 图片 OCR 识别
        
        Args:
            image: 图片路径, None 则截屏识别
            x, y, w, h: 识别区域 (0-1 相对坐标 或 像素坐标)
            use_gpu: 是否使用 GPU 加速 (手机端支持)
            
        Returns:
            OCR 结果列表
        """
        ...

    def ocr_click(self, text: 'str', timeout: 'float' = 10, x: 'Optional[float]' = None, y: 'Optional[float]' = None, w: 'Optional[float]' = None, h: 'Optional[float]' = None, use_gpu: 'bool' = False) -> 'bool':
        """
        OCR 查找文字并点击
        """
        ...

    def ocr_click_if_found(self, *texts: 'str', x: 'Optional[float]' = None, y: 'Optional[float]' = None, w: 'Optional[float]' = None, h: 'Optional[float]' = None, use_gpu: 'bool' = False) -> 'bool':
        """
        如果所有文字都存在, 点击最后一个文字
        """
        ...

    def ocr_exists_all(self, *texts: 'str', x: 'Optional[float]' = None, y: 'Optional[float]' = None, w: 'Optional[float]' = None, h: 'Optional[float]' = None, use_gpu: 'bool' = False) -> 'bool':
        """
        判断所有文字是否都存在
        """
        ...

    def ocr_find(self, text: 'str', x: 'Optional[float]' = None, y: 'Optional[float]' = None, w: 'Optional[float]' = None, h: 'Optional[float]' = None, use_gpu: 'bool' = False) -> 'Optional[OcrResult]':
        """
        查找屏幕上的文字
        
        Args:
            text: 要查找的文字 (正则)
            x, y, w, h: 搜索区域
        """
        ...

    def ocr_wait(self, text: 'str', timeout: 'float' = 10, x: 'Optional[float]' = None, y: 'Optional[float]' = None, w: 'Optional[float]' = None, h: 'Optional[float]' = None, use_gpu: 'bool' = False) -> 'bool':
        """
        等待屏幕上出现指定文字
        """
        ...

    def open_url(self, url: 'str') -> 'None':
        """
        用系统浏览器打开 URL
        """
        ...

    def pid(self) -> 'int':
        """
        获取引擎进程 PID
        """
        ...

    def pixel_color(self, x: 'int', y: 'int') -> 'Tuple[int, int, int]':
        """
        获取指定坐标的像素颜色
        
        Returns:
            (R, G, B) 元组，值范围 0-255
        """
        ...

    def press(self, key: 'str') -> 'None':
        """
        按下按键
        
        Args:
            key: 按键名称（如 "home", "back", "enter", "volume_up"）
                 或 Android KeyCode 数字字符串
        """
        ...

    def project_status(self, name: 'Optional[str]' = None) -> 'Optional[Dict]':
        """
        获取项目运行状态
        
        Args:
            name: 项目名称，None 则返回当前运行项目状态
        
        Returns:
            状态 dict，或 None（无项目运行）
        """
        ...

    def pull(self, remote: 'str', local: 'str') -> 'None':
        """
        从设备拉取文件到 PC 本地
        
        Args:
            remote: 设备文件完整路径
            local:  PC 端保存路径（含文件名）
        
        Example:
            >>> d.pull("/sdcard/log.txt", "C:/log.txt")
        """
        ...

    def pull_dir(self, remote_dir: 'str', local_dir: 'str') -> 'int':
        """
        从设备拉取目录到 PC（需要目录内的文件列表）
        
        Args:
            remote_dir: 设备目录路径
            local_dir:  PC 端目标目录
        
        Returns:
            已拉取文件数量
        """
        ...

    def push(self, local: 'str', remote: 'str') -> 'None':
        """
        推送 PC 本地文件到设备
        
        Args:
            local:  PC 端本地文件路径
            remote: 设备目标完整路径（含文件名）
        
        Example:
            >>> d.push("C:/test.py", "/sdcard/test.py")
        """
        ...

    def push_dir(self, local_dir: 'str', remote_dir: 'str') -> 'int':
        """
        递归推送本地目录到设备
        
        Args:
            local_dir:  PC 端本地目录路径
            remote_dir: 设备目标目录路径
        
        Returns:
            已推送文件数量
        """
        ...

    def random_click(self, x: 'int', y: 'int', w: 'int', h: 'int') -> 'None':
        """
        在指定矩形区域内随机点击 (模拟人工操作, 防检测)
        
        Args:
            x, y: 基础坐标 x, y
            w, h: 横向、纵向随机偏移范围 (像素)
        """
        ...

    def random_sleep(self, a: 'int', b: 'int') -> 'None':
        """
        随机休眠 [a, be] 秒 (兼容引擎脚本API)
        """
        ...

    def read_file(self, path: 'str') -> 'str':
        """
        读取设备上的文本文件
        """
        ...

    def reboot_engine(self) -> 'None':
        """
        重启引擎
        """
        ...

    def remove(self, path: 'str') -> 'None':
        """
        删除文件或目录
        """
        ...

    def rename(self, old_path: 'str', new_name: 'str') -> 'Optional[str]':
        """
        重命名文件或目录
        
        Args:
            old_path: 原路径
            new_name: 新文件名（不含路径）
        
        Returns:
            新路径，失败返回 None
        """
        ...

    def run_code(self, code: 'str', timeout: 'float' = 30) -> 'str':
        """
        在设备上执行 Python 代码片段
        
        Args:
            code: Python 代码（print() 输出会被捕获返回）
            timeout: 超时秒数
        
        Returns:
            stdout 输出文本
        """
        ...

    def screen_info(self) -> 'Dict[str, int]':
        """
        获取屏幕宽高信息
        
        Returns:
            {"width": 1080, "height": 2340}
        """
        ...

    def screen_ocr_first_x(self, specific_texts: 'Optional[List[str]]' = None, x: 'Optional[float]' = None, y: 'Optional[float]' = None, w: 'Optional[float]' = None, h: 'Optional[float]' = None, use_gpu: 'bool' = False) -> 'Optional[OcrResult]':
        """
        高级找字 — 仅返回第一个匹配结果
        """
        ...

    def screen_ocr_x(self, specific_texts: 'Optional[List[str]]' = None, x: 'Optional[float]' = None, y: 'Optional[float]' = None, w: 'Optional[float]' = None, h: 'Optional[float]' = None, use_gpu: 'bool' = False) -> 'List[OcrResult]':
        """
        高级找字 — 返回匹配指定文字的结果 (支持正则)
        """
        ...

    def screen_off(self) -> 'None':
        """
        熄灭屏幕
        """
        ...

    def screen_on(self) -> 'None':
        """
        点亮屏幕
        """
        ...

    def screenshot(self, filename: 'Optional[str]' = None, quality: 'int' = 80) -> "Union[Any, Any]":
        """
        截图
        """
        ...

    def screenshot_bytes(self, quality: 'int' = 80) -> 'bytes':
        """
        截图，返回原始 JPEG 字节
        """
        ...

    def send_keys(self, text: 'str', clear: 'bool' = False) -> 'None':
        """
        输入文本（通过系统 InputManager 注入，兼容英文）
        
        Args:
            text: 要输入的文本
            clear: 是否先清空输入框
        """
        ...

    def set_clipboard(self, text: 'str') -> 'None':
        """
        设置剪贴板内容
        """
        ...

    def set_touch_mode(self, mode: 'str' = 'auto') -> 'Dict[str, Any]':
        """
        设置触控模式
        """
        ...

    def set_yy_input(self, enable: 'bool' = True) -> 'None':
        """
        切换 YY 输入法
        
        Args:
            enable: True 启用 YY 输入法，False 恢复系统输入法
        """
        ...

    def shell(self, cmd: 'str', timeout: 'float' = 15) -> 'ShellResponse':
        """
        在设备上执行 Shell 命令（通过引擎，ROOT/SHELL 权限）
        
        Args:
            cmd: Shell 命令
            timeout: 超时秒数
        
        Returns:
            ShellResponse(output, exit_code)
        
        Example:
            >>> d.shell("ls /sdcard").output
            >>> d.shell("whoami")  # 返回 root 或 shell
        """
        ...

    def sleep_ms(self, ms: 'int') -> 'None':
        """
        在设备端休眠（不受网络延迟影响，更精准）
        
        Args:
            ms: 休眠毫秒数
        """
        ...

    def start_project(self, name: 'str') -> 'None':
        """
        启动脚本项目
        """
        ...

    def stop_project(self) -> 'None':
        """
        停止当前运行的脚本项目
        """
        ...

    def swipe(self, fx: 'int', fy: 'int', tx: 'int', ty: 'int', duration: 'float' = 0.5) -> 'None':
        """
        从 (fx, fy) 滑动到 (tx, ty)
        
        Args:
            fx, fy: 起点坐标
            tx, ty: 终点坐标
            duration: 滑动时长（秒）
        """
        ...

    def swipe_down(self, scale: 'float' = 0.8) -> 'None':
        """
        向下滑动屏幕
        """
        ...

    def swipe_ext(self, direction: 'str', scale: 'float' = 0.8) -> 'None':
        """
        扩展滑动 — 按方向滑动屏幕
        
        Args:
            direction: "up", "down", "left", "right"
            scale: 滑动距离占屏幕比例 (0~1)
        """
        ...

    def swipe_left(self, scale: 'float' = 0.8) -> 'None':
        """
        向左滑动屏幕
        """
        ...

    def swipe_right(self, scale: 'float' = 0.8) -> 'None':
        """
        向右滑动屏幕
        """
        ...

    def swipe_up(self, scale: 'float' = 0.8) -> 'None':
        """
        向上滑动屏幕
        """
        ...

    def toast(self, text: 'str') -> 'None':
        """
        在设备屏幕上显示 Toast 提示
        """
        ...

    def toast_print(self, text: 'str') -> 'None':
        """
        打印文本到控制台并弹出toast
        """
        ...

    def touch_down(self, x: 'int', y: 'int') -> 'None':
        """
        按下触摸（低层级 API）
        """
        ...

    def touch_move(self, x: 'int', y: 'int') -> 'None':
        """
        移动触摸点（低层级 API）
        """
        ...

    def touch_up(self, x: 'int', y: 'int') -> 'None':
        """
        抬起触摸（低层级 API）
        """
        ...

    def ui_exist(self, **match_params) -> 'bool':
        """
        检查符合条件的控件是否存在
        """
        ...

    def ui_match(self, all_window: 'bool' = False, match_from_cache: 'bool' = False, limit: 'int' = 9999, **match_params) -> "List['UiObject']":
        """
        扫描屏幕 UI 控件并匹配
        
        Args:
            all_window: 是否查找所有窗口 (含悬浮窗)
            match_from_cache: 是否从缓存匹配
            limit: 最大返回数量
            **match_params: 匹配参数 (text, res, desc, cls, pkg...)
        """
        ...

    def update_language(self, code: 'str') -> 'bool':
        """
        设置安卓系统语言, 如 "en-us" 
        """
        ...

    def version(self) -> 'str':
        """
        获取 yyds.auto 引擎版本号
        """
        ...

    def wait_for_image(self, template: 'str', timeout: 'float' = 10, interval: 'float' = 1.0, threshold: 'float' = 0.8) -> 'Optional[Tuple[int, int]]':
        """
        等待屏幕出现指定图片
        """
        ...

    def wait_for_text(self, *texts: 'str', timeout: 'float' = 10, x: 'Optional[float]' = None, y: 'Optional[float]' = None, w: 'Optional[float]' = None, h: 'Optional[float]' = None, use_gpu: 'bool' = False) -> 'bool':
        """
        等待屏幕上出现指定文字 (ocr_wait 的别名)
        """
        ...

    def wait_for_ui(self, timeout: 'float' = 10, interval: 'float' = 0.5, **match_params) -> "Optional['UiObject']":
        """
        等待屏幕出现符合条件的 UI 控件
        """
        ...

    def wait_screen_change(self, timeout: 'float' = 10, interval: 'float' = 0.3, threshold: 'float' = 0.95) -> 'bool':
        """
        等待屏幕发生变化
        """
        ...

    def wait_screen_stable(self, stable_duration: 'float' = 1.0, timeout: 'float' = 10, interval: 'float' = 0.3, threshold: 'float' = 0.98) -> 'bool':
        """
        等待屏幕稳定
        """
        ...

    def window_size(self) -> 'Tuple[int, int]':
        """
        获取屏幕尺寸 (width, height)
        """
        ...

    def write_file(self, path: 'str', content: 'str') -> 'None':
        """
        写入文本文件到设备
        """
        ...

    def x_clear_text(self) -> 'None':
        """
        通过 YY 输入法清空当前输入框
        """
        ...

    def x_send_keys(self, text: 'str', clear: 'bool' = False) -> 'None':
        """
        通过 YY 输入法输入文本（推荐，兼容中文及特殊字符）
        
        Args:
            text: 要输入的文本
            clear: 是否先清空输入框
        """
        ...
