""" Deck management routes """ from fastapi import APIRouter, Depends, HTTPException from sqlalchemy.orm import Session from pydantic import BaseModel from typing import List, Optional from app.database import get_db from app.models.deck import Deck, DeckCard from app.models.card import Card from app.models.user import User from app.routers.auth import get_current_user router = APIRouter() # Pydantic models class DeckResponse(BaseModel): id: int name: str description: Optional[str] format: Optional[str] game: str is_public: bool is_complete: bool is_favorite: bool total_cards: int avg_mana_cost: Optional[float] estimated_value: Optional[float] commander_card_id: Optional[int] class Config: from_attributes = True class DeckCreate(BaseModel): name: str game: str description: Optional[str] = None format: Optional[str] = None is_public: bool = False commander_card_id: Optional[int] = None class DeckCardResponse(BaseModel): id: int card_id: int card_name: str quantity: int is_sideboard: bool is_commander: bool category: Optional[str] notes: Optional[str] owned: bool need_to_acquire: bool class Config: from_attributes = True class DeckCardCreate(BaseModel): card_id: int quantity: int = 1 is_sideboard: bool = False is_commander: bool = False category: Optional[str] = None notes: Optional[str] = None # Routes @router.get("/", response_model=List[DeckResponse]) async def get_my_decks( current_user: User = Depends(get_current_user), db: Session = Depends(get_db) ): """Get current user's decks""" decks = db.query(Deck).filter(Deck.owner_id == current_user.id).all() return decks @router.get("/{deck_id}", response_model=DeckResponse) async def get_deck( deck_id: int, current_user: User = Depends(get_current_user), db: Session = Depends(get_db) ): """Get a specific deck""" deck = db.query(Deck).filter( Deck.id == deck_id, Deck.owner_id == current_user.id ).first() if not deck: raise HTTPException(status_code=404, detail="Deck not found") return deck @router.post("/", response_model=DeckResponse) async def create_deck( deck_data: DeckCreate, current_user: User = Depends(get_current_user), db: Session = Depends(get_db) ): """Create a new deck""" new_deck = Deck( **deck_data.dict(), owner_id=current_user.id ) db.add(new_deck) db.commit() db.refresh(new_deck) return new_deck @router.get("/{deck_id}/cards", response_model=List[DeckCardResponse]) async def get_deck_cards( deck_id: int, current_user: User = Depends(get_current_user), db: Session = Depends(get_db) ): """Get all cards in a deck""" # Verify deck ownership deck = db.query(Deck).filter( Deck.id == deck_id, Deck.owner_id == current_user.id ).first() if not deck: raise HTTPException(status_code=404, detail="Deck not found") # Get deck cards with card names cards = db.query(DeckCard, Card.name.label('card_name')).join( Card, DeckCard.card_id == Card.id ).filter(DeckCard.deck_id == deck_id).all() result = [] for dc, card_name in cards: dc_dict = dc.__dict__.copy() dc_dict['card_name'] = card_name result.append(DeckCardResponse(**dc_dict)) return result @router.post("/{deck_id}/cards", response_model=DeckCardResponse) async def add_card_to_deck( deck_id: int, card_data: DeckCardCreate, current_user: User = Depends(get_current_user), db: Session = Depends(get_db) ): """Add a card to a deck""" # Verify deck ownership deck = db.query(Deck).filter( Deck.id == deck_id, Deck.owner_id == current_user.id ).first() if not deck: raise HTTPException(status_code=404, detail="Deck not found") # Verify card exists card = db.query(Card).filter(Card.id == card_data.card_id).first() if not card: raise HTTPException(status_code=404, detail="Card not found") # Check if card already exists in deck (same sideboard status) existing_card = db.query(DeckCard).filter( DeckCard.deck_id == deck_id, DeckCard.card_id == card_data.card_id, DeckCard.is_sideboard == card_data.is_sideboard ).first() if existing_card: # Update quantity if card already exists existing_card.quantity += card_data.quantity db.commit() db.refresh(existing_card) # Add card name for response existing_card_dict = existing_card.__dict__.copy() existing_card_dict['card_name'] = card.name return DeckCardResponse(**existing_card_dict) else: # Create new deck card entry new_deck_card = DeckCard( deck_id=deck_id, **card_data.dict() ) db.add(new_deck_card) db.commit() db.refresh(new_deck_card) # Recalculate deck stats deck.calculate_stats() db.commit() # Add card name for response new_card_dict = new_deck_card.__dict__.copy() new_card_dict['card_name'] = card.name return DeckCardResponse(**new_card_dict) @router.put("/{deck_id}/calculate-stats") async def calculate_deck_stats( deck_id: int, current_user: User = Depends(get_current_user), db: Session = Depends(get_db) ): """Recalculate deck statistics""" deck = db.query(Deck).filter( Deck.id == deck_id, Deck.owner_id == current_user.id ).first() if not deck: raise HTTPException(status_code=404, detail="Deck not found") deck.calculate_stats() db.commit() return {"message": "Deck statistics updated"}