"""FastAPI application for Hangar."""

from pathlib import Path

from contextlib import asynccontextmanager
from fastapi import FastAPI
from fastapi.middleware.cors import CORSMiddleware
from fastapi.responses import FileResponse, JSONResponse
from fastapi.staticfiles import StaticFiles

from hangar.dependencies import get_project_path
from hangar.routers import gitdiff, project, specs, stats, sync, tasks, terminal, timeline, watch, wizard
from hangar.services.watcher import WatcherService

STATIC_DIR = Path(__file__).parent / "static"

@asynccontextmanager
async def lifespan(app: FastAPI):
    """Start/stop the filesystem watcher with the app."""
    watcher = WatcherService(project_path=get_project_path())
    watch.set_watcher_service(watcher)
    await watcher.start()
    yield
    await watcher.stop()


app = FastAPI(
    title="Hangar",
    description="Orchestration-first IDE for spec-driven AI development",
    version="0.1.1",
    lifespan=lifespan,
)

app.add_middleware(
    CORSMiddleware,
    allow_origins=["http://localhost:5173"],
    allow_credentials=True,
    allow_methods=["*"],
    allow_headers=["*"],
)

app.include_router(tasks.router)
app.include_router(specs.router)
app.include_router(gitdiff.router)
app.include_router(sync.router)
app.include_router(wizard.router)
app.include_router(timeline.router)
app.include_router(stats.router)
app.include_router(project.router)
app.include_router(terminal.router)
app.include_router(watch.router)


@app.get("/api/health")
async def health() -> dict:
    """Health check endpoint."""
    return {"status": "ok", "service": "hangar"}


# SPA fallback: non-API 404s serve the SPA shell
@app.exception_handler(404)
async def spa_fallback(request, exc):
    if request.url.path.startswith("/api/"):
        detail = getattr(exc, "detail", "Not Found")
        return JSONResponse(status_code=404, content={"detail": detail})
    fallback = STATIC_DIR / "200.html"
    if fallback.is_file():
        return FileResponse(fallback)
    return JSONResponse(status_code=404, content={"detail": "Not Found"})


# Mount static files if the build directory exists (skip in dev mode)
if STATIC_DIR.is_dir():
    app.mount("/", StaticFiles(directory=STATIC_DIR, html=True), name="spa")


if __name__ == "__main__":
    from hangar.cli import main
    main()
