from __future__ import annotations from datetime import datetime from pydantic import BaseModel, Field class SessionResponse(BaseModel): authenticated: bool provider: str | None = None is_admin: bool = False external_user_id: str | None = None external_team_id: str | None = None external_player_id: str | None = None token_expires_at: datetime | None = None class TeamSnapTokenResponse(BaseModel): access_token: str expires_at: datetime | None = None api_root: str auth_url: str class WalkupSessionSelectionUpdate(BaseModel): external_team_id: str = Field(min_length=1, max_length=128) external_player_id: str = Field(min_length=1, max_length=128) class AdminLoginRequest(BaseModel): username: str password: str class AudioAssetResponse(BaseModel): id: int external_team_id: str owner_external_player_id: str title: str original_filename: str mime_type: str size_bytes: int created_at: datetime class AudioAssetUpdate(BaseModel): title: str = Field(min_length=1, max_length=255) class AudioAssetImportCreate(BaseModel): external_team_id: str owner_external_player_id: str url: str = Field(min_length=1) title: str | None = Field(default=None, min_length=1, max_length=255) class AudioClipCreate(BaseModel): asset_id: int external_team_id: str owner_external_player_id: str label: str = Field(min_length=1, max_length=255) start_ms: int = Field(ge=0) end_ms: int = Field(gt=0) class AudioClipUpdate(BaseModel): label: str | None = Field(default=None, min_length=1, max_length=255) start_ms: int = Field(ge=0) end_ms: int = Field(gt=0) sort_order: int | None = None hidden: bool | None = None class AudioClipResponse(BaseModel): id: int asset_id: int external_team_id: str owner_external_player_id: str asset_title: str label: str start_ms: int end_ms: int sort_order: int hidden: bool normalization_status: str normalized_url: str | None waveform_duration_ms: int | None = None waveform_peaks: list[int] | None = None created_at: datetime class GameAssignmentCreate(BaseModel): external_team_id: str external_player_id: str clip_id: int batting_slot: int | None = Field(default=None, ge=1, le=99) status: str = "ready" class GameAssignmentResponse(BaseModel): id: int external_team_id: str external_game_id: str external_player_id: str clip_id: int clip_label: str asset_title: str start_ms: int end_ms: int batting_slot: int | None status: str normalized_url: str | None updated_at: datetime class GamePrepResponse(BaseModel): external_game_id: str external_team_id: str prepared_at: datetime assignments: list[GameAssignmentResponse] class AudioClipReorder(BaseModel): external_team_id: str owner_external_player_id: str clip_ids: list[int] = Field(min_length=1) class PlaybackAction(BaseModel): assignment_id: int | None = None clip_id: int | None = None external_player_id: str | None = None