from __future__ import annotations

from contextlib import asynccontextmanager
from pathlib import Path

from fastapi import FastAPI, HTTPException
from fastapi.middleware.cors import CORSMiddleware
from fastapi.responses import FileResponse
from fastapi.staticfiles import StaticFiles

from .api import router as api_router
from .config import get_control_settings
from .db import ControlDB, set_control_db


def resolve_frontend_dist() -> Path:
    # control/backend/app -> control/frontend/dist
    return Path(__file__).resolve().parents[2] / "frontend" / "dist"


@asynccontextmanager
async def lifespan(app: FastAPI):
    from .envfile import ensure_env_control_defaults

    # 首次启动补全 .env.control 缺项（已有值不覆盖）
    ensure_env_control_defaults()
    db = ControlDB()
    set_control_db(db)
    yield
    db.close()
    set_control_db(None)


app = FastAPI(
    title="比特骆驼中控",
    version="0.1.0",
    lifespan=lifespan,
)
app.add_middleware(
    CORSMiddleware,
    allow_origins=[],
    allow_credentials=False,
    allow_methods=["*"],
    allow_headers=["*"],
)
app.include_router(api_router)


@app.get("/health")
async def health() -> dict:
    s = get_control_settings()
    return {"ok": True, "app": "control", "sse_interval_sec": s.control_sse_interval_sec}


_DIST = resolve_frontend_dist()
if (_DIST / "assets").is_dir():
    app.mount("/assets", StaticFiles(directory=str(_DIST / "assets")), name="assets")


@app.get("/")
@app.get("/monitor")
@app.get("/settings")
@app.get("/login")
async def spa(full_path: str = ""):
    index = _DIST / "index.html"
    if index.exists():
        return FileResponse(index)
    if Path(__file__).name:
        return {
            "ok": True,
            "msg": "control frontend not built; cd control/frontend && npm ci && npm run build",
            "health": "/health",
        }
    raise HTTPException(status_code=404, detail="frontend missing")
