from typing import Optional, List from pydantic import BaseModel from datetime import datetime # Player schemas class PlayerCreate(BaseModel): name: str contact: Optional[str] = None skill_level: str = "Beginner" class PlayerUpdate(BaseModel): name: Optional[str] = None contact: Optional[str] = None skill_level: Optional[str] = None class PlayerOut(BaseModel): id: int name: str contact: Optional[str] skill_level: str matches_played: int wins: int losses: int elo: float created_at: datetime class Config: from_attributes = True # Court schemas class CourtCreate(BaseModel): name: str court_type: str = "Sport Court" class CourtStatusUpdate(BaseModel): status: str # available/in_use/reserved/maintenance class ReservationCreate(BaseModel): player_id: Optional[int] = None group_name: Optional[str] = None start_time: datetime end_time: datetime notes: Optional[str] = None class ReservationOut(BaseModel): id: int court_id: int player_id: Optional[int] group_name: Optional[str] start_time: datetime end_time: datetime notes: Optional[str] player: Optional[PlayerOut] = None class Config: from_attributes = True class CourtOut(BaseModel): id: int name: str court_type: str status: str reservations: List[ReservationOut] = [] class Config: from_attributes = True # Event schemas class EventCreate(BaseModel): name: str format: str = "Singles" courts_count: int = 1 class EventUpdate(BaseModel): name: Optional[str] = None format: Optional[str] = None courts_count: Optional[int] = None class EventPlayerAdd(BaseModel): player_id: int skill_level_override: Optional[str] = None class EventPlayerOut(BaseModel): id: int player_id: int skill_level_override: Optional[str] player: PlayerOut class Config: from_attributes = True # Stage schemas class StageCreate(BaseModel): name: str match_type: str # Open/Skill-Based/Round Robin/Tournament rounds: int = 1 advance_count: int = 0 order: int = 0 class StageUpdate(BaseModel): name: Optional[str] = None match_type: Optional[str] = None rounds: Optional[int] = None advance_count: Optional[int] = None class StageOut(BaseModel): id: int event_id: int name: str match_type: str rounds: int advance_count: int status: str order: int class Config: from_attributes = True # Match schemas class MatchScoreUpdate(BaseModel): score1: int score2: int class MatchCourtAssign(BaseModel): court_id: Optional[int] class MatchOut(BaseModel): id: int stage_id: int court_id: Optional[int] round_number: int match_number: int player1_id: Optional[int] player2_id: Optional[int] team1_players: Optional[List[int]] team2_players: Optional[List[int]] score1: Optional[int] score2: Optional[int] winner_id: Optional[int] winner_team: Optional[int] status: str bracket_position: Optional[str] next_winner_match_id: Optional[int] next_loser_match_id: Optional[int] scheduled_time: Optional[datetime] started_at: Optional[datetime] completed_at: Optional[datetime] player1: Optional[PlayerOut] = None player2: Optional[PlayerOut] = None class Config: from_attributes = True # Dashboard schema class DashboardCourtData(BaseModel): court: CourtOut current_match: Optional[MatchOut] = None elapsed_seconds: Optional[int] = None class DashboardData(BaseModel): courts: List[DashboardCourtData] upcoming_matches: List[MatchOut] active_event: Optional[dict] = None