from fastapi import APIRouter, Depends, HTTPException from sqlalchemy.ext.asyncio import AsyncSession from sqlalchemy import select, func from app.core.database import get_db from app.core.deps import get_approved_user from app.models.user import User from app.models.deck import Deck, DeckCard from app.schemas.deck import DeckOut, DeckSummaryOut, GenerateRequest, CompleteRequest, CullRequest from app.services.ai.deck_service import generate_deck, complete_deck, cull_deck router = APIRouter() @router.post("/generate", response_model=DeckOut, status_code=201) async def api_generate( req: GenerateRequest, user: User = Depends(get_approved_user), db: AsyncSession = Depends(get_db), ): return await generate_deck(req, user.id, db) @router.post("/complete", response_model=DeckOut, status_code=201) async def api_complete( req: CompleteRequest, user: User = Depends(get_approved_user), db: AsyncSession = Depends(get_db), ): return await complete_deck(req, user.id, db) @router.post("/cull", response_model=DeckOut, status_code=201) async def api_cull( req: CullRequest, user: User = Depends(get_approved_user), db: AsyncSession = Depends(get_db), ): return await cull_deck(req, user.id, db) @router.get("/", response_model=dict) async def list_decks( page: int = 1, page_size: int = 20, user: User = Depends(get_approved_user), db: AsyncSession = Depends(get_db), ): total_result = await db.execute( select(func.count(Deck.id)).where(Deck.owner_id == user.id) ) total = total_result.scalar_one() result = await db.execute( select(Deck) .where(Deck.owner_id == user.id) .order_by(Deck.created_at.desc()) .offset((page - 1) * page_size) .limit(page_size) ) decks = result.scalars().all() items = [] for deck in decks: count_result = await db.execute( select(func.count(DeckCard.id)).where(DeckCard.deck_id == deck.id) ) items.append(DeckSummaryOut( id=deck.id, name=deck.name, commander=deck.commander, mode=deck.mode, playstyle=deck.playstyle, created_at=deck.created_at, card_count=count_result.scalar_one(), )) return { "items": [i.model_dump() for i in items], "total": total, "page": page, "page_size": page_size, "pages": max(1, -(-total // page_size)), } @router.get("/{deck_id}", response_model=DeckOut) async def get_deck( deck_id: int, user: User = Depends(get_approved_user), db: AsyncSession = Depends(get_db), ): result = await db.execute(select(Deck).where(Deck.id == deck_id, Deck.owner_id == user.id)) deck = result.scalar_one_or_none() if not deck: raise HTTPException(status_code=404, detail="Deck not found") cards_result = await db.execute(select(DeckCard).where(DeckCard.deck_id == deck_id)) deck.cards = cards_result.scalars().all() return deck @router.delete("/{deck_id}", status_code=204) async def delete_deck( deck_id: int, user: User = Depends(get_approved_user), db: AsyncSession = Depends(get_db), ): result = await db.execute(select(Deck).where(Deck.id == deck_id, Deck.owner_id == user.id)) deck = result.scalar_one_or_none() if not deck: raise HTTPException(status_code=404, detail="Deck not found") await db.delete(deck) await db.commit()