/**
 * Game State and Play Result Types
 *
 * TypeScript definitions matching backend Pydantic models exactly.
 * These types ensure type safety between frontend and backend.
 *
 * Backend Reference: app/models/game_models.py
 */

/**
 * Game status enumeration
 */
export type GameStatus = 'pending' | 'active' | 'paused' | 'completed' | 'abandoned'

/**
 * Inning half
 */
export type InningHalf = 'top' | 'bottom'

/**
 * Game mode
 */
export type GameMode = 'live' | 'async' | 'vs_ai'

/**
 * Game visibility
 */
export type GameVisibility = 'public' | 'private'

/**
 * League identifier
 */
export type LeagueId = 'sba' | 'pd'

/**
 * Decision phase in the play workflow
 *
 * Standardized naming (2025-01-21): Uses backend convention 'awaiting_*'
 * for clarity about what action is pending.
 */
export type DecisionPhase = 'awaiting_defensive' | 'awaiting_stolen_base' | 'awaiting_offensive' | 'resolution' | 'complete'

/**
 * Lineup player state - represents a player in the game
 * Backend: LineupPlayerState
 */
export interface LineupPlayerState {
  lineup_id: number
  card_id: number
  position: string
  batting_order: number | null
  is_active: boolean
  position_rating?: {
    range: number
    error: number
    innings: number
  } | null
}

/**
 * Core game state - complete representation of active game
 * Backend: GameState
 */
export interface GameState {
  // Identity
  game_id: string
  league_id: LeagueId

  // Teams
  home_team_id: number
  away_team_id: number
  home_team_is_ai: boolean
  away_team_is_ai: boolean

  // Team display info (from game_metadata, stored at creation time)
  home_team_name?: string | null      // Full name: "Chicago Cyclones"
  home_team_abbrev?: string | null    // Abbreviation: "CHC"
  home_team_color?: string | null     // Hex color without #: "ff5349"
  home_team_dice_color?: string | null // Dice color hex without #, default "cc0000"
  home_team_thumbnail?: string | null // Team logo URL
  away_team_name?: string | null
  away_team_abbrev?: string | null
  away_team_color?: string | null
  away_team_dice_color?: string | null // Dice color hex without #, default "cc0000"
  away_team_thumbnail?: string | null

  // Creator (for demo/testing - creator can control home team)
  creator_discord_id: string | null

  // Resolution mode
  auto_mode: boolean

  // Game state
  status: GameStatus
  inning: number
  half: InningHalf
  outs: number
  balls: number
  strikes: number
  home_score: number
  away_score: number

  // Runners (direct references)
  on_first: LineupPlayerState | null
  on_second: LineupPlayerState | null
  on_third: LineupPlayerState | null

  // Current players
  current_batter: LineupPlayerState
  current_pitcher: LineupPlayerState | null
  current_catcher: LineupPlayerState | null
  current_on_base_code: number

  // Batting order tracking
  away_team_batter_idx: number  // 0-8
  home_team_batter_idx: number  // 0-8

  // Decision tracking
  pending_decision: DecisionPhase | null
  decision_phase: DecisionPhase
  decisions_this_play: Record<string, boolean>
  pending_defensive_decision: DefensiveDecision | null
  pending_offensive_decision: OffensiveDecision | null

  // Manual mode
  pending_manual_roll: RollData | null

  // Play history
  play_count: number
  last_play_result: string | null

  // Timestamps
  created_at: string
  started_at: string | null
  completed_at: string | null
}

/**
 * Defensive strategic decision
 * Backend: DefensiveDecision
 */
export interface DefensiveDecision {
  infield_depth: 'infield_in' | 'normal' | 'corners_in'
  outfield_depth: 'normal' | 'shallow'
  hold_runners: number[]  // Bases to hold (e.g., [1, 3])
}

/**
 * Offensive strategic decision
 * Backend: OffensiveDecision
 *
 * Session 2 Update (2025-01-14): Replaced approach/hit_and_run/bunt_attempt with action field.
 */
export interface OffensiveDecision {
  action: 'swing_away' | 'steal' | 'check_jump' | 'hit_and_run' | 'sac_bunt' | 'squeeze_bunt'
  steal_attempts: number[]  // Bases to steal (2, 3, or 4) - only used when action="steal"
}

/**
 * Dice roll data from server
 * Backend: AbRoll (simplified for frontend)
 */
