"""mockupAWS main application entry point."""

from contextlib import asynccontextmanager

from fastapi import FastAPI, Request, Response
from fastapi.middleware.cors import CORSMiddleware
from fastapi.responses import JSONResponse

from src.core.exceptions import setup_exception_handlers
from src.core.config import settings
from src.core.cache import cache_manager
from src.core.monitoring import MetricsMiddleware
from src.core.logging_config import setup_logging, get_logger, set_correlation_id
from src.core.tracing import setup_tracing, instrument_fastapi
from src.core.security_headers import setup_security_middleware
from src.api.v1 import api_router as api_router_v1
from src.api.v2 import api_router as api_router_v2


logger = get_logger(__name__)


@asynccontextmanager
async def lifespan(app: FastAPI):
    """Application lifespan manager."""
    # Startup
    logger.info("Starting up mockupAWS", extra={"version": settings.app_version})

    # Initialize cache
    await cache_manager.initialize()
    logger.info("Cache manager initialized")

    # Setup tracing
    setup_tracing()
    logger.info("Tracing initialized")

    yield

    # Shutdown
    logger.info("Shutting down mockupAWS")

    # Close cache connection
    await cache_manager.close()
    logger.info("Cache manager closed")


# Create FastAPI app
app = FastAPI(
    title=settings.app_name,
    description="AWS Cost Simulation Platform",
    version=settings.app_version,
    docs_url="/docs" if settings.debug else None,
    redoc_url="/redoc" if settings.debug else None,
    lifespan=lifespan,
)

# Setup logging
setup_logging()

# Setup security middleware
setup_security_middleware(app)

# Setup CORS
app.add_middleware(
    CORSMiddleware,
    allow_origins=settings.cors_allowed_origins
    if settings.debug
    else settings.cors_allowed_origins_production,
    allow_credentials=True,
    allow_methods=["GET", "POST", "PUT", "DELETE", "PATCH", "OPTIONS"],
    allow_headers=[
        "Authorization",
        "Content-Type",
        "X-Request-ID",
        "X-Correlation-ID",
        "X-API-Key",
        "X-Scenario-ID",
    ],
    expose_headers=[
        "X-Request-ID",
        "X-Correlation-ID",
        "X-RateLimit-Limit",
        "X-RateLimit-Remaining",
        "X-RateLimit-Reset",
    ],
)

# Setup tracing
instrument_fastapi(app)

# Setup exception handlers
setup_exception_handlers(app)


@app.middleware("http")
async def correlation_id_middleware(request: Request, call_next):
    """Add correlation ID to all requests."""
    # Get or create correlation ID
    correlation_id = request.headers.get("X-Correlation-ID") or request.headers.get(
        "X-Request-ID"
    )
    correlation_id = set_correlation_id(correlation_id)

    # Process request
    start_time = __import__("time").time()

    try:
        response = await call_next(request)

        # Add correlation ID to response
        response.headers["X-Correlation-ID"] = correlation_id

        # Log request
        duration_ms = (__import__("time").time() - start_time) * 1000
        logger.info(
            "Request processed",
            extra={
                "method": request.method,
                "path": request.url.path,
                "status_code": response.status_code,
                "duration_ms": duration_ms,
                "correlation_id": correlation_id,
            },
        )

        return response

    except Exception as e:
        logger.error(
            "Request failed",
            extra={
                "method": request.method,
                "path": request.url.path,
                "error": str(e),
                "correlation_id": correlation_id,
            },
        )
        raise


# Include API routes
app.include_router(api_router_v1, prefix="/api/v1")
app.include_router(api_router_v2, prefix="/api/v2")


@app.get("/health", tags=["health"])
async def health_check():
    """Health check endpoint."""
    return {
        "status": "healthy",
        "version": settings.app_version,
        "timestamp": __import__("datetime").datetime.utcnow().isoformat(),
    }


@app.get("/", tags=["root"])
async def root():
    """Root endpoint."""
    return {
        "name": settings.app_name,
        "version": settings.app_version,
        "description": "AWS Cost Simulation Platform",
        "documentation": "/docs",
        "health": "/health",
    }


# API deprecation notice
@app.get("/api/deprecation", tags=["info"])
async def deprecation_info():
    """Get API deprecation information."""
    return {
        "current_version": "v2",
        "deprecated_versions": ["v1"],
        "v1_deprecation_date": "2026-12-31",
        "v1_sunset_date": "2027-06-30",
        "migration_guide": "/docs/migration/v1-to-v2",
    }
