"""FastAPI application entrypoint: routers, static files, security headers, startup."""
import logging
from contextlib import asynccontextmanager

from fastapi import FastAPI, Request
from fastapi.responses import JSONResponse, FileResponse
from fastapi.staticfiles import StaticFiles
from starlette.middleware.base import BaseHTTPMiddleware

from app.api.routers import (accounts, attachments, auth, campaigns, dashboard,
                             recipients, settings_router, subjects, suppression,
                             templates, phones, test_send, logs, unsubscribe as unsub_router)
from app.core.config import settings

logging.basicConfig(level=logging.INFO,
                    format="%(asctime)s %(levelname)s %(name)s %(message)s")


@asynccontextmanager
async def lifespan(app: FastAPI):
    yield
    from app.db.session import close_engines
    await close_engines()


app = FastAPI(title=settings.APP_NAME, lifespan=lifespan,
              docs_url="/api/docs", openapi_url="/api/openapi.json")


class SecurityHeadersMiddleware(BaseHTTPMiddleware):
    async def dispatch(self, request, call_next):
        response = await call_next(request)
        response.headers.setdefault("X-Content-Type-Options", "nosniff")
        response.headers.setdefault("X-Frame-Options", "DENY")
        response.headers.setdefault("Referrer-Policy", "no-referrer")
        response.headers.setdefault("Content-Security-Policy",
                                    "default-src 'self'; img-src 'self' data:; style-src 'self' 'unsafe-inline';"
                                    " script-src 'self'; frame-src 'self' data: blob:;"
                                    " object-src 'self' data: blob:; frame-ancestors 'none'")
        if settings.ENVIRONMENT == "production":
            response.headers.setdefault("Strict-Transport-Security", "max-age=63072000; includeSubDomains")
        return response


app.add_middleware(SecurityHeadersMiddleware)

app.include_router(auth.router)
app.include_router(accounts.router)
app.include_router(recipients.router)
app.include_router(subjects.router)
app.include_router(templates.router)
app.include_router(attachments.router)
app.include_router(phones.router)
app.include_router(campaigns.router)
app.include_router(test_send.router)
app.include_router(dashboard.router)
app.include_router(suppression.router)
app.include_router(settings_router.router)
app.include_router(logs.router)
app.include_router(unsub_router.router)

app.mount("/static", StaticFiles(directory="static"), name="static")


@app.get("/api/health")
async def health():
    from app.db.session import check_db_health
    import redis as redis_lib
    db_ok = check_db_health()
    try:
        r = redis_lib.from_url(settings.REDIS_URL, socket_timeout=1)
        r.ping()
        redis_ok = True
    except Exception:
        redis_ok = False
    return {"status": "ok" if db_ok and redis_ok else "degraded",
            "database": "up" if db_ok else "down", "redis": "up" if redis_ok else "down"}


# Frontend SPA-ish pages
@app.get("/", include_in_schema=False)
async def index():
    return FileResponse("static/index.html")


@app.get("/{page}", include_in_schema=False)
async def page(page: str):
    import os
    safe = page.replace("/", "")
    path = f"static/{safe}.html"
    if os.path.exists(path):
        return FileResponse(path)
    return JSONResponse({"error": "not found"}, status_code=404)
