"""FastAPI application entrypoint.

Lifespan opens the DB pool and runs migrations before uvicorn accepts
connections — so a fresh container bootstraps its schema upgrade-ably and
does not have a "cold pool just before the first request" race.
"""

from __future__ import annotations

import logging
from contextlib import asynccontextmanager

from fastapi import FastAPI

from app import __version__
from app.api.routes_brief import router as brief_router
from app.db import db
from app.logging import setup_logging

logger = logging.getLogger(__name__)


@asynccontextmanager
async def lifespan(app: FastAPI):
    setup_logging()
    logger.info("city briefing agent starting (version %s)", __version__)
    try:
        await db.open()
        applied = await db.migrate()
        if applied:
            logger.info("migrations applied: %s", ", ".join(applied))
        else:
            logger.info("migrations up to date")
    except Exception:
        logger.exception("DB bootstrap failed; continuing without migrations applied")
    yield
    try:
        await db.close()
    except Exception:
        logger.debug("db close failed", exc_info=True)


app = FastAPI(
    title="Max Amini — City Briefing Agent",
    version=__version__,
    description=(
        "Daily pipeline: discover shows 7 days out → city intel → news → fact "
        "check → 20 GPT-4o crowd-work ideas → Claude top-10 → HTML → VPS → "
        "verify URL + Open Graph. Phase 12 — no email delivery."
    ),
    lifespan=lifespan,
)


@app.get("/health", tags=["health"])
async def health() -> dict[str, str]:
    return {"status": "ok", "version": __version__}


app.include_router(brief_router)