from fastapi import Depends, FastAPI, Request, status
from fastapi.middleware.cors import CORSMiddleware
from fastapi.middleware.trustedhost import TrustedHostMiddleware
from fastapi.responses import JSONResponse
from fastapi.exceptions import RequestValidationError
from contextlib import asynccontextmanager
import os
import time

from dotenv import load_dotenv
from pif_compiler.functions.common_log import get_logger

load_dotenv()

# Import dei tuoi router
from pif_compiler.api.routes import api_echa, api_cosing, common, api_ingredients, api_esposition, api_orders, api_auth
from pif_compiler.functions.auth import get_current_user

# Configurazione logging
logger = get_logger()

# Lifespan events (startup/shutdown) - moderna alternativa a @app.on_event
@asynccontextmanager
async def lifespan(app: FastAPI):
    # Startup
    logger.info("🚀 Starting up API...")
    # Qui puoi inizializzare:
    # - Connessioni al database
    
    yield  # L'app gira qui
    
    # Shutdown
    logger.info("👋 Shutting down API...")
    # Qui chiudi le connessioni e fai cleanup
    # - Chiudi DB connections
    # - Salva cache
    # - Cleanup risorse


ENVIRONMENT = os.getenv("ENVIRONMENT", "production")
ALLOWED_ORIGINS = [
    "http://127.0.0.1",
    "https://lmb.cosmoguard.it",
    "http://localhost:8501",   # Streamlit locale
]
TRUSTED_HOSTS = [
    "lmb.cosmoguard.it",
    "http://localhost",
    "http://127.0.0.1",
    "*"
]

# Inizializza FastAPI
app = FastAPI(
    title="Comsoguard API",
    description="Central API for Comsoguard services",
    version="0.0.1",
    docs_url="/docs" if ENVIRONMENT == "development" else None,
    redoc_url="/redoc" if ENVIRONMENT == "development" else None,
    openapi_url="/openapi.json" if ENVIRONMENT == "development" else None,
    lifespan=lifespan
)


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

# 1. Trusted Host — rifiuta richieste con Host header non autorizzato
app.add_middleware(TrustedHostMiddleware, allowed_hosts=TRUSTED_HOSTS)

# 2. CORS — solo origine autorizzata
app.add_middleware(
    CORSMiddleware,
    allow_origins=ALLOWED_ORIGINS,
    allow_credentials=True,
    allow_methods=["GET", "POST", "DELETE"],
    allow_headers=["*"],
)


# 2. Logging Middleware - Log di tutte le richieste
@app.middleware("http")
async def log_requests(request: Request, call_next):
    start_time = time.time()
    
    # Log della richiesta in arrivo
    logger.info(
        f"📥 {request.method} {request.url.path} - "
        f"Client: {request.client.host}"
    )
    
    # Esegui la richiesta
    response = await call_next(request)
    
    # Calcola il tempo di elaborazione
    process_time = time.time() - start_time
    
    # Log della risposta
    logger.info(
        f"📤 {request.method} {request.url.path} - "
        f"Status: {response.status_code} - "
        f"Time: {process_time:.3f}s"
    )
    
    return response


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

# Handler per errori di validazione (422)
@app.exception_handler(RequestValidationError)
async def validation_exception_handler(request: Request, exc: RequestValidationError):
    logger.warning(f"❌ Validation error on {request.url.path}: {exc.errors()}")
    return JSONResponse(
        status_code=status.HTTP_422_UNPROCESSABLE_ENTITY,
        content={
            "error": "Validation Error",
            "detail": exc.errors(),
            "body": exc.body
        }
    )


# Handler per errori generici
@app.exception_handler(Exception)
async def general_exception_handler(request: Request, exc: Exception):
    logger.error(f"💥 Unhandled exception on {request.url.path}: {str(exc)}", exc_info=True)
    return JSONResponse(
        status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
        content={
            "error": "Internal Server Error",
            "message": "Si è verificato un errore imprevisto. Riprova più tardi."
        }
    )


# ==================== ROUTERS ====================

_auth = [Depends(get_current_user)]

# Auth — pubblico (login, refresh, logout non richiedono token)
app.include_router(api_auth.router, prefix="/api/v1")

# Tutti gli altri router richiedono JWT valido
app.include_router(
    api_echa.router,
    prefix="/api/v1",
    tags=["ECHA"],
    dependencies=_auth,
)

app.include_router(
    api_cosing.router,
    prefix="/api/v1",
    tags=["COSING"],
    dependencies=_auth,
)

app.include_router(
    common.router,
    prefix="/api/v1",
    tags=["Common"],
    dependencies=_auth,
)

app.include_router(
    api_ingredients.router,
    prefix="/api/v1",
    tags=["Ingredients"],
    dependencies=_auth,
)

app.include_router(
    api_esposition.router,
    prefix="/api/v1",
    tags=["Esposition"],
    dependencies=_auth,
)

app.include_router(
    api_orders.router,
    prefix="/api/v1",
    tags=["Orders"],
    dependencies=_auth,
)

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

@app.get("/", tags=["Root"])
async def root():
    """
    Endpoint di benvenuto - mostra info base dell'API
    """
    return {
        "message": "Welcome to Comsoguard API",
        "version": "0.0.1",
        "docs": "/docs",
        "redoc": "/redoc"
    }


@app.get("/health", tags=["Health"])
async def health_check():
    """
    Health check endpoint - utile per monitoring e load balancers
    """
    return {
        "status": "healthy",
        "service": "comsoguard-api",
        "version": "0.0.1"
    }


@app.get("/ping", tags=["Health"])
async def ping():
    """
    Ping endpoint - risposta velocissima per verificare che l'API sia up
    """
    return {"ping": "pong"}


# ==================== RUN SERVER ====================

if __name__ == "__main__":
    import uvicorn
    uvicorn.run(
        "pif_compiler.main:app",
        host="0.0.0.0",
        port=8000,
        reload=True,  # Auto-reload on code changes during development
        log_level="info"
    )