"""Aplicação web completa para produção: a API em `/api` (mesmo prefixo do proxy do Vite no dev) e o
frontend compilado (`frontend/dist`) servido como SPA, tudo na mesma origem.

Rodar localmente "como produção": `uvicorn custos_precificacao.api.web:app`.
"""

import os
from pathlib import Path

from fastapi import FastAPI
from starlette.exceptions import HTTPException as StarletteHTTPException
from starlette.requests import Request
from starlette.staticfiles import StaticFiles

from custos_precificacao.api.main import app as api_app

RAIZ = Path(__file__).resolve().parents[3]

CABECALHOS = {
    "X-Content-Type-Options": "nosniff",
    "X-Frame-Options": "DENY",
    "Referrer-Policy": "same-origin",
}


class SpaStaticFiles(StaticFiles):
    """Arquivos estáticos; caminhos sem extensão que não existem caem no index.html (rotas do React)."""

    async def get_response(self, path, scope):
        try:
            return await super().get_response(path, scope)
        except StarletteHTTPException as exc:
            if exc.status_code == 404 and "." not in Path(path).name:
                return await super().get_response("index.html", scope)
            raise


def criar_app(dist: Path | None = None) -> FastAPI:
    dist = dist or Path(os.getenv("FRONTEND_DIST") or RAIZ / "frontend" / "dist")
    app = FastAPI(docs_url=None, redoc_url=None, openapi_url=None)

    @app.middleware("http")
    async def cabecalhos_de_seguranca(request: Request, call_next):
        resposta = await call_next(request)
        for nome, valor in CABECALHOS.items():
            resposta.headers.setdefault(nome, valor)
        if request.url.path.startswith("/api"):
            resposta.headers.setdefault("Cache-Control", "no-store")
        return resposta

    app.mount("/api", api_app)
    if (dist / "index.html").is_file():
        app.mount("/", SpaStaticFiles(directory=dist, html=True), name="frontend")
    return app


app = criar_app()
