"""
    Main FastAPI Application Entry Point for Search Coordinator Service 

    This module creates and configures the FastAPI application with all necessary middleware,
    routers, exception handlers, and startup/shutdown events.

    Features:
        - FastAPI application initialization
        - Middleware configuration
        - API router registration
        - Database connection management
        - Kafka client initialization
        - Background task setup
        - Error handling configuration
        - Health check endpoints 
        - CORS configuration

    Author: Sentinel Team
"""

import uvicorn
import logging
import asyncio

from fastapi import FastAPI
from contextlib import asynccontextmanager
from fastapi.middleware.cors import CORSMiddleware
from fastapi.exceptions import RequestValidationError
from starlette.exceptions import HTTPException as StarletteHTTPException

from typing import Dict
from app.core.config import settings
from app.core.kafka_client import kafka_client
from app.core.exceptions import SearchCoordinatorException
from app.infrastructure.cache.redis_cache import redis_cache
from app.infrastructure.kafka.consumer import search_results_consumer
from app.core.database import connect_to_mongo, close_mongo_connection
from app.infrastructure.monitoring.metrics import start_metrics_server
from app.infrastructure.external.scheduler_client import scheduler_service
from app.presentation.api.error_handlers import (
    search_coordinator_exception_handler,
    validation_exception_handler,
    http_exception_handler,
    general_exception_handler
)
from app.presentation.api import api_router

# Configure logging
logging.basicConfig(
    level=logging.INFO,
    format="%(asctime)s - %(name)s - %(levelname)s - %(message)s"
)
logger = logging.getLogger(__name__)


@asynccontextmanager
async def lifespan(app: FastAPI):
    """
        Application lifespan manager.
        
        Handles startup and shutdown events for the FastAPI application.
        
        Args:
            app: FastAPI application instance.
    """

    # Startup 
    logger.info("Starting Search Coordinator Service...")
    
    try:
        # Connect to MongoDB
        await connect_to_mongo()
        # Connect to Redis
        await redis_cache.connect()
        # Start Kafka producer
        await kafka_client.start_producer() 
        #!!! Start periodic scheduler
        await scheduler_service.start() 
        #!!! Start search results consumer
        asyncio.create_task(search_results_consumer.start()) 
        # Start metrics server
        await start_metrics_server(8001)
        logger.info("Search Coordinator Service started successfully")
    except Exception as e:
        logger.error(f"Error starting service: {e}")
        raise
    
    yield
    
    # Shutdown
    logger.info("Shutting down Search Coordinator Service...")
    try:
        # Stop search results consumer
        await search_results_consumer.stop()
        # Stop scheduler
        await scheduler_service.stop()
        # Close Redis connection
        await redis_cache.disconnect()
        # Close MongoDB connection
        await close_mongo_connection()
        # Stop Kafka producer
        await kafka_client.stop_producer()
        logger.info("Search Coordinator Service stopped")
    except Exception as e:
        logger.error(f"Error stopping service: {e}")
    finally:
        # Stop metrics server
        await metrics_server.stop()
        print("Need More Actions")


# Create FastAPI app
app = FastAPI(
    title=settings.APP_NAME,
    version=settings.VERSION,
    debug=settings.DEBUG,
    lifespan=lifespan
)

# Add exception handlers
app.add_exception_handler(SearchCoordinatorException, search_coordinator_exception_handler)
app.add_exception_handler(RequestValidationError, validation_exception_handler)
app.add_exception_handler(StarletteHTTPException, http_exception_handler)
app.add_exception_handler(Exception, general_exception_handler)

# Add CORS middleware
app.add_middleware(
    CORSMiddleware,
    allow_origins=settings.CORS_ORIGINS,
    allow_credentials=settings.CORS_ALLOW_CREDENTIALS,
    allow_methods=settings.CORS_ALLOW_METHODS,
    allow_headers=settings.CORS_ALLOW_HEADERS,
) 

# Include routers
app.include_router(api_router)

@app.get("/", include_in_schema=False)
async def root() -> Dict[str, str]:
    """Root endpoint.
    
    Returns:
        Dict[str, str]: Welcome message.
    """
    return {
        "message": "Welcome to Web Search Service",
        "service": settings.APP_NAME,
        "version": settings.VERSION,
        "status": "running",
        "docs": "/docs" if settings.DEBUG else "Documentation not available"
    }

if __name__ == "__main__":
    
    uvicorn.run(
        "app.main:app",
        host=settings.HOST,
        port=settings.PORT,
        reload=settings.DEBUG,
        log_level="info" if not settings.DEBUG else "debug"
    )
