"""
MTG Online Backend Application

FastAPI application for the MTG Online multiplayer platform.
Mounts all routers and provides centralized configuration.

## Routers
- Authentication: /auth/*
- Users: /users/*
- Decks: /decks/*
- Rooms: /rooms/*
- Games: /games/*
- Admin: /admin/*
- MTG Cards: /api/cards/*
- Card Interactions: /interactions/*
"""
import asyncio
import logging
from contextlib import asynccontextmanager
from typing import AsyncGenerator

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

from app.core.settings import get_settings
from app.core.database import engine, mtg_engine, async_session, mtg_async_session
from app.routers import auth, users, decks, rooms, admin, card_router, interactions, refresh, user_data, card_import
from app.routers.games import router as games_router
from app.services.mtgjson_manager import MTGJSONManager


def setup_logging(debug: bool = False) -> None:
    """Configure application logging with verbose support."""
    level = logging.DEBUG if debug else logging.INFO
    
    logging.basicConfig(
        level=level,
        format='%(asctime)s - %(name)s - %(levelname)s - %(message)s',
        handlers=[
            logging.StreamHandler(),
        ]
    )
    
    if debug:
        logging.getLogger('sqlalchemy.engine').setLevel(logging.WARNING)
        logging.getLogger('sqlalchemy.pool').setLevel(logging.WARNING)
    
    logger = logging.getLogger(__name__)
    logger.info(f"Logging initialized at level {logging.getLevelName(level)}")


async def run_initial_download():
    """Run initial MTGJSON data download and upsert."""
    logger = logging.getLogger(__name__)
    
    try:
        settings = get_settings()
        manager = MTGJSONManager(settings.DATA_DIR)
        
        # Check if data already exists
        last_refresh = await manager.get_last_refresh()
        if last_refresh:
            logger.info(f"MTGJSON data already exists (last refresh: {last_refresh})")
            return
        
        logger.info("Running initial MTGJSON data download with sanity checks...")
        logger.info("This may take several minutes depending on network speed...")
        
        # Download files and upsert data in one operation
        result = await manager.download_and_refresh(force=False)
        
        if not result.get("success", False):
            error_msg = result.get("error", "Unknown error")
            logger.error(f"Failed to download MTGJSON files: {error_msg}")
            raise RuntimeError(f"MTGJSON data download failed: {error_msg}")
        
        # Log success
        counts = result.get("upsert", {})
        await manager.log_refresh("SUCCESS", counts, result.get("duration", 0))
        
        logger.info(f"Initial MTGJSON data load complete!")
        logger.info(f"  Sets: {counts.get('sets', 0)}")
        logger.info(f"  Cards: {counts.get('cards', 0)}")
        
    except Exception as e:
        logger.error(f"Failed to run initial download: {e}")
        raise


def lifespan(app: FastAPI) -> AsyncGenerator[None, None]:
    """Application lifespan events for startup and shutdown."""
    settings = get_settings()
    
    # Startup
    setup_logging(debug=settings.DEBUG)
    logger = logging.getLogger(__name__)
    logger.info(f"MTG Online Backend starting (v{settings.APP_VERSION})")
    logger.info(f"Database: {settings.DATABASE_URL.split('@')[1] if '@' in settings.DATABASE_URL else 'configured'}")
    logger.info(f"MTG Database: {settings.MTG_DATABASE_URL.split('@')[1] if '@' in settings.MTG_DATABASE_URL else 'configured'}")
    logger.info(f"Redis: {settings.REDIS_URL}")
    
    # Run initial download in background
    try:
        asyncio.create_task(run_initial_download())
    except RuntimeError:
        # Event loop already running
        asyncio.get_event_loop().create_task(run_initial_download())
    
    yield
    
    # Shutdown
    logger.info("Shutting down MTG Online Backend")
    # Engine disposal is handled by FastAPI's shutdown events


app = FastAPI(
    title="MTG Online Backend API",
    description="Backend API for the MTG Online multiplayer platform",
    version="0.2.0",
    lifespan=lifespan,
)

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


# Mount all routers
app.include_router(auth.router, prefix="/auth", tags=["Authentication"])
app.include_router(users.router, prefix="/users", tags=["Users"])
app.include_router(decks.router, prefix="/decks", tags=["Decks"])
app.include_router(rooms.router, prefix="/rooms", tags=["Rooms"])
app.include_router(games_router, prefix="/games", tags=["Games"])
app.include_router(admin.router, prefix="/admin", tags=["Admin"])
app.include_router(card_router.router, tags=["MTG Cards"])
app.include_router(interactions.router)
app.include_router(refresh.router)
app.include_router(user_data.router, prefix="/api/v1/user-data", tags=["User Data"])
app.include_router(card_import.router, prefix="/api/v1/card-import", tags=["Card Import"])

@app.get("/health", tags=["Health"])
async def health_check():
    """Health check endpoint with MTGJSON data status."""
    from app.services.mtgjson_manager import get_manager
    
    # Get MTGJSON health status
    try:
        manager = get_manager()
        mtg_status = await manager.get_health_status()
    except Exception as e:
        mtg_status = {
            "status": "unhealthy",
            "error": str(e),
        }
    
    return {
        "status": "healthy" if mtg_status.get("status") == "healthy" else "degraded",
        "version": settings.APP_VERSION,
        "mtgjson": mtg_status,
    }


@app.get("/", tags=["Root"])
async def root():
    """Root endpoint with API information."""
    return {
        "name": settings.APP_NAME,
        "version": settings.APP_VERSION,
        "docs": "/docs",
    }