"""CLI command for trajectory web viewer."""

from pathlib import Path
from typing import Annotated

import typer
from rich.console import Console
from typer import Argument, Option

from harbor.viewer.server import PortInUseError, PortPermissionError, start_server

console = Console(stderr=True)


def parse_port_range(value: str) -> list[int]:
    """Parse port string as single port or range (e.g., '8080' or '8080-8090').

    Returns a list of ports to try in order.
    Range is inclusive on both ends (8080-8090 includes 8090).
    """
    try:
        if "-" in value:
            parts = value.split("-")
            if len(parts) != 2:
                raise typer.BadParameter(
                    f"Invalid port range format: '{value}'. Use 'START-END' (e.g., 8080-8090)."
                )
            start, end = int(parts[0]), int(parts[1])

            if start > end:
                raise typer.BadParameter(
                    f"Start port {start} cannot be higher than end port {end}."
                )
            if not (1 <= start <= 65535) or not (1 <= end <= 65535):
                raise typer.BadParameter("Ports must be between 1 and 65535.")

            return list(range(start, end + 1))
        else:
            port = int(value)
            if not (1 <= port <= 65535):
                raise typer.BadParameter("Port must be between 1 and 65535.")
            return [port]

    except ValueError:
        raise typer.BadParameter(
            f"Invalid port format: '{value}'. Use a number (8080) or range (8080-8090)."
        )


def view_command(
    folder: Annotated[
        Path,
        Argument(
            help="Folder containing job/trial directories with trajectories",
        ),
    ],
    port: Annotated[
        str,
        Option(
            "--port",
            "-p",
            help="Port or port range (e.g., 8080 or 8080-8090)",
        ),
    ] = "8080-8089",
    host: Annotated[
        str,
        Option(
            "--host",
            help="Host to bind the server to",
        ),
    ] = "127.0.0.1",
    no_browser: Annotated[
        bool,
        Option(
            "--no-browser",
            help="Don't open browser automatically",
        ),
    ] = False,
) -> None:
    """Start a web server to browse and view trajectories.

    Scans the specified folder for jobs/trials containing trajectory files
    and serves an interactive web UI for browsing them.

    Example usage:
        harbor view ./jobs
        harbor view ./jobs --port 9000
        harbor view ./jobs --port 8080-8090
        harbor view ./trials --no-browser
    """
    if not folder.exists():
        console.print(f"[red]Error:[/red] Folder not found: {folder}")
        raise SystemExit(1)

    ports = parse_port_range(port)

    try:
        start_server(
            folder=folder.resolve(),
            ports=ports,
            host=host,
            open_browser=not no_browser,
        )
    except PortInUseError as e:
        console.print()
        console.print(f"[red]Error:[/red] {e}")
        if len(ports) == 1:
            console.print(
                f"[dim]Try --port {ports[0] + 1}, "
                f"or use a range like --port {ports[0]}-{ports[0] + 9}[/dim]"
            )
        console.print()
        raise SystemExit(1)
    except PortPermissionError as e:
        console.print()
        console.print(f"[red]Error:[/red] {e}")
        console.print()
        raise SystemExit(1)
