"""Game schemas for Mantimon TCG.

This module defines Pydantic models for game-related API requests
and responses. Games are real-time matches between players.

The backend is stateless - game rules come from the request via RulesConfig.
Frontend provides the rules appropriate for the game mode (campaign, freeplay, custom).

Example:
    game = GameInfoResponse(
        game_id="abc-123",
        game_type=GameType.FREEPLAY,
        player1_id=uuid4(),
        player2_id=uuid4(),
        current_player_id="player1-id",
        turn_number=5,
        phase=TurnPhase.MAIN,
        is_your_turn=True,
        started_at=datetime.now(UTC),
    )
"""

from datetime import datetime
from uuid import UUID

from pydantic import BaseModel, Field

from app.core.config import RulesConfig
from app.core.enums import GameEndReason, TurnPhase
from app.db.models.game import GameType


class GameCreateRequest(BaseModel):
    """Request model for creating a new game.

    For multiplayer games, opponent_id should be provided (Phase 6 matchmaking).
    For campaign games, npc_id should be provided (Phase 5).
    Currently supports direct opponent specification for testing.

    Attributes:
        deck_id: ID of the deck to use for this game.
        opponent_id: UUID of the opponent player (for PvP games).
        opponent_deck_id: UUID of opponent's deck (required if opponent_id provided).
        rules_config: Game rules from the frontend (defaults to standard rules).
        game_type: Type of game (freeplay, ranked, etc.).
    """

    deck_id: UUID = Field(..., description="ID of deck to use")
    opponent_id: UUID = Field(..., description="Opponent player ID")
    opponent_deck_id: UUID = Field(..., description="Opponent's deck ID")
    rules_config: RulesConfig = Field(
        default_factory=RulesConfig, description="Game rules from frontend"
    )
    game_type: GameType = Field(default=GameType.FREEPLAY, description="Type of game")


class GameCreateResponse(BaseModel):
    """Response model for game creation.

    Attributes:
        game_id: Unique game identifier.
        ws_url: WebSocket URL to connect for gameplay.
        starting_player_id: ID of the player who goes first.
        message: Status message.
    """

    game_id: str = Field(..., description="Unique game identifier")
    ws_url: str = Field(..., description="WebSocket URL for gameplay")
    starting_player_id: str = Field(..., description="Player who goes first")
    message: str = Field(default="Game created successfully", description="Status message")


class GameInfoResponse(BaseModel):
    """Response model for game info.

    Provides metadata about a game without full state (use WebSocket for state).

    Attributes:
        game_id: Unique game identifier.
        game_type: Type of game (campaign, freeplay, ranked).
        player1_id: First player's user ID.
        player2_id: Second player's user ID (None for campaign).
        npc_id: NPC opponent ID for campaign games.
        current_player_id: ID of player whose turn it is.
        turn_number: Current turn number.
        phase: Current turn phase.
        is_your_turn: Whether it's the requesting user's turn.
        is_game_over: Whether the game has ended.
        winner_id: Winner's ID if game ended (None for ongoing or draw).
        end_reason: Reason game ended, if applicable.
        started_at: When the game started.
        last_action_at: Timestamp of last action.
    """

    game_id: str = Field(..., description="Unique game identifier")
    game_type: GameType = Field(..., description="Type of game")
    player1_id: UUID = Field(..., description="First player's user ID")
    player2_id: UUID | None = Field(default=None, description="Second player's user ID")
    npc_id: str | None = Field(default=None, description="NPC opponent ID")
    current_player_id: str | None = Field(default=None, description="Current player's turn")
    turn_number: int = Field(default=0, description="Current turn number")
    phase: TurnPhase | None = Field(default=None, description="Current turn phase")
    is_your_turn: bool = Field(default=False, description="Is it your turn")
    is_game_over: bool = Field(default=False, description="Has game ended")
    winner_id: str | None = Field(default=None, description="Winner's ID if ended")
    end_reason: GameEndReason | None = Field(default=None, description="Why game ended")
    started_at: datetime = Field(..., description="Game start time")
    last_action_at: datetime = Field(..., description="Last action time")

    model_config = {"from_attributes": True}


class ActiveGameSummary(BaseModel):
    """Summary of an active game for list endpoints.

    Lighter-weight than GameInfoResponse for list views.

    Attributes:
        game_id: Unique game identifier.
        game_type: Type of game.
        opponent_name: Opponent's display name or NPC name.
        is_your_turn: Whether it's your turn.
        turn_number: Current turn number.
        started_at: When the game started.
        last_action_at: Timestamp of last action.
    """

    game_id: str = Field(..., description="Unique game identifier")
    game_type: GameType = Field(..., description="Type of game")
    opponent_name: str = Field(..., description="Opponent's name")
    is_your_turn: bool = Field(default=False, description="Is it your turn")
    turn_number: int = Field(default=0, description="Current turn number")
    started_at: datetime = Field(..., description="Game start time")
    last_action_at: datetime = Field(..., description="Last action time")


class ActiveGameListResponse(BaseModel):
    """Response model for listing user's active games.

    Attributes:
        games: List of active game summaries.
        total: Total number of active games.
    """

    games: list[ActiveGameSummary] = Field(default_factory=list, description="Active games")
    total: int = Field(default=0, ge=0, description="Total active games")


class GameResignResponse(BaseModel):
    """Response model for game resignation.

    Attributes:
        success: Whether resignation was successful.
        game_id: The game that was resigned from.
        message: Status message.
    """

    success: bool = Field(..., description="Was resignation successful")
    game_id: str = Field(..., description="Game ID")
    message: str = Field(default="", description="Status message")
