"""Daemon management CLI commands."""

import os
from pathlib import Path

import typer

from fliiq.cli import display
from fliiq.runtime.scheduler.daemon_utils import (
    default_port,
    is_process_alive,
    read_pid,
    stop_daemon,
)

daemon_app = typer.Typer(help="Manage the Fliiq daemon")


def _fliiq_dir() -> Path:
    from fliiq.runtime.config import resolve_fliiq_dir

    try:
        return resolve_fliiq_dir(require_local=True)
    except FileNotFoundError:
        display.print_error("Daemon requires a local .fliiq/ directory. Run `fliiq init --project` first.")
        raise typer.Exit(1)


@daemon_app.command("start")
def start(
    port: int = typer.Option(None, "--port", help="Port (default: 7890 or FLIIQ_DAEMON_PORT)"),
    foreground: bool = typer.Option(False, "--foreground", help="Run in foreground (debug)"),
):
    """Start the Fliiq daemon."""
    from fliiq.runtime.scheduler.daemon_utils import ensure_daemon_running

    fliiq_dir = _fliiq_dir()
    project_root = fliiq_dir.parent
    effective_port = port or default_port()

    # Check if already running
    pid = read_pid(project_root)
    if pid and is_process_alive(pid):
        display.print_error(f"Daemon already running (PID: {pid})")
        raise typer.Exit(1)

    if foreground:
        import uvicorn

        os.environ["FLIIQ_PROJECT_ROOT"] = str(project_root)
        uvicorn.run("fliiq.api.server:app", host="127.0.0.1", port=effective_port, log_level="info")
        return

    # Background mode — delegate to shared helper
    ok = ensure_daemon_running(project_root, port=effective_port)
    if ok:
        pid = read_pid(project_root)
        display.console.print(f"Daemon started (PID: {pid}, port: {effective_port})")
    else:
        log_path = fliiq_dir / "daemon.log"
        display.print_error(f"Daemon failed to start. Check {log_path}")
        raise typer.Exit(1)


@daemon_app.command("stop")
def stop():
    """Stop the Fliiq daemon."""
    project_root = _fliiq_dir().parent

    pid = read_pid(project_root)
    if pid is None:
        display.console.print("Daemon not running.")
        return

    if not is_process_alive(pid):
        pid_path = project_root / ".fliiq" / "daemon.pid"
        pid_path.unlink(missing_ok=True)
        display.console.print("Daemon not running (stale PID file removed).")
        return

    stop_daemon(project_root)
    display.console.print("Daemon stopped.")


@daemon_app.command("restart")
def restart(
    port: int = typer.Option(None, "--port", help="Port (default: 7890 or FLIIQ_DAEMON_PORT)"),
):
    """Restart the Fliiq daemon (stop + start)."""
    project_root = _fliiq_dir().parent

    pid = read_pid(project_root)
    if pid and is_process_alive(pid):
        stop_daemon(project_root)
        display.console.print("Daemon stopped.")

    # Start fresh
    from fliiq.runtime.scheduler.daemon_utils import ensure_daemon_running

    effective_port = port or default_port()
    ok = ensure_daemon_running(project_root, port=effective_port)
    if ok:
        pid = read_pid(project_root)
        display.console.print(f"Daemon started (PID: {pid}, port: {effective_port})")
    else:
        log_path = project_root / ".fliiq" / "daemon.log"
        display.print_error(f"Daemon failed to start. Check {log_path}")
        raise typer.Exit(1)


@daemon_app.command("status")
def status():
    """Show daemon status."""
    project_root = _fliiq_dir().parent

    pid = read_pid(project_root)
    if pid is None or not is_process_alive(pid):
        display.console.print("Daemon: stopped")
        return

    effective_port = default_port()
    try:
        import httpx

        resp = httpx.get(f"http://127.0.0.1:{effective_port}/health", timeout=2.0)
        data = resp.json()
        uptime = data.get("uptime_s", 0)
        hours, remainder = divmod(uptime, 3600)
        minutes = remainder // 60

        telegram = "active" if data.get("telegram") else "inactive"

        display.console.print("Daemon:    running")
        display.console.print(f"PID:       {pid}")
        display.console.print(f"Port:      {effective_port}")
        display.console.print(f"Uptime:    {hours}h {minutes}m")
        display.console.print(f"Jobs:      {data.get('jobs', 0)}")
        display.console.print(f"Telegram:  {telegram}")
    except Exception:
        display.console.print(f"Daemon: running (PID: {pid}) but health check failed on port {effective_port}")
