"""Daemon entry point — persistent Agent Johnny 5.

Starts three components sharing one AgentBrain:
  1. Health monitor (background thread, no LLM)
  2. HTTP API server (background thread, localhost:8585)
  3. Telegram bot (main async loop, long-polling)

Usage:
    python -m easyclaw_installer --daemon
"""

from __future__ import annotations

import asyncio
import json
import logging
import os
import secrets
import signal
import sys

from ..agent.brain import AgentBrain
from ..agent.output import LoggingOutputHandler
from ..constants import BUILTIN_API_KEY, DEFAULT_MCP_URL, OPENROUTER_MODEL
from ..state import InstallState
from .health_monitor import HealthMonitor
from .http_api import HTTPAPIServer

logger = logging.getLogger(__name__)

AGENT_CONFIG_PATH = os.path.expanduser("~/.easyclaw/agent.json")


def load_agent_config() -> dict:
    """Load agent daemon config from ~/.easyclaw/agent.json."""
    if not os.path.exists(AGENT_CONFIG_PATH):
        logger.warning("No agent config at %s, using defaults", AGENT_CONFIG_PATH)
        return {}

    try:
        with open(AGENT_CONFIG_PATH, "r") as f:
            config = json.load(f)
        logger.info("Loaded agent config from %s", AGENT_CONFIG_PATH)
        return config
    except Exception as exc:
        logger.error("Failed to load agent config: %s", exc)
        return {}


def create_default_config() -> dict:
    """Create a default agent config with a random API token."""
    config = {
        "telegram_token": "",
        "telegram_allowed_users": [],
        "telegram_chat_id": 0,
        "api_token": f"ec_agent_{secrets.token_hex(16)}",
        "api_port": 8585,
        "health_check_interval": 300,
        "auto_restart": True,
        "max_auto_restarts_per_hour": 3,
    }

    os.makedirs(os.path.dirname(AGENT_CONFIG_PATH), exist_ok=True)
    with open(AGENT_CONFIG_PATH, "w") as f:
        json.dump(config, f, indent=4)
    logger.info("Created default agent config at %s", AGENT_CONFIG_PATH)
    return config


def run_daemon(
    api_key: str = "",
    mcp_url: str = "",
    mcp_key: str = "",
) -> None:
    """Main daemon entry point. Starts all components and blocks."""

    # Setup logging for daemon mode
    logging.basicConfig(
        level=logging.INFO,
        format="%(asctime)s %(levelname)s %(name)s: %(message)s",
        handlers=[
            logging.StreamHandler(sys.stdout),
            logging.FileHandler("/tmp/easyclaw-agent.log"),
        ],
        force=True,
    )

    logger.info("EasyClaw Agent Johnny 5 daemon starting...")

    # Load config
    config = load_agent_config()
    if not config:
        config = create_default_config()

    # Resolve keys
    resolved_key = api_key or BUILTIN_API_KEY
    resolved_mcp_url = mcp_url or DEFAULT_MCP_URL
    resolved_mcp_key = mcp_key or os.environ.get("EASYCLAW_MCP_KEY", "")

    # Create shared state (post-install mode)
    state = InstallState()
    state.install_complete = True

    # Create shared AgentBrain
    brain = AgentBrain(
        state=state,
        api_key=resolved_key,
        mcp_url=resolved_mcp_url,
        mcp_key=resolved_mcp_key,
        model=OPENROUTER_MODEL,
    )

    brain.daemon_mode = True

    # Initialize MCP (blocking, before anything else)
    brain.ensure_mcp(LoggingOutputHandler())

    # 1. Start health monitor (background thread)
    monitor = HealthMonitor(
        telegram_token=config.get("telegram_token", ""),
        telegram_chat_id=config.get("telegram_chat_id", 0),
        check_interval=config.get("health_check_interval", 300),
        auto_restart=config.get("auto_restart", True),
        max_restarts=config.get("max_auto_restarts_per_hour", 3),
    )
    monitor.start()

    # 2. Start HTTP API (background thread)
    api = HTTPAPIServer(
        agent=brain,
        monitor=monitor,
        api_token=config.get("api_token", ""),
        port=config.get("api_port", 8585),
    )
    api.start()

    # 3. Start Telegram bot (main loop) or block on signal
    telegram_token = config.get("telegram_token", "")
    telegram_users = config.get("telegram_allowed_users", [])

    if telegram_token and telegram_users:
        from .telegram_bot import TelegramFrontend

        bot = TelegramFrontend(
            token=telegram_token,
            allowed_user_ids=telegram_users,
            agent=brain,
            monitor=monitor,
        )
        logger.info("Starting Telegram bot...")
        try:
            asyncio.run(bot.start())
        except KeyboardInterrupt:
            logger.info("Daemon interrupted by user")
    else:
        logger.info(
            "No Telegram config. Running HTTP API + health monitor only. "
            "Press Ctrl+C to stop."
        )
        try:
            # Block until signal
            stop_event = asyncio.Event()
            asyncio.get_event_loop().run_until_complete(stop_event.wait())
        except KeyboardInterrupt:
            logger.info("Daemon interrupted by user")

    # Cleanup
    monitor.stop()
    api.stop()
    brain.close()
    logger.info("EasyClaw Agent Johnny 5 daemon stopped.")
