"""Daemon management — start/stop/status for the health monitor."""

from __future__ import annotations

import logging
import os
import signal
import sys
from pathlib import Path

from easyclaw_tui.agent.config import (
    AGENT_DIR,
    LOG_PATH,
    PID_PATH,
    AgentConfig,
)

log = logging.getLogger("foreman.daemon")

SYSTEMD_UNIT = """\
[Unit]
Description=EasyClaw Agent Johnny 5 (Health Monitor)
After=network.target openclaw-gateway.service
Wants=openclaw-gateway.service

[Service]
Type=simple
User=root
Environment=HOME=/root
ExecStart={easyclaw_bin} agent start --foreground
Restart=on-failure
RestartSec=30
StandardOutput=journal
StandardError=journal

[Install]
WantedBy=multi-user.target
"""


def _setup_logging(config: AgentConfig) -> None:
    """Configure file logging with rotation."""
    from logging.handlers import RotatingFileHandler

    AGENT_DIR.mkdir(parents=True, exist_ok=True)

    handler = RotatingFileHandler(
        str(LOG_PATH), maxBytes=5_000_000, backupCount=3
    )
    handler.setFormatter(
        logging.Formatter("%(asctime)s [%(levelname)s] %(name)s: %(message)s")
    )
    root = logging.getLogger("foreman")
    root.setLevel(getattr(logging, config.log_level, logging.INFO))
    root.addHandler(handler)


def _run_monitor(config: AgentConfig) -> None:
    """Run the health monitor (blocking — used in foreground mode or after fork)."""
    import asyncio

    from easyclaw_tui.agent.core import ForemanAgent
    from easyclaw_tui.agent.monitor import HealthMonitor
    from easyclaw_tui.agent.tools import mcp as mcp_tools

    _setup_logging(config)

    if config.api_key:
        mcp_tools.init_mcp(config.api_key)

    # Write PID
    AGENT_DIR.mkdir(parents=True, exist_ok=True)
    PID_PATH.write_text(str(os.getpid()))
    config.daemon_pid = os.getpid()
    config.save()

    def handle_stop(signum: int, frame: object) -> None:
        log.info("Received signal %d, shutting down...", signum)
        PID_PATH.unlink(missing_ok=True)
        sys.exit(0)

    signal.signal(signal.SIGTERM, handle_stop)
    signal.signal(signal.SIGINT, handle_stop)

    agent = ForemanAgent(config)
    monitor = HealthMonitor(agent, config)

    log.info("Agent Johnny 5 daemon started (PID %d)", os.getpid())
    asyncio.run(monitor.run_forever())


def start_daemon(config: AgentConfig, foreground: bool = False) -> None:
    """Start the Foreman daemon."""
    AGENT_DIR.mkdir(parents=True, exist_ok=True)

    # Check if already running
    if PID_PATH.exists():
        try:
            pid = int(PID_PATH.read_text().strip())
            os.kill(pid, 0)
            print(f"Agent Johnny 5 already running (PID {pid})")
            return
        except (ProcessLookupError, ValueError):
            PID_PATH.unlink(missing_ok=True)

    if foreground:
        # Run directly (for systemd)
        print(f"Agent Johnny 5 starting in foreground...")
        _run_monitor(config)
        return

    # Double-fork to daemonize (Linux only)
    try:
        pid = os.fork()
    except AttributeError:
        # Windows/other — fall back to foreground
        print("os.fork() not available. Running in foreground.")
        _run_monitor(config)
        return

    if pid > 0:
        # Parent — wait briefly for PID file
        import time

        time.sleep(1)
        if PID_PATH.exists():
            child_pid = PID_PATH.read_text().strip()
            print(f"Agent Johnny 5 started (PID {child_pid})")
        else:
            print("Agent Johnny 5 starting...")
        return

    # First child — create new session
    os.setsid()

    pid = os.fork()
    if pid > 0:
        os._exit(0)

    # Second child — the actual daemon
    # Redirect stdio
    sys.stdin = open(os.devnull, "r")
    log_file = open(str(LOG_PATH), "a")
    sys.stdout = log_file  # type: ignore[assignment]
    sys.stderr = log_file  # type: ignore[assignment]

    _run_monitor(config)


def stop_daemon() -> None:
    """Stop the running daemon."""
    if not PID_PATH.exists():
        print("No daemon running (no PID file)")
        return

    try:
        pid = int(PID_PATH.read_text().strip())
    except ValueError:
        print("Invalid PID file")
        PID_PATH.unlink(missing_ok=True)
        return

    try:
        os.kill(pid, signal.SIGTERM)
        print(f"Stopped Agent Johnny 5 (PID {pid})")
    except ProcessLookupError:
        print(f"Daemon not running (stale PID {pid})")

    PID_PATH.unlink(missing_ok=True)


def show_status() -> None:
    """Show daemon status."""
    config = AgentConfig.load()

    print(f"\n\033[38;5;214m\033[1mEasyClaw Agent Johnny 5 Status\033[0m\n")
    print(f"  Model:      {config.model}")
    print(f"  MCP tools:  {'enabled' if config.api_key else 'disabled'}")
    print(f"  Config:     {AGENT_DIR / 'agent.json'}")
    print(f"  Log:        {LOG_PATH}")

    # Daemon
    if PID_PATH.exists():
        try:
            pid = int(PID_PATH.read_text().strip())
            os.kill(pid, 0)
            print(f"  Daemon:     \033[32mrunning\033[0m (PID {pid})")
        except (ProcessLookupError, ValueError):
            print(f"  Daemon:     \033[31mstale PID\033[0m")
    else:
        print(f"  Daemon:     \033[2mnot running\033[0m")

    if config.last_health_check:
        print(f"  Last check: {config.last_health_check}")

    print(f"  Interval:   {config.check_interval}s")
    print(f"  Max fixes:  {config.max_auto_fix_attempts}")

    recent = config.recent_actions[-5:]
    if recent:
        print(f"\n  \033[1mRecent Actions:\033[0m")
        for action in recent:
            t = action.get("time", "?")[:19]
            check = action.get("check", "?")
            snippet = action.get("action", "")[:80]
            print(f"    \033[2m{t}\033[0m {check}")
            if snippet:
                print(f"      {snippet}")

    print()


def tail_log(lines: int = 50) -> None:
    """Print the last N lines of the agent log."""
    if not LOG_PATH.exists():
        print("No log file found.")
        return

    all_lines = LOG_PATH.read_text().splitlines()
    for line in all_lines[-lines:]:
        print(line)


def install_systemd() -> None:
    """Generate and install a systemd unit file for the daemon."""
    import shutil

    easyclaw_bin = shutil.which("easyclaw")
    if not easyclaw_bin:
        print("Error: 'easyclaw' not found in PATH. Is easyclaw-tui installed?")
        return

    unit_content = SYSTEMD_UNIT.format(easyclaw_bin=easyclaw_bin)
    unit_path = Path("/etc/systemd/system/easyclaw-foreman.service")

    try:
        unit_path.write_text(unit_content)
        print(f"Installed: {unit_path}")
        print()
        print("To enable and start:")
        print("  systemctl daemon-reload")
        print("  systemctl enable easyclaw-foreman")
        print("  systemctl start easyclaw-foreman")
        print()
        print("To check status:")
        print("  systemctl status easyclaw-foreman")
        print("  journalctl -u easyclaw-foreman -f")
    except PermissionError:
        print("Error: Permission denied. Run as root:")
        print(f"  sudo easyclaw agent systemd")
