# api.py — Thin orchestrator (routes live in routes/*.py)
#
# Monolith backup: api_monolith_backup.py
# To revert: cp api_monolith_backup.py api.py

from fastapi import FastAPI, Request
from fastapi.responses import JSONResponse
from fastapi.staticfiles import StaticFiles
from utils.logger import get_logger
from utils.log_config import load_config as load_log_config
import time
from fnmatch import fnmatch
import nest_asyncio
nest_asyncio.apply()

# Initialize API logger
logger = get_logger('api')
api_requests_logger = get_logger('api.requests')

app = FastAPI()

# ========== Global Exception Handler ==========
@app.exception_handler(Exception)
async def global_exception_handler(request: Request, exc: Exception):
    """Catch all unhandled exceptions and log them properly."""
    logger.error(f"Unhandled exception on {request.method} {request.url.path}: {exc}", exc_info=True)
    return JSONResponse(status_code=500, content={"success": False, "error": "Internal server error"})

# ========== Logging Middleware ==========
@app.middleware("http")
async def log_requests(request: Request, call_next):
    """Middleware to log HTTP requests based on configuration."""
    start_time = time.time()

    # Get logging config
    log_config = load_log_config()
    api_config = log_config.get('components', {}).get('api.requests', {})

    # Check if API request logging is enabled
    if not api_config.get('enabled', False):
        return await call_next(request)

    # Get filters
    filters = api_config.get('filters', {})
    exclude_paths = filters.get('exclude_paths', [])
    exclude_status = filters.get('exclude_status', [])
    include_slow_requests = filters.get('include_slow_requests', True)
    slow_threshold_ms = filters.get('slow_threshold_ms', 1000)

    # Process request
    response = await call_next(request)

    # Calculate duration
    duration_ms = (time.time() - start_time) * 1000

    # Check if path should be excluded
    path = request.url.path
    for pattern in exclude_paths:
        if fnmatch(path, pattern):
            return response

    # Check if status should be excluded (unless it's a slow request)
    is_slow = duration_ms >= slow_threshold_ms
    if response.status_code in exclude_status and not (include_slow_requests and is_slow):
        return response

    # Log the request
    log_msg = f"{request.method} {path} - {response.status_code} ({duration_ms:.2f}ms)"

    if is_slow:
        api_requests_logger.warning(f"SLOW REQUEST: {log_msg}")
    elif response.status_code >= 500:
        api_requests_logger.error(log_msg)
    elif response.status_code >= 400:
        api_requests_logger.warning(log_msg)
    else:
        api_requests_logger.api(log_msg)

    return response

# Serve static folder
app.mount("/static", StaticFiles(directory="static"), name="static")

# ========== Include Route Modules ==========
from routes.core import router as core_router
from routes.mood import router as mood_router
from routes.language import router as language_router
from routes.evil_mode import router as evil_mode_router
from routes.bipolar_mode import router as bipolar_mode_router
from routes.gpu import router as gpu_router
from routes.bot_actions import router as bot_actions_router
from routes.autonomous import router as autonomous_router
from routes.profile_picture import router as profile_picture_router
from routes.manual_send import router as manual_send_router
from routes.servers import router as servers_router
from routes.figurines import router as figurines_router
from routes.dms import router as dms_router
from routes.image_generation import router as image_generation_router
from routes.chat import router as chat_router
from routes.config import router as config_router
from routes.logging_config import router as logging_config_router
from routes.voice import router as voice_router
from routes.memory import router as memory_router
from routes.activities import router as activities_router
from routes.models_selector import router as models_selector_router

app.include_router(core_router)
app.include_router(mood_router)
app.include_router(language_router)
app.include_router(evil_mode_router)
app.include_router(bipolar_mode_router)
app.include_router(gpu_router)
app.include_router(bot_actions_router)
app.include_router(autonomous_router)
app.include_router(profile_picture_router)
app.include_router(manual_send_router)
app.include_router(servers_router)
app.include_router(figurines_router)
app.include_router(dms_router)
app.include_router(image_generation_router)
app.include_router(chat_router)
app.include_router(config_router)
app.include_router(logging_config_router)
app.include_router(voice_router)
app.include_router(memory_router)
app.include_router(activities_router)
app.include_router(models_selector_router)



def start_api():
    import uvicorn
    uvicorn.run(app, host="0.0.0.0", port=3939)
