"""v2.6 主入口 - FastAPI + Daemon ticker 共享 asyncio event loop"""

from __future__ import annotations

import logging
from contextlib import asynccontextmanager
from pathlib import Path
from typing import Optional

import yaml
from fastapi import FastAPI
from fastapi.middleware.cors import CORSMiddleware
from fastapi.staticfiles import StaticFiles

from src.blackboard.registry import ProjectRegistry
from src.daemon.ticker import Ticker
from src.utils import get_data_root

logger = logging.getLogger("moziplus-v2")

# ---------------------------------------------------------------------------
# 配置加载
# ---------------------------------------------------------------------------

DEFAULT_CONFIG_PATH = Path(__file__).parent.parent / "config" / "default.yaml"


def load_config() -> dict:
    """加载全局默认配置"""
    if DEFAULT_CONFIG_PATH.exists():
        with open(DEFAULT_CONFIG_PATH) as f:
            return yaml.safe_load(f) or {}
    return {}


config = load_config()

# ---------------------------------------------------------------------------
# 全局组件
# ---------------------------------------------------------------------------

DATA_ROOT = get_data_root()

ticker: Optional[Ticker] = None


def get_ticker() -> Optional[Ticker]:
    """获取全局 Ticker 实例"""
    return ticker


def get_registry() -> ProjectRegistry:
    """获取全局项目注册表"""
    return ProjectRegistry(DATA_ROOT)


# ---------------------------------------------------------------------------
# FastAPI 生命周期
# ---------------------------------------------------------------------------


@asynccontextmanager
async def lifespan(app: FastAPI):
    """启动 Daemon ticker，关闭时清理"""
    global ticker
    logger.info("moziplus-v2 starting...")

    registry = get_registry()
    tick_interval = config.get("daemon", {}).get("tick_interval", 30)

    ticker = Ticker(
        registry=registry,
        tick_interval=tick_interval,
    )
    await ticker.start()
    logger.info("Ticker started (interval=%ss)", tick_interval)

    yield

    if ticker:
        await ticker.stop()
    logger.info("moziplus-v2 stopped")


# ---------------------------------------------------------------------------
# FastAPI app
# ---------------------------------------------------------------------------

app = FastAPI(
    title="Sanguo MoziPlus v2",
    description="AI Native DevOps Platform - Blackboard Architecture",
    version="2.6.0",
    lifespan=lifespan,
)

app.add_middleware(
    CORSMiddleware,
    allow_origins=["*"],
    allow_credentials=True,
    allow_methods=["*"],
    allow_headers=["*"],
)

# ---------------------------------------------------------------------------
# API 路由注册
# ---------------------------------------------------------------------------

from src.api.blackboard_routes import router as blackboard_router
from src.api.daemon_routes import router as daemon_router
from src.api.project_routes import router as project_router
from src.api.sse_routes import router as sse_router

app.include_router(blackboard_router)
app.include_router(daemon_router)
app.include_router(project_router)
app.include_router(sse_router)

# ---------------------------------------------------------------------------
# 兼容端点
# ---------------------------------------------------------------------------


@app.get("/api/projects")
async def list_projects_compat():
    """兼容旧端点"""
    from src.api.project_routes import _registry
    reg = _registry()
    return {"projects": {pid: info for pid, info in reg.list_projects().items()
                         if info.get("status") != "archived"}}


# ---------------------------------------------------------------------------
# 静态文件服务（前端 dist/，F18 实现）
# ---------------------------------------------------------------------------

DIST_DIR = Path(__file__).parent / "frontend" / "dist"
if DIST_DIR.exists():
    app.mount("/", StaticFiles(directory=str(DIST_DIR), html=True), name="frontend")
