"""
Geutebruck Cross-Switching API
FastAPI application entry point
"""
from fastapi import FastAPI, Request, status
from fastapi.middleware.cors import CORSMiddleware
from fastapi.responses import JSONResponse
from fastapi.exceptions import RequestValidationError
import structlog
import sys
from pathlib import Path

# Add src/api to Python path for imports
sys.path.insert(0, str(Path(__file__).parent))

from config import settings

# Configure structured logging
structlog.configure(
    processors=[
        structlog.processors.TimeStamper(fmt="iso"),
        structlog.stdlib.add_log_level,
        structlog.processors.JSONRenderer() if settings.LOG_FORMAT == "json" else structlog.dev.ConsoleRenderer()
    ],
    wrapper_class=structlog.stdlib.BoundLogger,
    context_class=dict,
    logger_factory=structlog.stdlib.LoggerFactory(),
)

logger = structlog.get_logger()

# Create FastAPI app
app = FastAPI(
    title=settings.API_TITLE,
    version=settings.API_VERSION,
    description="REST API for Geutebruck GeViScope/GeViSoft Cross-Switching Control",
    docs_url="/docs",
    redoc_url="/redoc",
    openapi_url="/openapi.json"
)

# CORS middleware
app.add_middleware(
    CORSMiddleware,
    allow_origins=settings.CORS_ORIGINS,
    allow_credentials=True,
    allow_methods=["*"],
    allow_headers=["*"],
)

# Global exception handlers
@app.exception_handler(RequestValidationError)
async def validation_exception_handler(request: Request, exc: RequestValidationError):
    """Handle validation errors"""
    logger.warning("validation_error", errors=exc.errors(), body=exc.body)
    return JSONResponse(
        status_code=status.HTTP_422_UNPROCESSABLE_ENTITY,
        content={
            "error": "Validation Error",
            "detail": exc.errors(),
        },
    )

@app.exception_handler(Exception)
async def global_exception_handler(request: Request, exc: Exception):
    """Handle unexpected errors"""
    logger.error("unexpected_error", exc_info=exc)
    return JSONResponse(
        status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
        content={
            "error": "Internal Server Error",
            "message": "An unexpected error occurred" if settings.ENVIRONMENT == "production" else str(exc),
        },
    )

# Startup event
@app.on_event("startup")
async def startup_event():
    """Initialize services on startup"""
    logger.info("startup",
                api_title=settings.API_TITLE,
                version=settings.API_VERSION,
                environment=settings.ENVIRONMENT)

    # Initialize Redis connection
    try:
        from clients.redis_client import redis_client
        await redis_client.connect()
        logger.info("redis_connected", host=settings.REDIS_HOST, port=settings.REDIS_PORT)
    except Exception as e:
        logger.error("redis_connection_failed", error=str(e))
        # Non-fatal: API can run without Redis (no caching/token blacklist)

    # Initialize gRPC SDK Bridge client
    try:
        from clients.sdk_bridge_client import sdk_bridge_client
        await sdk_bridge_client.connect()
        logger.info("sdk_bridge_connected", url=settings.sdk_bridge_url)
    except Exception as e:
        logger.error("sdk_bridge_connection_failed", error=str(e))
        # Non-fatal: API can run without SDK Bridge (for testing)

    # Database connection pool is initialized lazily via AsyncSessionLocal

    logger.info("startup_complete")

# Shutdown event
@app.on_event("shutdown")
async def shutdown_event():
    """Cleanup on shutdown"""
    logger.info("shutdown")

    # Close Redis connections
    try:
        from clients.redis_client import redis_client
        await redis_client.disconnect()
        logger.info("redis_disconnected")
    except Exception as e:
        logger.error("redis_disconnect_failed", error=str(e))

    # Close gRPC SDK Bridge connections
    try:
        from clients.sdk_bridge_client import sdk_bridge_client
        await sdk_bridge_client.disconnect()
        logger.info("sdk_bridge_disconnected")
    except Exception as e:
        logger.error("sdk_bridge_disconnect_failed", error=str(e))

    # Close database connections
    try:
        from models import engine
        await engine.dispose()
        logger.info("database_disconnected")
    except Exception as e:
        logger.error("database_disconnect_failed", error=str(e))

    logger.info("shutdown_complete")

# Health check endpoint
@app.get("/health", tags=["system"])
async def health_check():
    """Health check endpoint"""
    return {
        "status": "healthy",
        "version": settings.API_VERSION,
        "environment": settings.ENVIRONMENT
    }

# Root endpoint
@app.get("/", tags=["system"])
async def root():
    """API root endpoint"""
    return {
        "name": settings.API_TITLE,
        "version": settings.API_VERSION,
        "docs": "/docs",
        "health": "/health"
    }

# Register routers
from routers import auth, cameras
app.include_router(auth.router)
app.include_router(cameras.router)

# TODO: Add remaining routers as phases complete
# from routers import monitors, crossswitch
# app.include_router(monitors.router)
# app.include_router(crossswitch.router)

if __name__ == "__main__":
    import uvicorn
    uvicorn.run(
        "main:app",
        host=settings.API_HOST,
        port=settings.API_PORT,
        reload=settings.ENVIRONMENT == "development"
    )
