"""FastAPI application factory for Mixer Studio."""

from __future__ import annotations

from contextlib import asynccontextmanager
from pathlib import Path

from fastapi import FastAPI, Request
from fastapi.middleware.cors import CORSMiddleware
from fastapi.responses import FileResponse, HTMLResponse

from mixersystem.studio.config import StudioConfig
from mixersystem.studio.event_bus import EventBus
from mixersystem.studio.process_manager import ProcessManager


def create_app(config: StudioConfig | None = None) -> FastAPI:
    config = config or StudioConfig()

    @asynccontextmanager
    async def lifespan(app: FastAPI):
        event_bus = EventBus(project_root=config.project_root)
        process_manager = ProcessManager(event_bus, config.project_root)

        app.state.config = config
        app.state.event_bus = event_bus
        app.state.process_manager = process_manager

        yield

        await process_manager.shutdown()

    app = FastAPI(
        title="Mixer Studio",
        lifespan=lifespan,
    )

    # CORS for dev mode (Vite dev server)
    app.add_middleware(
        CORSMiddleware,
        allow_origins=[
            "http://localhost:5173",
            "http://127.0.0.1:5173",
        ],
        allow_origin_regex=r"^https?://(localhost|127\.0\.0\.1)(:\d+)?$",
        allow_methods=["*"],
        allow_headers=["*"],
    )

    # Include API routers
    from mixersystem.studio.routes.session_folders import router as wf_router
    from mixersystem.studio.routes.workflows import router as flow_router
    from mixersystem.studio.routes.artifacts import router as art_router
    from mixersystem.studio.routes.logs import router as logs_router
    from mixersystem.studio.routes.push import router as push_router
    from mixersystem.studio.routes.linear import router as linear_router
    from mixersystem.studio.routes.settings import router as settings_router
    from mixersystem.studio.routes.questions import router as questions_router
    from mixersystem.studio.ws import router as ws_router

    app.include_router(wf_router)
    app.include_router(flow_router)
    app.include_router(art_router)
    app.include_router(logs_router)
    app.include_router(push_router)
    app.include_router(linear_router)
    app.include_router(settings_router)
    app.include_router(questions_router)
    app.include_router(ws_router)

    # Serve React build output — static assets + SPA fallback
    static_dir = Path(__file__).parent / "static"

    @app.get("/{path:path}")
    async def spa_fallback(request: Request, path: str):
        # Try serving a static file first
        if static_dir.is_dir() and path:
            file = static_dir / path
            if file.is_file() and static_dir in file.resolve().parents:
                return FileResponse(str(file))
        # Fall back to index.html for SPA routing
        index = static_dir / "index.html"
        if index.is_file():
            return FileResponse(str(index), media_type="text/html")
        return HTMLResponse("<h1>Studio not built</h1><p>Run: cd mixersystem/studio/frontend && npm run build</p>", status_code=404)

    return app
