"""触控操作 Mixin — click, swipe, long_press, drag"""

from __future__ import annotations

import time
from typing import TYPE_CHECKING, Optional, Tuple, Union

if TYPE_CHECKING:
    from ..device import Device


class TouchMixin:
    """触控手势"""

    # 由 Device 注入
    _client: ...

    def click(self, x: int, y: int, count: int = 1, interval: int = 50) -> None:
        """点击指定坐标
        
        Args:
            x, y: 坐标
            count: 点击次数
            interval: 连续点击间隔 (毫秒)
        """
        self._client.auto_api("/touch", {"x": str(x), "y": str(y), "time": str(count), "interval": str(interval)})

    def long_press(self, x: int, y: int, duration: int = 500) -> None:
        """长按指定坐标
        
        Args:
            x, y: 坐标
            duration: 按住时长 (毫秒)
        """
        self._client.auto_api("/touch_down", {"x": str(x), "y": str(y)})
        time.sleep(duration / 1000.0)
        self._client.auto_api("/touch_up", {"x": str(x), "y": str(y)})

    def double_click(self, x: int, y: int) -> None:
        """双击指定坐标"""
        self.click(x, y, count=2, interval=100)

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

        Args:
            x, y: 坐标
            count: 点击次数
            interval: 每次点击间隔（毫秒）
        """
        self._client.auto_api("/touch", {"x": str(x), "y": str(y),
                                          "time": str(count), "interval": str(interval)})

    def long_click(self, x: int, y: int, duration: float = 0.5) -> None:
        """长按指定坐标

        Args:
            x, y: 坐标
            duration: 按住时长（秒）
        """
        self._client.auto_api("/touch_down", {"x": str(x), "y": str(y)})
        time.sleep(duration)
        self._client.auto_api("/touch_up", {"x": str(x), "y": str(y)})

    def touch_down(self, x: int, y: int) -> None:
        """按下触摸（低层级 API）"""
        self._client.auto_api("/touch_down", {"x": str(x), "y": str(y)})

    def touch_up(self, x: int, y: int) -> None:
        """抬起触摸（低层级 API）"""
        self._client.auto_api("/touch_up", {"x": str(x), "y": str(y)})

    def touch_move(self, x: int, y: int) -> None:
        """移动触摸点（低层级 API）"""
        self._client.auto_api("/touch_move", {"x": str(x), "y": str(y)})

    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: 滑动时长（秒）
        """
        ms = int(duration * 1000)
        self._client.auto_api("/swipe", {
            "x1": str(fx), "y1": str(fy),
            "x2": str(tx), "y2": str(ty),
            "duration": str(ms),
        })

    def swipe_ext(self, direction: str, scale: float = 0.8) -> None:
        """扩展滑动 — 按方向滑动屏幕

        Args:
            direction: "up", "down", "left", "right"
            scale: 滑动距离占屏幕比例 (0~1)
        """
        w, h = self.window_size()  # type: ignore
        cx, cy = w // 2, h // 2
        dist_x = int(w * scale / 2)
        dist_y = int(h * scale / 2)

        mapping = {
            "up": (cx, cy + dist_y, cx, cy - dist_y),
            "down": (cx, cy - dist_y, cx, cy + dist_y),
            "left": (cx + dist_x, cy, cx - dist_x, cy),
            "right": (cx - dist_x, cy, cx + dist_x, cy),
        }
        if direction not in mapping:
            raise ValueError(f"direction 必须是 up/down/left/right，收到: {direction}")
        self.swipe(*mapping[direction])

    def gesture(self, points: list[tuple[int, int]], duration: int = 500) -> None:
        """执行手势轨迹
        
        Args:
            points: 坐标点列表 [(x1, y1), (x2, y2), ...]
            duration: 手势总时长 (毫秒)
        """
        if not points:
            return
        ms = int(duration / len(points)) if len(points) > 1 else duration
        self.touch_down(*points[0])
        for p in points[1:]:
            self.touch_move(*p)
            time.sleep(ms / 1000.0)
        self.touch_up(*points[-1])

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

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

        Args:
            ms: 休眠毫秒数
        """
        self._client.auto_api("/sleep", {"ms": str(ms)})

    @property
    def touch(self) -> "_TouchAction":
        """底层触控操作链: d.touch.down(x,y).move(x,y).up()"""
        return _TouchAction(self._client)


class _TouchAction:
    """底层触控操作链"""

    def __init__(self, client):
        self._client = client

    def down(self, x: int, y: int) -> "_TouchAction":
        self._client.auto_api("/touch_down", {"x": str(x), "y": str(y)})
        return self

    def move(self, x: int, y: int) -> "_TouchAction":
        self._client.auto_api("/touch_move", {"x": str(x), "y": str(y)})
        return self

    def up(self, x: int = 0, y: int = 0) -> "_TouchAction":
        self._client.auto_api("/touch_up", {"x": str(x), "y": str(y)})
        return self

    def sleep(self, seconds: float) -> "_TouchAction":
        time.sleep(seconds)
        return self
