"""
设备端 SDK 自动发现 — 监听 UDP beacon（8898），无线主控免手填 IP。

与 sdk/app/services/discovery_service.py BEACON 协议对齐。
"""

from __future__ import annotations

import json
import socket
import time
from typing import Optional

BEACON_PORT = 8898
BEACON_MAGIC = "WORKPHONE_SDK"


def _pick_best_ip(ips: list) -> str:
    """优先 192.168.110.x（工作机常用网段），否则取第一个私网 IP。"""
    for ip in ips:
        if ip.startswith("192.168.110."):
            return ip
    for ip in ips:
        if ip.startswith(("192.168.", "10.", "172.")):
            return ip
    return ips[0]


def discover_sdk_ws_base(timeout: float = 20.0) -> Optional[str]:
    """
    监听局域网 UDP beacon，返回 WebSocket 基础地址。
    例: ws://192.168.110.251:8899/ws/device
    """
    deadline = time.time() + timeout
    sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
    sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
    try:
        sock.bind(("", BEACON_PORT))
    except OSError:
        # Termux 可能无权限绑 8898，改绑任意端口并只 recv
        sock.bind(("", 0))
    sock.settimeout(1.0)

    while time.time() < deadline:
        try:
            data, _addr = sock.recvfrom(4096)
            payload = json.loads(data.decode("utf-8"))
            if payload.get("magic") != BEACON_MAGIC:
                continue
            port = int(payload.get("port") or 8899)
            ws_path = (payload.get("ws_path") or "/ws/device").rstrip("/")
            ips = payload.get("ips") or []
            host = _pick_best_ip(ips) if ips else "127.0.0.1"
            return f"ws://{host}:{port}{ws_path}"
        except socket.timeout:
            continue
        except Exception:
            continue
    return None
