"""
GigLez FastAPI Application

Environment-aware API server supporting both development (Termux) and production (Server) modes
"""

from fastapi import FastAPI, Request
from fastapi.middleware.cors import CORSMiddleware
from fastapi.middleware.gzip import GZipMiddleware
from fastapi.responses import JSONResponse, HTMLResponse
from fastapi.staticfiles import StaticFiles
from fastapi.templating import Jinja2Templates
from contextlib import asynccontextmanager
from loguru import logger
from pathlib import Path
import time
import sys

# Add project root to Python path
sys.path.insert(0, str(Path(__file__).parent.parent.parent))

from config.settings import settings
from config.database import get_db_config


# =============================================================================
# LIFESPAN MANAGEMENT
# =============================================================================

@asynccontextmanager
async def lifespan(app: FastAPI):
    """
    Application lifespan manager
    Handles startup and shutdown events
    """
    # Startup
    logger.info("=" * 80)
    logger.info("GigLez API Starting")
    logger.info("=" * 80)

    # Display configuration
    settings.display()

    # Validate configuration
    errors = settings.validate()
    if errors:
        logger.error("Configuration validation failed:")
        for error in errors:
            logger.error(f"  ❌ {error}")
        raise RuntimeError("Invalid configuration")

    # Test database connection
    db_config = get_db_config()
    if not db_config.test_connection():
        raise RuntimeError("Database connection failed")

    if not db_config.test_postgis():
        raise RuntimeError("PostGIS extension not available")

    logger.success("✅ Database connection established")
    logger.success("✅ PostGIS extension available")

    # Initialize storage backend
    from src.core.storage import get_storage_backend
    storage = get_storage_backend()
    logger.success(f"✅ Storage backend initialized: {type(storage).__name__}")

    # Initialize background task system
    if settings.use_celery:
        logger.info("Using Celery for background tasks")
        # Celery app will be imported when needed
    else:
        logger.info("Using synchronous background tasks")

    logger.success("=" * 80)
    logger.success(f"🚀 GigLez API ready on {settings.api_host}:{settings.api_port}")
    logger.success(f"📡 Mode: {settings.mode.value}")
    logger.success("=" * 80)

    yield

    # Shutdown
    logger.info("=" * 80)
    logger.info("GigLez API Shutting Down")
    logger.info("=" * 80)

    # Close database connections
    db_config.close()
    logger.success("✅ Database connections closed")

    logger.info("Shutdown complete")


# =============================================================================
# APPLICATION INSTANCE
# =============================================================================

app = FastAPI(
    title="GigLez API",
    description="IoT RF Device Mapping Platform - Wigle for Sub-GHz Signals",
    version="1.0.0",
    lifespan=lifespan,
    docs_url="/docs" if settings.debug_endpoints else None,
    redoc_url="/redoc" if settings.debug_endpoints else None,
    openapi_url="/openapi.json" if settings.debug_endpoints else None,
)

# Mount static files and templates
BASE_DIR = Path(__file__).parent.parent.parent
app.mount("/static", StaticFiles(directory=str(BASE_DIR / "static")), name="static")
templates = Jinja2Templates(directory=str(BASE_DIR / "templates"))


# =============================================================================
# MIDDLEWARE
# =============================================================================

# CORS Middleware
app.add_middleware(
    CORSMiddleware,
    allow_origins=settings.cors_origins,
    allow_credentials=True,
    allow_methods=["*"],
    allow_headers=["*"],
    expose_headers=["X-Total-Count", "X-Page-Size"],
)

# GZip compression
app.add_middleware(GZipMiddleware, minimum_size=1000)


# Request timing middleware
@app.middleware("http")
async def add_process_time_header(request: Request, call_next):
    """Add request processing time header"""
    start_time = time.time()
    response = await call_next(request)
    process_time = time.time() - start_time
    response.headers["X-Process-Time"] = f"{process_time:.4f}"
    return response


# Request logging middleware
@app.middleware("http")
async def log_requests(request: Request, call_next):
    """Log all requests"""
    logger.info(f"{request.method} {request.url.path}")
    response = await call_next(request)
    logger.info(f"{request.method} {request.url.path} - {response.status_code}")
    return response


# =============================================================================
# EXCEPTION HANDLERS
# =============================================================================

@app.exception_handler(Exception)
async def global_exception_handler(request: Request, exc: Exception):
    """Global exception handler"""
    logger.error(f"Unhandled exception: {exc}", exc_info=True)

    if settings.debug_errors:
        # Detailed error in development
        return JSONResponse(
            status_code=500,
            content={
                "error": "Internal Server Error",
                "detail": str(exc),
                "type": type(exc).__name__
            }
        )
    else:
        # Generic error in production
        return JSONResponse(
            status_code=500,
            content={"error": "Internal Server Error"}
        )


# =============================================================================
# ROOT ENDPOINTS
# =============================================================================

@app.get("/", response_class=HTMLResponse)
async def root(request: Request):
    """Root endpoint - Serve web interface"""
    return templates.TemplateResponse("index.html", {"request": request})


@app.get("/api")
async def api_root():
    """API information endpoint"""
    return {
        "name": "GigLez API",
        "version": "1.0.0",
        "description": "IoT RF Device Mapping Platform",
        "mode": settings.mode.value,
        "docs": "/docs" if settings.debug_endpoints else "disabled",
        "status": "operational"
    }


@app.get("/health")
async def health():
    """Health check endpoint"""
    # Test database connection
    db_config = get_db_config()
    db_healthy = db_config.test_connection()

    return {
        "status": "healthy" if db_healthy else "unhealthy",
        "database": "connected" if db_healthy else "disconnected",
        "mode": settings.mode.value,
        "hardware_enabled": settings.enable_hardware
    }


@app.get("/version")
async def version():
    """Version information"""
    return {
        "version": "1.0.0",
        "mode": settings.mode.value,
        "api": "v1"
    }


# =============================================================================
# IMPORT ROUTERS
# =============================================================================

# Import and register route modules
from src.api.routes import captures, devices, query, stats

# Register routers
app.include_router(captures.router, prefix="/api/v1", tags=["captures"])
app.include_router(devices.router, prefix="/api/v1", tags=["devices"])
app.include_router(query.router, prefix="/api/v1", tags=["query"])
app.include_router(stats.router, prefix="/api/v1", tags=["statistics"])

# Hardware endpoints (development mode only)
if settings.enable_hardware:
    from src.api.routes import hardware
    app.include_router(hardware.router, prefix="/api/v1", tags=["hardware"])
    logger.info("✅ Hardware endpoints enabled")


# Debug endpoints (development mode only)
if settings.debug_endpoints:
    from src.api.routes import debug
    app.include_router(debug.router, prefix="/api/debug", tags=["debug"])
    logger.info("✅ Debug endpoints enabled")


# =============================================================================
# STARTUP MESSAGE
# =============================================================================

logger.info("FastAPI application initialized")
logger.info(f"Mode: {settings.mode.value}")
logger.info(f"Authentication: {'Required' if settings.require_auth else 'Optional'}")
logger.info(f"CORS Origins: {settings.cors_origins}")
logger.info(f"Storage: {settings.storage_type.value}")


# =============================================================================
# RUN WITH UVICORN (for development)
# =============================================================================

if __name__ == "__main__":
    import uvicorn

    uvicorn.run(
        "src.api.main:app",
        host=settings.api_host,
        port=settings.api_port,
        reload=settings.auto_reload,
        log_level=settings.log_level.lower(),
        access_log=True,
    )
