"""
工作手机SDK v3.0 - ADB设备路由
直接ADB控制模式（支持模拟器和真机）

所有端点使用 def（非 async def），FastAPI 自动在线程池中执行，
避免同步 ADB shell 命令阻塞事件循环。
"""

from fastapi import APIRouter, HTTPException
from pydantic import BaseModel
from typing import Optional
import sys
import os

sys.path.insert(0, os.path.dirname(os.path.dirname(os.path.abspath(__file__))))
from services.adb_device import adb_manager
from services.ws_hub import ws_hub

router = APIRouter(prefix="/api/v3/adb", tags=["ADB设备控制"])


async def _ws_execute(serial: str, action: str, params: Optional[dict] = None, timeout: int = 30) -> Optional[dict]:
    """ADB 兼容路由兜底：serial 为逻辑 device_id 且 WS 在线时转发到 Agent。"""
    if not ws_hub.is_online(serial):
        return None
    result = await ws_hub.send_command(
        serial,
        {
            "type": "execute",
            "data": {
                "action": action,
                "params": params or {},
            },
        },
        timeout=timeout,
    )
    code = result.get("code", 200)
    return {
        "code": code,
        "message": result.get("message", "success" if code == 200 else "failed"),
        "data": result.get("data", {}),
        "channel_used": "websocket/agent",
    }


def _raise_not_found():
    raise HTTPException(status_code=404, detail="设备不存在")


# ========== 请求模型 ==========

class ClickRequest(BaseModel):
    x: int
    y: int


class ClickTextRequest(BaseModel):
    text: str
    timeout: float = 10


class InputRequest(BaseModel):
    text: str
    clear: bool = True


class SwipeRequest(BaseModel):
    direction: str
    scale: float = 0.5


class AppRequest(BaseModel):
    package: str


class KeyRequest(BaseModel):
    key: str


# ========== 设备管理 ==========

@router.get("/devices")
def list_devices():
    """获取所有ADB设备"""
    devices = adb_manager.list_devices()
    return {"code": 200, "data": devices}


@router.get("/scan")
@router.post("/scan")
def scan_devices():
    """扫描设备（含未授权设备的完整信息）"""
    serials = adb_manager.scan_devices()
    all_devices = adb_manager.scan_all_devices()
    return {
        "code": 200,
        "data": {
            "devices": serials,
            "all_devices": all_devices,
            "authorized_count": len(serials),
            "total_count": len(all_devices),
        },
    }


@router.get("/devices/{serial}")
async def get_device_info(serial: str):
    """获取设备详情"""
    device = adb_manager.get_device(serial)
    if not device:
        info = ws_hub.get_device_info(serial)
        if info:
            return {"code": 200, "data": {**info, "channel_used": "websocket/agent"}}
        _raise_not_found()

    info = device.get_info()
    info["status"] = "online" if device.is_online() else "offline"
    return {"code": 200, "data": info}


# ========== 基础操作 ==========

@router.post("/devices/{serial}/screenshot")
async def screenshot(serial: str):
    """截图"""
    device = adb_manager.get_device(serial)
    if not device:
        result = await _ws_execute(serial, "screenshot", timeout=12)
        if result:
            return result
        _raise_not_found()

    return device.screenshot()


@router.post("/devices/{serial}/click")
async def click(serial: str, req: ClickRequest):
    """点击坐标"""
    device = adb_manager.get_device(serial)
    if not device:
        result = await _ws_execute(serial, "click", {"x": req.x, "y": req.y})
        if result:
            return result
        _raise_not_found()

    return device.click(req.x, req.y)


@router.post("/devices/{serial}/click-text")
async def click_text(serial: str, req: ClickTextRequest):
    """点击文字"""
    device = adb_manager.get_device(serial)
    if not device:
        result = await _ws_execute(serial, "click_text", {"text": req.text, "timeout": req.timeout})
        if result:
            return result
        _raise_not_found()

    return device.click_text(req.text, req.timeout)


@router.post("/devices/{serial}/input")
async def input_text(serial: str, req: InputRequest):
    """输入文字"""
    device = adb_manager.get_device(serial)
    if not device:
        result = await _ws_execute(serial, "input", {"text": req.text, "clear": req.clear})
        if result:
            return result
        _raise_not_found()

    return device.input_text(req.text, req.clear)


@router.post("/devices/{serial}/swipe")
async def swipe(serial: str, req: SwipeRequest):
    """滑动"""
    device = adb_manager.get_device(serial)
    if not device:
        result = await _ws_execute(serial, "swipe", {"direction": req.direction, "scale": req.scale})
        if result:
            return result
        _raise_not_found()

    return device.swipe(req.direction, req.scale)


@router.post("/devices/{serial}/key")
async def press_key(serial: str, req: KeyRequest):
    """按键"""
    device = adb_manager.get_device(serial)
    if not device:
        result = await _ws_execute(serial, "press_key", {"key": req.key})
        if result:
            return result
        _raise_not_found()

    return device.press_key(req.key)


# ========== APP操作 ==========

@router.post("/devices/{serial}/app/start")
async def start_app(serial: str, req: AppRequest):
    """启动APP"""
    device = adb_manager.get_device(serial)
    if not device:
        result = await _ws_execute(serial, "app_start", {"package": req.package}, timeout=45)
        if result:
            return result
        _raise_not_found()

    return device.start_app(req.package)


@router.post("/devices/{serial}/app/stop")
async def stop_app(serial: str, req: AppRequest):
    """停止APP"""
    device = adb_manager.get_device(serial)
    if not device:
        result = await _ws_execute(serial, "app_stop", {"package": req.package}, timeout=45)
        if result:
            return result
        _raise_not_found()

    return device.stop_app(req.package)


@router.get("/devices/{serial}/app/current")
async def current_app(serial: str):
    """获取当前APP"""
    device = adb_manager.get_device(serial)
    if not device:
        result = await _ws_execute(serial, "get_foreground", timeout=15)
        if result:
            return result
        _raise_not_found()

    return device.current_app()


@router.get("/devices/{serial}/app/list")
def list_apps(serial: str):
    """获取已安装APP"""
    device = adb_manager.get_device(serial)
    if not device:
        raise HTTPException(status_code=404, detail="设备不存在")

    return device.installed_apps()


# ========== UI ==========

@router.get("/devices/{serial}/ui-tree")
async def get_ui_tree(serial: str):
    """获取UI树（XML 已做 JSON-safe 转义）"""
    device = adb_manager.get_device(serial)
    if not device:
        result = await _ws_execute(serial, "ui_tree", timeout=20)
        if result:
            xml = result.get("data", {}).get("xml", "")
            if isinstance(xml, str):
                result["data"]["xml"] = xml.replace("\x00", "").replace("\r", "")
            return result
        _raise_not_found()

    result = device.get_ui_tree()
    if isinstance(result, dict) and "data" in result:
        xml = result["data"].get("xml", "")
        if isinstance(xml, str):
            result["data"]["xml"] = xml.replace("\x00", "").replace("\r", "")
    return result
