"""
FastAPI main application for chocolate tempering machine control system.
Provides REST API endpoints for system control and monitoring.
"""

import logging
from contextlib import asynccontextmanager
from typing import Dict, Any

from fastapi import FastAPI, Request, HTTPException
from fastapi.middleware.cors import CORSMiddleware
from fastapi.middleware.trustedhost import TrustedHostMiddleware
from fastapi.responses import JSONResponse
import uvicorn

from ...shared.config import settings
from ...shared.database import init_database, create_tables, close_database
from ..hardware.hardware_manager import hardware_manager
from ..recipe.recipe_controller import recipe_controller
from ..safety.safety_monitor import safety_monitor
from ..safety.error_handler import error_handler
from .routers import recipes, process, hardware, users, system, health


logger = logging.getLogger(__name__)


@asynccontextmanager
async def lifespan(app: FastAPI):
    """Application lifespan manager for startup and shutdown tasks."""
    # Startup
    logger.info("Starting chocolate tempering machine control system")
    
    try:
        # Initialize database
        init_database()
        await create_tables()
        logger.info("Database initialized")
        
        # Initialize hardware manager
        if await hardware_manager.initialize():
            logger.info("Hardware manager initialized")
        else:
            logger.error("Hardware manager initialization failed")
        
        # Initialize safety monitor
        if await safety_monitor.initialize():
            logger.info("Safety monitor initialized")
        else:
            logger.error("Safety monitor initialization failed")
        
        logger.info("System startup completed successfully")
        
    except Exception as e:
        logger.critical(f"System startup failed: {e}")
        raise
    
    yield
    
    # Shutdown
    logger.info("Shutting down chocolate tempering machine control system")
    
    try:
        # Stop any running recipes
        await recipe_controller.emergency_stop(reason="System shutdown")
        
        # Shutdown safety monitor
        await safety_monitor.shutdown()
        
        # Shutdown hardware manager
        await hardware_manager.shutdown()
        
        # Close database connections
        await close_database()
        
        logger.info("System shutdown completed")
        
    except Exception as e:
        logger.error(f"Error during shutdown: {e}")


# Create FastAPI application
app = FastAPI(
    title=settings.web.api_title,
    version=settings.web.api_version,
    description="Industrial chocolate tempering machine control system API",
    docs_url="/docs",
    redoc_url="/redoc",
    openapi_url="/openapi.json",
    lifespan=lifespan,
)

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

app.add_middleware(
    TrustedHostMiddleware,
    allowed_hosts=["*"]  # Configure appropriately for production
)


# Global exception handler
@app.exception_handler(Exception)
async def global_exception_handler(request: Request, exc: Exception):
    """Global exception handler for unhandled errors."""
    logger.error(f"Unhandled exception in {request.url}: {exc}")
    
    # Handle error through error handling system
    await error_handler.handle_error(exc, "web_api", {
        "url": str(request.url),
        "method": request.method,
        "client": request.client.host if request.client else "unknown"
    })
    
    return JSONResponse(
        status_code=500,
        content={
            "error": "Internal server error",
            "message": "An unexpected error occurred",
            "request_id": getattr(request.state, "request_id", "unknown")
        }
    )


# HTTP exception handler
@app.exception_handler(HTTPException)
async def http_exception_handler(request: Request, exc: HTTPException):
    """Handler for HTTP exceptions."""
    return JSONResponse(
        status_code=exc.status_code,
        content={
            "error": exc.detail,
            "status_code": exc.status_code
        }
    )


# Request ID middleware
@app.middleware("http")
async def add_request_id(request: Request, call_next):
    """Add request ID for tracing."""
    import uuid
    request_id = str(uuid.uuid4())
    request.state.request_id = request_id
    
    response = await call_next(request)
    response.headers["X-Request-ID"] = request_id
    
    return response


# Include routers
app.include_router(
    health.router,
    prefix="/health",
    tags=["health"]
)

app.include_router(
    recipes.router,
    prefix="/api/v1/recipes",
    tags=["recipes"]
)

app.include_router(
    process.router,
    prefix="/api/v1/process",
    tags=["process"]
)

app.include_router(
    hardware.router,
    prefix="/api/v1/hardware",
    tags=["hardware"]
)

app.include_router(
    users.router,
    prefix="/api/v1/users",
    tags=["users"]
)

app.include_router(
    system.router,
    prefix="/api/v1/system",
    tags=["system"]
)


# Root endpoint
@app.get("/", response_model=Dict[str, Any])
async def root():
    """Root endpoint with system information."""
    return {
        "name": settings.app_name,
        "version": settings.app_version,
        "environment": settings.environment,
        "api_version": "v1",
        "docs_url": "/docs",
        "health_url": "/health"
    }


# API info endpoint
@app.get("/api/v1/info", response_model=Dict[str, Any])
async def api_info():
    """API information endpoint."""
    return {
        "api_title": settings.web.api_title,
        "api_version": settings.web.api_version,
        "environment": settings.environment,
        "features": {
            "recipe_management": True,
            "process_control": True,
            "hardware_monitoring": True,
            "safety_monitoring": True,
            "user_management": True,
            "real_time_monitoring": True,
        },
        "endpoints": {
            "recipes": "/api/v1/recipes",
            "process": "/api/v1/process", 
            "hardware": "/api/v1/hardware",
            "users": "/api/v1/users",
            "system": "/api/v1/system",
            "health": "/health",
        }
    }


def create_app() -> FastAPI:
    """Factory function to create FastAPI app."""
    return app


def run_server():
    """Run the development server."""
    uvicorn.run(
        "tempering_machine.services.web.main:app",
        host=settings.web.host,
        port=settings.web.port,
        reload=settings.web.reload,
        workers=settings.web.workers if not settings.web.reload else 1,
        access_log=settings.web.access_log,
        log_level=settings.log_level.lower(),
    )


if __name__ == "__main__":
    run_server()