from typing import Optional from fastapi import APIRouter, Depends, HTTPException, Query from sqlalchemy import select, func from sqlalchemy.ext.asyncio import AsyncSession from ..database import get_db from ..db_models import Background, Difficulty from ..schemas import ( BackgroundCreate, BackgroundUpdate, BackgroundResponse, BackgroundListResponse, ) router = APIRouter(prefix="/backgrounds", tags=["backgrounds"]) @router.get("", response_model=BackgroundListResponse) async def list_backgrounds( skip: int = Query(0, ge=0), limit: int = Query(100, ge=1, le=500), difficulty: Optional[Difficulty] = None, search: Optional[str] = None, db: AsyncSession = Depends(get_db), ): """List all backgrounds with pagination and filtering.""" query = select(Background) if difficulty: query = query.where(Background.difficulty == difficulty) if search: query = query.where(Background.name.ilike(f"%{search}%")) # Count total count_query = select(func.count(Background.id)) if difficulty: count_query = count_query.where(Background.difficulty == difficulty) if search: count_query = count_query.where(Background.name.ilike(f"%{search}%")) total_result = await db.execute(count_query) total = total_result.scalar() # Get items query = query.order_by(Background.difficulty, Background.name) query = query.offset(skip).limit(limit) result = await db.execute(query) backgrounds = result.scalars().all() return BackgroundListResponse(backgrounds=backgrounds, total=total) @router.get("/{background_id}", response_model=BackgroundResponse) async def get_background(background_id: int, db: AsyncSession = Depends(get_db)): """Get a single background by ID.""" query = select(Background).where(Background.id == background_id) result = await db.execute(query) background = result.scalar_one_or_none() if not background: raise HTTPException(status_code=404, detail="Background not found") return background @router.post("", response_model=BackgroundResponse, status_code=201) async def create_background(data: BackgroundCreate, db: AsyncSession = Depends(get_db)): """Create a new background.""" background = Background( name=data.name, video_file=data.video_file, difficulty=data.difficulty, ) db.add(background) await db.commit() await db.refresh(background) return background @router.put("/{background_id}", response_model=BackgroundResponse) async def update_background( background_id: int, data: BackgroundUpdate, db: AsyncSession = Depends(get_db), ): """Update a background.""" query = select(Background).where(Background.id == background_id) result = await db.execute(query) background = result.scalar_one_or_none() if not background: raise HTTPException(status_code=404, detail="Background not found") # Update fields if data.name is not None: background.name = data.name if data.video_file is not None: background.video_file = data.video_file if data.difficulty is not None: background.difficulty = data.difficulty await db.commit() await db.refresh(background) return background @router.delete("/{background_id}", status_code=204) async def delete_background(background_id: int, db: AsyncSession = Depends(get_db)): """Delete a background.""" query = select(Background).where(Background.id == background_id) result = await db.execute(query) background = result.scalar_one_or_none() if not background: raise HTTPException(status_code=404, detail="Background not found") await db.delete(background) await db.commit() @router.get("/by-difficulty/{difficulty}", response_model=BackgroundListResponse) async def get_backgrounds_by_difficulty( difficulty: Difficulty, db: AsyncSession = Depends(get_db), ): """Get all backgrounds for a specific difficulty.""" query = select(Background).where(Background.difficulty == difficulty) query = query.order_by(Background.name) result = await db.execute(query) backgrounds = result.scalars().all() return BackgroundListResponse(backgrounds=backgrounds, total=len(backgrounds))