export interface RollData {
  roll_id: string
  d6_one: number
  d6_two_a: number
  d6_two_b: number
  d6_two_total: number
  chaos_d20: number
  resolution_d20: number
  check_wild_pitch: boolean
  check_passed_ball: boolean
  chaos_check_skipped: boolean  // True when no runners on base (WP/PB irrelevant)
  timestamp: string
}

/**
 * Play outcome enumeration (matches backend PlayOutcome enum values)
 * Note: These are the STRING VALUES, not enum names
 */
export type PlayOutcome =
  // Standard outs
  | 'strikeout'
  | 'groundball_a'
  | 'groundball_b'
  | 'groundball_c'
  | 'flyout_a'
  | 'flyout_b'
  | 'flyout_bq'
  | 'flyout_c'
  | 'lineout'
  | 'popout'

  // Walks and hits by pitch
  | 'walk'
  | 'intentional_walk'
  | 'hbp'

  // Hits (capped - specific bases)
  | 'single_1'
  | 'single_2'
  | 'single_uncapped'
  | 'double_2'
  | 'double_3'
  | 'double_uncapped'
  | 'triple'
  | 'homerun'

  // Interrupt plays (baserunning events)
  | 'stolen_base'
  | 'caught_stealing'
  | 'wild_pitch'
  | 'passed_ball'
  | 'balk'
  | 'pick_off'

  // Errors
  | 'error'
  | 'x_check'

  // Ballpark power (PD specific)
  | 'bp_homerun'
  | 'bp_flyout'
  | 'bp_single'
  | 'bp_lineout'

/**
 * Runner advancement during a play
 */
export interface RunnerAdvancement {
  from: number       // 0=batter, 1-3=bases
  to: number         // 1-4=bases (4=home/scored)
  lineup_id: number  // Player's lineup ID for name lookup
  is_out?: boolean   // Runner was out during advancement (renamed from 'out')
}

/**
 * Play resolution result from server
 * Backend: PlayResult
 */
export interface PlayResult {
  // Play identification
  play_number: number
  inning?: number                    // Inning when play occurred
  half?: InningHalf                  // 'top' or 'bottom'
  outcome: PlayOutcome

  // Play description
  description: string
  hit_type?: string

  // Results
  outs_recorded: number
  runs_scored: number

  // Player identification for display
  batter_lineup_id?: number          // Batter's lineup ID for name lookup

  // Runner advancement
  runners_advanced: RunnerAdvancement[]
  batter_result: number | null  // Where batter ended up (1-4, null=out)

  // Updated state snapshot
  new_state: Partial<GameState>

  // Categorization helpers
  is_hit: boolean
  is_out: boolean
  is_walk: boolean
  is_strikeout: boolean

  // Roll reference (if manual mode)
  roll_id?: string

  // X-Check details (if defensive play)
  x_check_details?: XCheckResult
}

/**
 * X-Check resolution audit trail
 */
export interface XCheckResult {
  check_position: string
  defense_range: number
  error_rating: number
  d20_roll: number
  error_3d6: number
  base_result: string
  error_result: string
  final_outcome: PlayOutcome
  held_runners: string[]
}

/**
 * Decision prompt from server
 * Backend: DecisionPrompt (WebSocket event)
 */
export interface DecisionPrompt {
  phase: DecisionPhase
  role: 'home' | 'away'
  timeout_seconds: number
  options?: string[]
  message?: string
}

/**
 * Manual outcome submission to server
 * Backend: ManualOutcomeSubmission
 */
export interface ManualOutcomeSubmission {
  outcome: PlayOutcome
  hit_location?: string  // Required for groundballs/flyballs
}

/**
 * Game list item for active/completed games
 * Note: Field names match backend GameListItem response
 */
export interface GameListItem {
  game_id: string
  league_id: LeagueId
  home_team_id: number
  away_team_id: number
  status: GameStatus
  // Enriched team info from backend
  home_team_name?: string
  away_team_name?: string
  home_team_abbrev?: string
  away_team_abbrev?: string
  home_score: number
  away_score: number
  inning?: number
  half?: InningHalf
  // External schedule reference (for linking to SBA/PD schedule systems)
  schedule_game_id?: number
}

/**
 * Game creation request
 */
export interface CreateGameRequest {
  league_id: LeagueId
  home_team_id: number
  away_team_id: number
  game_mode: GameMode
  visibility: GameVisibility
}

/**
 * Game creation response
 */
export interface CreateGameResponse {
  game_id: string
  status: GameStatus
  created_at: string
}
