from pathlib import Path
from dotenv import load_dotenv
import os

ENV_PATH = Path(__file__).resolve().parent.parent / ".env"
os.environ["DOTENV_PATH"] = str(ENV_PATH)  
load_dotenv(dotenv_path=ENV_PATH, override=True)

from fastapi import FastAPI, Request, Response
from fastapi.middleware.cors import CORSMiddleware
from fastapi.staticfiles import StaticFiles
from starlette.middleware.base import BaseHTTPMiddleware

from app.api import (
    auth, users, products, bookings, deliveries, stats, topups,
    audit_logs, profile, transactions, categories, ledger, admin_settings, paypal_ipn
)
from app.core.auth import CSRF_HEADER_NAME, verify_csrf

ALLOWED_ORIGINS = ["http://localhost:5173"]

# CSRF-Ausnahmen (nur für DEV sinnvoll!)
CSRF_EXEMPT = {
    "/auth/pin-login",
    "/auth/management-login",
    "/auth/logout",
    "/auth/csrf",
    "/docs",
    "/openapi.json",
    "/redoc",
    "/docs/oauth2-redirect",
}

# Swagger-/Redoc-Pfade
DOCS_PATHS = ("/docs", "/redoc", "/openapi.json")

app = FastAPI()

app.add_middleware(
    CORSMiddleware,
    allow_origins=ALLOWED_ORIGINS,
    allow_credentials=True,
    allow_methods=["GET", "POST", "PUT", "PATCH", "DELETE", "OPTIONS"],
    allow_headers=["Content-Type", CSRF_HEADER_NAME],
)

class SecurityHeadersMiddleware(BaseHTTPMiddleware):
    async def dispatch(self, request: Request, call_next):
        path = request.url.path

        # CSRF nur für mutierende Methoden prüfen, ausgenommene Pfade überspringen
        if (
            request.method in {"POST", "PUT", "PATCH", "DELETE"}
            and not any(path == p or path.startswith(p + "/") for p in CSRF_EXEMPT)
        ):
            verify_csrf(request)

        response: Response = await call_next(request)

        
        if any(path == p or path.startswith(p + "/") for p in DOCS_PATHS):
            response.headers.setdefault(
                "Content-Security-Policy",
                "default-src 'self' https:; "
                "img-src 'self' data: https:; "
                "style-src 'self' 'unsafe-inline' https:; "
                "script-src 'self' 'unsafe-inline' https:"
            )
            return response

        # Normale Security-Header + strikte CSP
        response.headers.setdefault("X-Frame-Options", "DENY")
        response.headers.setdefault("X-Content-Type-Options", "nosniff")
        response.headers.setdefault("Referrer-Policy", "no-referrer")
        response.headers.setdefault(
            "Content-Security-Policy",
            "default-src 'self'; img-src 'self' data:; style-src 'self'; script-src 'self'"
        )
        return response

app.add_middleware(SecurityHeadersMiddleware)

# Medienordner sicherstellen (verhindert RuntimeError beim Mount)
os.makedirs("media/avatars", exist_ok=True)

# Static files für Avatare & Medien
app.mount("/media", StaticFiles(directory="media"), name="media")

# Router registrieren
app.include_router(auth.router)
app.include_router(users.router)
app.include_router(products.router)
app.include_router(bookings.router)
app.include_router(deliveries.router)
app.include_router(stats.router)
app.include_router(topups.router)
app.include_router(audit_logs.router)
app.include_router(profile.router)
app.include_router(transactions.router)
app.include_router(categories.router)
app.include_router(ledger.router)
app.include_router(admin_settings.router)
app.include_router(paypal_ipn.router)      
# app.include_router(sessions.router)

@app.get("/")
def root():
    return {"message": "Bacchus API läuft"}
