"""
Entry point: ``python -m backend``

Binds 0.0.0.0 and prints every address the dashboard is reachable on, so you can
open it from a phone or tablet on the same Wi-Fi without knowing this machine's
IP in advance.
"""

from __future__ import annotations

import argparse
import sys

from . import netinfo, settings


def main() -> int:
    parser = argparse.ArgumentParser(prog="python -m backend",
                                     description="AGIBOT X2 dashboard server")
    parser.add_argument("--port", type=int, help="HTTP port (default from config.json)")
    parser.add_argument("--host", default=None, help="Bind address (default 0.0.0.0 - all interfaces)")
    parser.add_argument("--robot", default=None, help="Robot host or IP; saved to config.json")
    parser.add_argument("--domain", type=int, default=None, help="ROS_DOMAIN_ID")
    parser.add_argument("--mode", choices=["auto", "ros2", "mock"], default=None,
                        help="Bridge mode: auto (default), ros2 (require rclpy), mock (simulate)")
    parser.add_argument("--reload", action="store_true", help="Auto-reload on source changes")
    args = parser.parse_args()

    updates = {}
    if args.port is not None:
        updates["port"] = args.port
    if args.robot is not None:
        updates["robot_host"] = args.robot
    if args.domain is not None:
        updates["ros_domain_id"] = args.domain
    if args.mode is not None:
        updates["bridge_mode"] = args.mode
    if updates:
        settings.save(updates)

    config = settings.load()
    host = args.host or config["host"]
    port = config["port"]

    try:
        import uvicorn
    except ImportError:
        print("uvicorn is not installed. Run:  pip install -r requirements.txt", file=sys.stderr)
        return 1

    name = config.get("dashboard_name") if config.get("advertise_name") else None
    detail = netinfo.address_detail()

    print()
    print("  AGIBOT X2 Dashboard")
    print("  " + "-" * 52)
    if detail["ip"]:
        print("    Open this from a phone, tablet or laptop:")
        print(f"      http://{detail['ip']}:{port}")
        print(f"      (live {detail['kind'] or 'network'} address on '{detail['adapter']}')")
    else:
        print("    No usable network address right now:")
        print(f"      {detail['reason_text'] or detail['reason']}")
        print("      The dashboard is still running; it will pick the address up")
        print("      automatically when the network comes back.")

    others = [u for u in netinfo.dashboard_urls(port, name)
              if u != f"http://{detail['ip']}:{port}"]
    if others:
        print()
        print("    Also reachable at:")
        for url in others:
            print(f"      {url}")
    print("  " + "-" * 52)
    print(f"    robot host     {config['robot_host'] or '(not set - use the Settings tab)'}")
    print(f"    bridge mode    {config['bridge_mode']}")
    print(f"    ROS_DOMAIN_ID  {config['ros_domain_id']}")
    print("  Open any address above from any device on this network.")
    print(flush=True)

    uvicorn.run(
        "backend.server:app",
        host=host,
        port=port,
        reload=args.reload,
        log_level="info",
        access_log=False,
        # websockets 16.x crashes uvicorn's default WS impl (starlette/anyio
        # "cancel scope" error) -> stuck "Connecting". wsproto is a stable,
        # isolated WS engine that avoids it without touching the shared
        # `websockets` package the voice pipeline depends on.
        ws="wsproto",
    )
    return 0


if __name__ == "__main__":
    raise SystemExit(main())
