import os
import logging
from collections import defaultdict
from time import time
from contextlib import asynccontextmanager
from fastapi import FastAPI, Request
from fastapi.responses import JSONResponse
from fastapi.middleware.cors import CORSMiddleware
from enterprise_ai.api.health import router as health_router
from enterprise_ai.api.ai import router as ai_router
from enterprise_ai.api.agents import router as agents_router
from enterprise_ai.api.admin import router as admin_router
from enterprise_ai.api.config_admin import router as config_router
from enterprise_ai.core.database import SessionLocal
from enterprise_ai.core.auto_seed import run_seeds
from enterprise_ai.core.env_check import check_agent_environment

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

@asynccontextmanager
async def lifespan(app: FastAPI):
    run_seeds(SessionLocal())
    check_agent_environment()
    yield

app = FastAPI(
    title="EnterPrise Ai",
    version="1.0.0",
    lifespan=lifespan,
)

# ── CORS ──────────────────────────────────────────────────────
# Comma-separated allowlist, e.g. "https://app.example.com,http://localhost:5173".
# Unset or empty falls back to "*" (all origins). Because allow_credentials=True,
# Starlette echoes the caller's Origin header rather than sending a literal "*",
# so credentialed cross-origin requests still work.
_raw_origins = os.getenv("ALLOWED_ORIGINS", "*")
allowed_origins = [o.strip() for o in _raw_origins.split(",") if o.strip()] or ["*"]

app.add_middleware(
    CORSMiddleware,
    allow_origins=["*"],
    allow_credentials=True,
    allow_methods=["*"],
    allow_headers=["Authorization", "Content-Type"],
)

# ── Security headers ──────────────────────────────────────────
@app.middleware("http")
async def add_security_headers(request: Request, call_next):
    response = await call_next(request)
    response.headers["X-Content-Type-Options"] = "nosniff"
    response.headers["X-Frame-Options"] = "DENY"
    response.headers["X-XSS-Protection"] = "1; mode=block"
    response.headers["Referrer-Policy"] = "strict-origin-when-cross-origin"
    return response

# ── Rate limiting (60 requests / 60 seconds per IP) ───────────
_rate_limit_requests: dict = defaultdict(list)
RATE_LIMIT = int(os.getenv("RATE_LIMIT_PER_MINUTE", "60"))

@app.middleware("http")
async def rate_limit_middleware(request: Request, call_next):
    client_ip = request.client.host if request.client else "unknown"
    now = time()
    window = 60
    _rate_limit_requests[client_ip] = [
        t for t in _rate_limit_requests[client_ip] if now - t < window
    ]
    if not _rate_limit_requests[client_ip]:
        _rate_limit_requests.pop(client_ip, None)
        _rate_limit_requests[client_ip] = []
    if len(_rate_limit_requests[client_ip]) >= RATE_LIMIT:
        return JSONResponse({"detail": "Rate limit exceeded"}, status_code=429)
    _rate_limit_requests[client_ip].append(now)
    return await call_next(request)

# ── Routers ───────────────────────────────────────────────────
app.include_router(admin_router)
app.include_router(health_router)
app.include_router(ai_router)
app.include_router(config_router)
# Per-agent routes (POST /document_identifier, /parser_document, …) — generated
# from core/agent_catalog.py. Included last so platform routes always win.
app.include_router(agents_router)

if __name__ == "__main__":
    import uvicorn
    uvicorn.run(app, host="0.0.0.0", port=8006)

