"""Proactive agent routes: /proactive/status, start, stop, check, /engagement/status, /engagement/tick."""

from __future__ import annotations

import asyncio

try:
    from aiohttp import web  # noqa: F401
except ImportError as _exc:
    raise RuntimeError("aiohttp is required for gateway routes (pip install aiohttp)") from _exc
from navig.agent.proactive.engine import get_proactive_engine
from navig.debug_logger import get_debug_logger
from navig.gateway.routes.common import (
    json_error_response,
    json_ok,
    require_bearer_auth,
)

logger = get_debug_logger()


def register(app, gateway):
    app.router.add_get("/proactive/status", _proactive_status(gateway))
    app.router.add_post("/proactive/start", _proactive_start(gateway))
    app.router.add_post("/proactive/stop", _proactive_stop(gateway))
    app.router.add_post("/proactive/check", _proactive_check(gateway))
    app.router.add_get("/engagement/status", _engagement_status(gateway))
    app.router.add_post("/engagement/tick", _engagement_tick(gateway))


def _proactive_status(gw):
    async def h(r):
        auth = require_bearer_auth(r, gw)
        if auth is not None:
            return auth
        engine = get_proactive_engine()
        return json_ok(
            {
                "started": engine.running,
                "last_check": (engine.last_check.isoformat() if engine.last_check else None),
                "last_check_status": engine.last_check_status,
                "last_error": engine.last_error,
                "providers": engine.provider_status,
            }
        )

    return h


def _proactive_start(gw):
    async def h(r):
        auth = require_bearer_auth(r, gw)
        if auth is not None:
            return auth
        engine = get_proactive_engine()
        if not engine.running:
            asyncio.create_task(engine.start())
            return json_ok({"status": "started"})
        return json_ok({"status": "already_running"})

    return h


def _proactive_stop(gw):
    async def h(r):
        auth = require_bearer_auth(r, gw)
        if auth is not None:
            return auth
        engine = get_proactive_engine()
        if engine.running:
            await engine.stop()
            return json_ok({"status": "stopped"})
        return json_ok({"status": "not_running"})

    return h


def _proactive_check(gw):
    async def h(r):
        auth = require_bearer_auth(r, gw)
        if auth is not None:
            return auth
        engine = get_proactive_engine()
        if engine.is_checking:
            return json_error_response("Proactive engine busy", status=409, code="busy")
        asyncio.create_task(engine.run_checks(None))
        return json_ok({"status": "triggered"})

    return h


def _engagement_status(gw):
    async def h(r):
        auth = require_bearer_auth(r, gw)
        if auth is not None:
            return auth
        try:
            engine = get_proactive_engine()
            coordinator = engine._get_engagement_coordinator()
            state = coordinator.state
            return json_ok(
                {
                    "enabled": coordinator.config.enabled,
                    "operator_state": state.get_operator_state().value,
                    "time_of_day": state.get_time_of_day().value,
                    "within_active_hours": state.is_within_active_hours(),
                    "stats": {
                        "total_messages": state.stats.total_messages,
                        "total_commands": state.stats.total_commands,
                        "features_used": len(state.stats.features_used),
                        "last_greeting": state.stats.last_greeting,
                        "last_checkin": state.stats.last_checkin,
                        "last_capability_promo": state.stats.last_capability_promo,
                        "last_feedback_ask": state.stats.last_feedback_ask,
                    },
                    "daily_sends": len(coordinator._daily_sends),
                    "max_daily": coordinator.config.max_proactive_per_day,
                }
            )
        except Exception as e:
            return json_error_response(
                "Failed to get engagement status",
                status=500,
                code="internal_error",
                details={"error": str(e)},
            )

    return h


def _engagement_tick(gw):
    async def h(r):
        auth = require_bearer_auth(r, gw)
        if auth is not None:
            return auth
        try:
            engine = get_proactive_engine()
            coordinator = engine._get_engagement_coordinator()
            result = coordinator.engagement_tick()
            if result:
                if "telegram" in gw.channels:
                    await gw.deliver_message(
                        channel="telegram",
                        to=None,
                        content=result.message,
                    )
                return json_ok(
                    {
                        "status": "sent",
                        "action": result.action.value,
                        "message": result.message,
                        "priority": result.priority,
                    }
                )
            return json_ok({"status": "no_action"})
        except Exception as e:
            return json_error_response(
                "Failed to run engagement tick",
                status=500,
                code="internal_error",
                details={"error": str(e)},
            )

    return h
