"""AIF Normbase - FastAPI Application Entry Point"""
import asyncio
from contextlib import asynccontextmanager
from fastapi import FastAPI
from fastapi.middleware.cors import CORSMiddleware
from fastapi.responses import JSONResponse
import json

from normbase.config import settings
from normbase.db.connection import init_db, close_db
from normbase.api.norms import router as norms_router
from normbase.api.retrieval import router as retrieval_router
from normbase.api.keys import router as keys_router
from normbase.api.roles import router as roles_router
from normbase.api.compliance import router as compliance_router
from normbase.api.fields import router as fields_router
from normbase.api.extraction import router as extraction_router
from normbase.api.retrieval import prewarm_retrieval_service
from normbase.api.deps_auth import RequireInternalToken, RequireRuntimeAuth
from normbase.admin import admin_html
from normbase.services.cache_service import CacheService
from normbase.services.qdrant_service import QdrantService


class CustomJSONResponse(JSONResponse):
    def render(self, content) -> bytes:
        return json.dumps(
            content,
            ensure_ascii=False,
            allow_nan=False,
            indent=None,
            separators=(",", ":"),
        ).encode("utf-8")


@asynccontextmanager
async def lifespan(app: FastAPI):
    """Application lifespan events"""
    # Startup
    await init_db()
    prewarm_retrieval_service()
    yield
    # Shutdown
    await close_db()


app = FastAPI(
    title="AIF Normbase API",
    description="Agent Information Field - Norm Repository",
    version="0.1.0",
    lifespan=lifespan,
    default_response_class=CustomJSONResponse,
)

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

# Include routers
app.include_router(norms_router, prefix="/api/v1", dependencies=[RequireInternalToken])
app.include_router(fields_router, prefix="/api/v1", dependencies=[RequireInternalToken])
app.include_router(extraction_router, prefix="/api/v1", dependencies=[RequireInternalToken])
app.include_router(retrieval_router, prefix="/api/v1", dependencies=[RequireRuntimeAuth])
app.include_router(keys_router, prefix="/api/v1")
app.include_router(roles_router, prefix="/api/v1", dependencies=[RequireRuntimeAuth])
app.include_router(compliance_router, prefix="/api/v1", dependencies=[RequireRuntimeAuth])


@app.get("/")
async def root():
    """Health check endpoint"""
    return {
        "name": "AIF Normbase",
        "version": "0.1.0",
        "status": "running"
    }


@app.get("/health")
async def health():
    """Detailed health check"""
    redis_status = "unavailable"
    try:
        redis_ok = await asyncio.wait_for(CacheService().ping(), timeout=2.0)
        redis_status = "connected" if redis_ok else "unreachable"
    except Exception:
        redis_status = "unavailable"

    qdrant_status = "unavailable"
    try:
        qdrant_ok = await asyncio.wait_for(
            asyncio.to_thread(QdrantService.ping),
            timeout=2.0,
        )
        qdrant_status = "connected" if qdrant_ok else "unreachable"
    except Exception:
        qdrant_status = "unavailable"

    return {
        "status": "healthy",
        "database": "connected",
        "redis": redis_status,
        "qdrant": qdrant_status,
    }


if __name__ == "__main__":
    import uvicorn
    uvicorn.run(
        "normbase.main:app",
        host=settings.api_host,
        port=settings.normbase_api_port,
        reload=settings.api_debug
    )
