"""FastAPI 主入口。"""

import asyncio
import logging
import os
from contextlib import asynccontextmanager
from typing import Any

import inngest
import inngest.fast_api
import uvicorn
from fastapi import FastAPI

from butler.config import settings
from butler.gateway.napcat import NapCatGateway
from butler.workflows import inngest_client
from butler.workflows.handle_message import handle_im_message
from butler.workflows.guardrail import command_guardrail

logging.basicConfig(
    level=getattr(logging, settings.log_level),
    format="%(asctime)s - %(name)s - %(levelname)s - %(message)s",
)
logger = logging.getLogger(__name__)

gateway = NapCatGateway(
    ws_url=settings.napcat_ws_url,
    access_token=settings.napcat_token,
)


async def run_gateway() -> None:
    """后台运行 Gateway。"""
    def handle_message(event: Any) -> None:
        """同步消息处理函数。"""
        logger.info(f"Received message from {event.user_id}: {event.message[:50]}...")
        # 在后台任务中发送事件
        asyncio.create_task(inngest_client.send(
            inngest.Event(
                name="im/message",
                data={
                    "user_id": str(event.user_id),
                    "content": event.message,
                },
            )
        ))

    gateway.on_message(handle_message)
    await gateway.connect()


@asynccontextmanager
async def lifespan(app: FastAPI):
    """应用生命周期管理。"""
    logger.info("Starting Butler-Shell...")

    gateway_task = asyncio.create_task(run_gateway())

    yield

    logger.info("Shutting down Butler-Shell...")
    await gateway.stop()
    gateway_task.cancel()


app = FastAPI(
    title="Butler-Shell",
    description="Persistent Shell Assistant with QQ Bridge",
    version="0.1.0",
    lifespan=lifespan,
)

# 注册 Inngest 函数
# 开发模式下使用占位签名密钥
_signing_key = settings.inngest_signing_key or os.environ.get(
    "INNGEST_SIGNING_KEY",
    "signkey-dev-placeholder-1234567890123456789012345678901234567890"
)
_dev_client = inngest.Inngest(
    app_id="butler-shell",
    event_key=settings.inngest_event_key or "dev_key",
    signing_key=_signing_key,
    is_production=bool(settings.inngest_signing_key),
)

inngest.fast_api.serve(
    app,
    _dev_client,
    [handle_im_message, command_guardrail],
    serve_path="/api/inngest",
)


@app.get("/health")
async def health() -> dict[str, str]:
    """服务存活检查。"""
    return {"status": "ok"}


@app.get("/ready")
async def ready() -> dict[str, Any]:
    """服务就绪检查。"""
    import subprocess
    try:
        subprocess.run(["tmux", "-V"], capture_output=True, check=True)
        tmux_ok = True
    except Exception:
        tmux_ok = False

    return {
        "status": "ready" if tmux_ok else "degraded",
        "tmux": tmux_ok,
        "gateway": gateway._ws is not None,
    }


@app.post("/api/approval")
async def handle_approval(user_id: str, approved: bool) -> dict[str, str]:
    """处理用户审批响应。"""
    await inngest_client.send(
        inngest.Event(
            name="im/approval-response",
            data={"user_id": user_id, "approved": approved},
        )
    )
    return {"status": "sent"}


def main() -> None:
    """启动服务。"""
    uvicorn.run("butler.main:app", host="0.0.0.0", port=8000, reload=False)


if __name__ == "__main__":
    main()
