from fastapi import APIRouter, HTTPException, Depends from sqlalchemy.ext.asyncio import AsyncSession from sqlalchemy import select from datetime import date from typing import Dict, List from app.models.base import get_db from app.models.question import Question from app.models.category import Category from app.schemas.game import RoomCreate, RoomJoin, GameState from app.services.achievement_manager import achievement_manager from app.schemas.achievement import AchievementResponse router = APIRouter() @router.get("/categories") async def get_game_categories(db: AsyncSession = Depends(get_db)): """Get all categories for the game board.""" result = await db.execute(select(Category).order_by(Category.id)) categories = result.scalars().all() return [ { "id": cat.id, "name": cat.name, "icon": cat.icon, "color": cat.color } for cat in categories ] @router.get("/board/{room_code}") async def get_game_board(room_code: str, db: AsyncSession = Depends(get_db)): """ Get the game board with questions for today. Returns questions grouped by category. """ from app.services.room_manager import room_manager room = await room_manager.get_room(room_code) if not room: raise HTTPException(status_code=404, detail="Room not found") # If board already exists in room, return it if room.get("board"): return room["board"] # Load today's questions from database today = date.today() result = await db.execute( select(Question, Category) .join(Category, Question.category_id == Category.id) .where(Question.date_active == today) .where(Question.status == "approved") .order_by(Category.id, Question.difficulty) ) rows = result.all() board = {} for question, category in rows: cat_id = str(category.id) if cat_id not in board: board[cat_id] = [] board[cat_id].append({ "id": question.id, "difficulty": question.difficulty, "points": question.points, "time_seconds": question.time_seconds, "answered": False }) return board @router.get("/today-questions") async def get_today_questions(db: AsyncSession = Depends(get_db)): """ Get all approved questions for today, grouped by category and difficulty. This is used to build the game board. """ today = date.today() # Get all approved questions for today result = await db.execute( select(Question, Category) .join(Category, Question.category_id == Category.id) .where(Question.date_active == today) .where(Question.status == "approved") .order_by(Category.id, Question.difficulty) ) rows = result.all() categories = {} for question, category in rows: cat_id = str(category.id) if cat_id not in categories: categories[cat_id] = { "name": category.name, "icon": category.icon, "color": category.color, "questions": [] } categories[cat_id]["questions"].append({ "difficulty": question.difficulty, "id": question.id, "points": question.points }) return { "date": str(today), "categories": categories } @router.get("/question/{question_id}") async def get_question(question_id: int, db: AsyncSession = Depends(get_db)): """ Get a specific question (without the answer). Used when a player selects a question. """ result = await db.execute( select(Question).where(Question.id == question_id) ) question = result.scalar_one_or_none() if not question: raise HTTPException(status_code=404, detail="Question not found") return { "id": question.id, "question_text": question.question_text, "difficulty": question.difficulty, "points": question.points, "time_seconds": question.time_seconds, "category_id": question.category_id, "fun_fact": question.fun_fact } @router.get("/achievements", response_model=list[AchievementResponse]) async def get_achievements(db: AsyncSession = Depends(get_db)): """Obtiene lista de todos los logros disponibles""" achievements = await achievement_manager.get_all_achievements(db) return achievements