""" Player Router - Refactored Thin HTTP layer using PlayerService for business logic. """ from fastapi import APIRouter, Query, Response, Depends from typing import Optional, List from ..dependencies import ( oauth2_scheme, cache_result, handle_db_errors, MAX_LIMIT, DEFAULT_LIMIT, ) from ..services.base import BaseService from ..services.player_service import PlayerService router = APIRouter(prefix="/api/v3/players", tags=["players"]) @router.get("") @handle_db_errors @cache_result(ttl=30 * 60, key_prefix="players") async def get_players( season: Optional[int] = None, name: Optional[str] = None, team_id: list = Query(default=None), pos: list = Query(default=None), strat_code: list = Query(default=None), is_injured: Optional[bool] = None, sort: Optional[str] = None, limit: int = Query(default=DEFAULT_LIMIT, ge=1, le=MAX_LIMIT), offset: Optional[int] = Query( default=None, ge=0, description="Number of results to skip for pagination" ), short_output: Optional[bool] = False, csv: Optional[bool] = False, ): """Get players with filtering and sorting.""" result = PlayerService.get_players( season=season, team_id=team_id if team_id else None, pos=pos if pos else None, strat_code=strat_code if strat_code else None, name=name, is_injured=is_injured, sort=sort, limit=limit, offset=offset, short_output=short_output or False, as_csv=csv or False, ) if csv: return Response(content=result, media_type="text/csv") return result @router.get("/search") @handle_db_errors @cache_result(ttl=15 * 60, key_prefix="players-search") async def search_players( q: str = Query(..., description="Search query for player name"), season: Optional[int] = Query( default=None, description="Season to search (0 for all)" ), limit: int = Query(default=10, ge=1, le=50), short_output: bool = False, ): """Search players by name with fuzzy matching.""" return PlayerService.search_players( query_str=q, season=season, limit=limit, short_output=short_output ) @router.get("/{player_id}") @handle_db_errors @cache_result(ttl=30 * 60, key_prefix="player") async def get_one_player(player_id: int, short_output: Optional[bool] = False): """Get a single player by ID.""" return PlayerService.get_player(player_id, short_output=short_output or False) @router.put("/{player_id}") async def put_player( player_id: int, new_player: dict, token: str = Depends(oauth2_scheme) ): """Update a player (full replacement).""" return PlayerService.update_player(player_id, new_player, token) @router.patch("/{player_id}") async def patch_player( player_id: int, token: str = Depends(oauth2_scheme), name: Optional[str] = None, wara: Optional[float] = None, image: Optional[str] = None, image2: Optional[str] = None, team_id: Optional[int] = None, season: Optional[int] = None, pos_1: Optional[str] = None, pos_2: Optional[str] = None, pos_3: Optional[str] = None, pos_4: Optional[str] = None, pos_5: Optional[str] = None, pos_6: Optional[str] = None, pos_7: Optional[str] = None, pos_8: Optional[str] = None, vanity_card: Optional[str] = None, headshot: Optional[str] = None, il_return: Optional[str] = None, demotion_week: Optional[int] = None, strat_code: Optional[str] = None, bbref_id: Optional[str] = None, injury_rating: Optional[str] = None, sbaref_id: Optional[int] = None, ): """Patch a player (partial update).""" # Build dict of provided fields data = { key: value for key, value in { "name": name, "wara": wara, "image": image, "image2": image2, "team_id": team_id, "season": season, "pos_1": pos_1, "pos_2": pos_2, "pos_3": pos_3, "pos_4": pos_4, "pos_5": pos_5, "pos_6": pos_6, "pos_7": pos_7, "pos_8": pos_8, "vanity_card": vanity_card, "headshot": headshot, "il_return": il_return, "demotion_week": demotion_week, "strat_code": strat_code, "bbref_id": bbref_id, "injury_rating": injury_rating, "sbaref_id": sbaref_id, }.items() if value is not None } return PlayerService.patch_player(player_id, data, token) @router.post("/") async def post_players(p_list: dict, token: str = Depends(oauth2_scheme)): """Create multiple players.""" return PlayerService.create_players(p_list.get("players", []), token) @router.delete("/{player_id}") async def delete_player(player_id: int, token: str = Depends(oauth2_scheme)): """Delete a player.""" return PlayerService.delete_player(player_id, token)