"""Mantimon TCG - FastAPI Application Entry Point.

This module configures and starts the FastAPI application with:
- Database initialization and cleanup
- Redis connection management
- Card service loading
- CORS middleware
- API routers

Usage:
    uvicorn app.main:app --reload
"""

import logging
from collections.abc import AsyncGenerator
from contextlib import asynccontextmanager

from fastapi import FastAPI
from fastapi.middleware.cors import CORSMiddleware

from app.api.auth import router as auth_router
from app.api.collections import router as collections_router
from app.api.decks import router as decks_router
from app.api.games import router as games_router
from app.api.users import router as users_router
from app.config import settings
from app.db import close_db, init_db
from app.db.redis import close_redis, init_redis
from app.services import get_card_service
from app.socketio import create_socketio_app

logger = logging.getLogger(__name__)


@asynccontextmanager
async def lifespan(app: FastAPI) -> AsyncGenerator[None, None]:
    """Application lifespan context manager.

    Handles startup and shutdown events:
    - Startup: Initialize DB, Redis, and load cards
    - Shutdown: Close DB and Redis connections

    Args:
        app: The FastAPI application instance.

    Yields:
        None - Control returns to the application during its lifetime.
    """
    # === STARTUP ===
    logger.info("Starting Mantimon TCG server...")

    # Initialize database connection pool
    logger.info("Initializing database...")
    await init_db()
    logger.info("Database initialized")

    # Initialize Redis connection pool
    logger.info("Initializing Redis...")
    await init_redis()
    logger.info("Redis initialized")

    # Load card definitions into memory
    logger.info("Loading card definitions...")
    card_service = get_card_service()
    await card_service.load_all()
    card_count = len(card_service.get_all_cards())
    logger.info(f"Loaded {card_count} card definitions")

    logger.info("Mantimon TCG server started successfully")

    yield  # Application runs here

    # === SHUTDOWN ===
    logger.info("Shutting down Mantimon TCG server...")

    # Close Redis connections
    logger.info("Closing Redis connections...")
    await close_redis()
    logger.info("Redis connections closed")

    # Close database connections
    logger.info("Closing database connections...")
    await close_db()
    logger.info("Database connections closed")

    logger.info("Mantimon TCG server shutdown complete")


# Create FastAPI application with lifespan
app = FastAPI(
    title="Mantimon TCG",
    description="A home-rule-modified Pokemon Trading Card Game API",
    version="0.1.0",
    lifespan=lifespan,
    docs_url="/docs" if settings.is_development else None,
    redoc_url="/redoc" if settings.is_development else None,
)

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


# === Health Check Endpoints ===


@app.get("/health")
async def health_check() -> dict[str, str]:
    """Basic health check endpoint.

    Returns:
        Health status indicating the server is running.
    """
    return {"status": "healthy"}


@app.get("/health/ready")
async def readiness_check() -> dict[str, str | int]:
    """Readiness check with service status.

    Verifies that all required services are available:
    - Database connection
    - Redis connection
    - Card service loaded

    Returns:
        Detailed status of each service.
    """
    from app.db import get_engine
    from app.db.redis import get_pool

    status: dict[str, str | int] = {"status": "ready"}

    # Check database
    try:
        get_engine()  # Raises RuntimeError if not initialized
        status["database"] = "connected"
    except RuntimeError:
        status["database"] = "not initialized"
        status["status"] = "not ready"

    # Check Redis
    try:
        get_pool()  # Raises RuntimeError if not initialized
        status["redis"] = "connected"
    except RuntimeError:
        status["redis"] = "not initialized"
        status["status"] = "not ready"

    # Check card service
    card_service = get_card_service()
    card_count = len(card_service.get_all_cards())
    if card_count > 0:
        status["cards_loaded"] = card_count
    else:
        status["cards_loaded"] = 0
        status["status"] = "not ready"

    return status


# === API Routers ===
app.include_router(auth_router, prefix="/api")
app.include_router(users_router, prefix="/api")
app.include_router(collections_router, prefix="/api")
app.include_router(decks_router, prefix="/api")
app.include_router(games_router, prefix="/api")

# TODO: Add remaining routers in future phases
# from app.api import cards, campaign
# app.include_router(cards.router, prefix="/api/cards", tags=["cards"])
# app.include_router(campaign.router, prefix="/api/campaign", tags=["campaign"])


# === Socket.IO Integration ===
# Wrap FastAPI with Socket.IO ASGI app for WebSocket support.
# The combined app handles:
# - WebSocket connections at /socket.io/
# - HTTP requests passed through to FastAPI
#
# Note: The module-level 'app' variable is now the combined ASGI app.
# This is intentional - uvicorn imports 'app' and will serve both
# FastAPI HTTP routes and Socket.IO WebSocket connections.
_fastapi_app = app
app = create_socketio_app(_fastapi_app)
