from contextlib import asynccontextmanager

from fastapi import FastAPI

from config.settings import settings
from config.logger import logger

from models.model_manager import ModelManager

# Routers
from api.health import router as health_router
from api.detect import router as detect_router
from api.embed import router as embed_router
from api.train import router as train_router
from api.recognize import router as recognize_router

# Middlewares
from middlewares.request_context import RequestContextMiddleware

# Exception Handlers
from handlers.exception_handler import (
    ai_exception_handler,
    general_exception_handler
)



from utils.exceptions import AIException


# ==================================================
# Application Lifespan
# ==================================================

@asynccontextmanager
async def lifespan(app: FastAPI):

    logger.info("Starting AI Service...")

    ModelManager.load_model()

    logger.info("AI Service Ready.")

    yield

    logger.info("Stopping AI Service...")


# ==================================================
# FastAPI Application
# ==================================================

app = FastAPI(

    title=settings.APP_NAME,

    version=settings.VERSION,

    lifespan=lifespan

)


# ==================================================
# Middlewares
# ==================================================

app.add_middleware(

    RequestContextMiddleware

)


# ==================================================
# Exception Handlers
# ==================================================

app.add_exception_handler(

    AIException,

    ai_exception_handler

)

app.add_exception_handler(

    Exception,

    general_exception_handler

)


# ==================================================
# Routers
# ==================================================

app.include_router(

    health_router,

    prefix="/api/v1",

    tags=["Health"]

)

app.include_router(

    detect_router,

    prefix="/api/v1",

    tags=["Face Detection"]

)

app.include_router(
    embed_router,
    prefix="/api/v1",
    tags=["Embedding"]
)

app.include_router(

    train_router,

    prefix="/api/v1",

    tags=["Training"]

)

app.include_router(

    recognize_router,

    prefix="/api/v1",

    tags=["Recognition"]

)


# ==================================================
# Root Endpoint
# ==================================================

@app.get("/")

async def root():

    return {

        "success": True,

        "service": settings.APP_NAME,

        "version": settings.VERSION,

        "status": "running"

    }