/**
 * Socket.IO types for the game namespace.
 *
 * Based on backend WebSocket documentation in backend/app/socketio/
 */

// ============================================
// Client -> Server Events
// ============================================

export interface ClientToServerEvents {
  /** Join or rejoin a game room */
  'game:join': (data: { game_id: string }) => void
  /** Execute a game action */
  'game:action': (data: GameAction) => void
  /** Resign from the current game */
  'game:resign': (data: { game_id: string }) => void
  /** Join as spectator */
  'game:spectate': (data: { game_id: string }) => void
  /** Leave spectator mode */
  'game:leave_spectate': (data: { game_id: string }) => void
}

// ============================================
// Server -> Client Events
// ============================================

export interface ServerToClientEvents {
  /** Full game state update (visibility filtered per player) */
  'game:state': (state: GameState) => void
  /** Result of a player action */
  'game:action_result': (result: ActionResult) => void
  /** Error notification */
  'game:error': (error: GameError) => void
  /** Turn timer warning */
  'game:turn_timeout_warning': (data: { remaining_seconds: number }) => void
  /** Game has ended */
  'game:game_over': (data: GameOverData) => void
  /** Opponent connection status changed */
  'game:opponent_connected': (data: { connected: boolean }) => void
  /** Auto-reconnected to game */
  'game:reconnected': (data: { game_id: string; state: GameState }) => void
  /** Spectator count update */
  'game:spectator_count': (data: { count: number }) => void
}

// ============================================
// Game Action Types
// ============================================

export type GameActionType =
  | 'play_pokemon'
  | 'attach_energy'
  | 'play_trainer'
  | 'attack'
  | 'retreat'
  | 'use_ability'
  | 'select_prize'
  | 'select_new_active'
  | 'end_turn'

export interface GameAction {
  type: GameActionType
  /** Card ID being played (for play actions) */
  card_id?: string
  /** Target card/zone ID */
  target_id?: string
  /** Attack index (0 or 1) */
  attack_index?: number
  /** Additional action-specific data */
  data?: Record<string, unknown>
}

// ============================================
// Game State Types
// ============================================

export interface GameState {
  game_id: string
  turn_number: number
  current_phase: TurnPhase
  current_player: 'me' | 'opponent'
  /** My visible state */
  my_state: PlayerState
  /** Opponent's visible state (hidden info redacted) */
  opponent_state: OpponentState
  /** Forced action required (e.g., select prize) */
  forced_action?: ForcedAction
  /** Turn timer remaining (seconds) */
  turn_timer?: number
}

export type TurnPhase = 'draw' | 'main' | 'attack' | 'end'

export interface PlayerState {
  /** Active Pokemon (full info) */
  active: CardInPlay | null
  /** Bench Pokemon (up to 5) */
  bench: (CardInPlay | null)[]
  /** Hand cards (full info - only visible to owner) */
  hand: Card[]
  /** Deck count (not contents) */
  deck_count: number
  /** Discard pile (visible to both players) */
  discard: Card[]
  /** Prize cards (face down until taken) */
  prizes: (Card | null)[]
  /** Number of prizes remaining */
  prizes_remaining: number
}

export interface OpponentState {
  /** Active Pokemon (public info only) */
  active: CardInPlay | null
  /** Bench Pokemon */
  bench: (CardInPlay | null)[]
  /** Hand count only (not contents) */
  hand_count: number
  /** Deck count */
  deck_count: number
  /** Discard pile */
  discard: Card[]
  /** Prize count (not contents) */
  prizes_remaining: number
}

export interface Card {
  id: string
  definition_id: string
  name: string
  card_type: 'pokemon' | 'trainer' | 'energy'
  /** Pokemon-specific fields */
  hp?: number
  pokemon_type?: string
  stage?: 'basic' | 'stage1' | 'stage2'
  evolves_from?: string
  attacks?: Attack[]
  weakness?: string
  resistance?: string
  retreat_cost?: number
  /** Energy-specific fields */
  energy_type?: string
  /** Trainer-specific fields */
  trainer_type?: 'item' | 'supporter' | 'stadium'
}

export interface CardInPlay extends Card {
  /** Current damage on the card */
  damage: number
  /** Attached energy cards */
  attached_energy: Card[]
  /** Status conditions */
  status: StatusCondition[]
  /** Can evolve this turn */
  can_evolve: boolean
}

export interface Attack {
  name: string
  cost: string[]
  damage: number
  effect?: string
  effect_text?: string
}

export type StatusCondition = 'poisoned' | 'burned' | 'paralyzed' | 'asleep' | 'confused'

export interface ForcedAction {
  type: 'select_prize' | 'select_new_active' | 'discard_cards'
  /** Number of selections required */
  count?: number
  /** Valid target IDs */
  valid_targets?: string[]
  /** Reason for forced action */
  reason?: string
}

// ============================================
// Action Result Types
// ============================================

export interface ActionResult {
  success: boolean
  action_type: GameActionType
  /** Error message if not successful */
  message?: string
  /** State changes that resulted */
  changes?: StateChange[]
}

export interface StateChange {
  type: string
  data: Record<string, unknown>
}

// ============================================
// Error and Game Over Types
// ============================================

export interface GameError {
  message: string
  code?: string
}

export interface GameOverData {
  winner: 'me' | 'opponent' | 'draw'
  reason: GameOverReason
  /** Game statistics */
  stats?: GameStats
}

export type GameOverReason =
  | 'prizes_taken'
  | 'no_pokemon'
  | 'deck_out'
  | 'resignation'
  | 'timeout'
  | 'disconnect'

export interface GameStats {
  turns: number
  cards_played: number
  damage_dealt: number
  knockouts: number
}
