/**
 * Game Actions Composable
 *
 * Provides type-safe methods for emitting game actions to the server.
 * Wraps Socket.io emit calls with proper error handling and validation.
 *
 * This composable is league-agnostic and will be shared between SBA and PD.
 */

import { computed } from 'vue'
import type {
  DefensiveDecision,
  OffensiveDecision,
  ManualOutcomeSubmission,
  PlayOutcome,
} from '~/types'
import { useWebSocket } from './useWebSocket'
import { useGameStore } from '~/store/game'
import { useUiStore } from '~/store/ui'

export function useGameActions(gameId?: string) {
  const { socket, isConnected } = useWebSocket()
  const gameStore = useGameStore()
  const uiStore = useUiStore()

  // Use provided gameId or get from store
  const currentGameId = computed(() => gameId || gameStore.gameId)

  /**
   * Validate socket connection before emitting
   */
  function validateConnection(): boolean {
    console.log('[GameActions] validateConnection check:', {
      isConnected: isConnected.value,
      hasSocket: !!socket.value,
      currentGameId: currentGameId.value,
      passedGameId: gameId,
      storeGameId: gameStore.gameId
    })

    if (!isConnected.value) {
      console.error('[GameActions] Validation failed: Not connected')
      uiStore.showError('Not connected to game server')
      return false
    }

    if (!socket.value) {
      console.error('[GameActions] Validation failed: No socket')
      uiStore.showError('WebSocket not initialized')
      return false
    }

    if (!currentGameId.value) {
      console.error('[GameActions] Validation failed: No game ID')
      uiStore.showError('No active game')
      return false
    }

    return true
  }

  // ============================================================================
  // Connection Actions
  // ============================================================================

  /**
   * Join a game room
   */
  function joinGame(role: 'player' | 'spectator' = 'player') {
    if (!validateConnection()) return

    console.log(`[GameActions] Joining game ${currentGameId.value} as ${role}`)

    socket.value!.emit('join_game', {
      game_id: currentGameId.value!,
      role,
    })
  }

  /**
   * Leave current game room
   */
  function leaveGame() {
    if (!socket.value || !currentGameId.value) return

    console.log(`[GameActions] Leaving game ${currentGameId.value}`)

    socket.value.emit('leave_game', {
      game_id: currentGameId.value,
    })

    // Clear game state
    gameStore.resetGame()
  }

  // ============================================================================
  // Strategic Decision Actions
  // ============================================================================

  /**
   * Submit defensive decision
   */
  function submitDefensiveDecision(decision: DefensiveDecision) {
    if (!validateConnection()) return

    console.log('[GameActions] Submitting defensive decision:', decision)

    socket.value!.emit('submit_defensive_decision', {
      game_id: currentGameId.value!,
      infield_depth: decision.infield_depth,
      outfield_depth: decision.outfield_depth,
      hold_runners: decision.hold_runners,
    })
  }

  /**
   * Submit offensive decision
   */
  function submitOffensiveDecision(decision: OffensiveDecision) {
    if (!validateConnection()) return

    console.log('[GameActions] Submitting offensive decision:', decision)

    socket.value!.emit('submit_offensive_decision', {
      game_id: currentGameId.value!,
      action: decision.action,
      steal_attempts: decision.steal_attempts,
    })
  }

  // ============================================================================
  // Manual Outcome Workflow
  // ============================================================================

  /**
   * Roll dice for manual outcome selection
   */
  function rollDice() {
    if (!validateConnection()) return

    if (!gameStore.canRollDice) {
      uiStore.showWarning('Cannot roll dice at this time')
      return
    }

    console.log('[GameActions] Rolling dice')

    socket.value!.emit('roll_dice', {
      game_id: currentGameId.value!,
    })

    uiStore.showInfo('Rolling dice...', 2000)
  }

  /**
   * Submit manual outcome after reading card
   */
  function submitManualOutcome(outcome: PlayOutcome, hitLocation?: string) {
    if (!validateConnection()) return

    if (!gameStore.canSubmitOutcome) {
      uiStore.showWarning('Must roll dice first')
      return
    }

    console.log('[GameActions] Submitting outcome:', outcome, hitLocation)

    socket.value!.emit('submit_manual_outcome', {
      game_id: currentGameId.value!,
      outcome: outcome,
      hit_location: hitLocation,
    })

    uiStore.showInfo('Submitting outcome...', 2000)
  }

  // ============================================================================
  // Substitution Actions
  // ============================================================================

  /**
   * Request pinch hitter substitution
   */
  function requestPinchHitter(
    playerOutLineupId: number,
    playerInCardId: number,
    teamId: number
  ) {
    if (!validateConnection()) return

    console.log('[GameActions] Requesting pinch hitter')

    socket.value!.emit('request_pinch_hitter', {
      game_id: currentGameId.value!,
      player_out_lineup_id: playerOutLineupId,
      player_in_card_id: playerInCardId,
      team_id: teamId,
    })

    uiStore.showInfo('Requesting pinch hitter...', 3000)
  }

  /**
   * Request defensive replacement
   */
  function requestDefensiveReplacement(
    playerOutLineupId: number,
    playerInCardId: number,
    newPosition: string,
    teamId: number
  ) {
    if (!validateConnection()) return

    console.log('[GameActions] Requesting defensive replacement')

    socket.value!.emit('request_defensive_replacement', {
      game_id: currentGameId.value!,
      player_out_lineup_id: playerOutLineupId,
      player_in_card_id: playerInCardId,
      new_position: newPosition,
      team_id: teamId,
    })

    uiStore.showInfo('Requesting defensive replacement...', 3000)
  }

  /**
   * Request pitching change
   */
  function requestPitchingChange(
    playerOutLineupId: number,
    playerInCardId: number,
    teamId: number
  ) {
    if (!validateConnection()) return

    console.log('[GameActions] Requesting pitching change')

    socket.value!.emit('request_pitching_change', {
      game_id: currentGameId.value!,
      player_out_lineup_id: playerOutLineupId,
      player_in_card_id: playerInCardId,
      team_id: teamId,
    })

    uiStore.showInfo('Requesting pitching change...', 3000)
  }

  /**
   * Submit substitution - unified wrapper for all substitution types
   * Routes to the appropriate specific method based on type
   */
  function submitSubstitution(
    type: 'pinch_hitter' | 'defensive_replacement' | 'pitching_change',
    playerOutLineupId: number,
    playerInCardId: number,
    teamId: number,
    newPosition?: string
  ) {
    switch (type) {
      case 'pinch_hitter':
        requestPinchHitter(playerOutLineupId, playerInCardId, teamId)
        break
      case 'defensive_replacement':
        if (!newPosition) {
          uiStore.showError('Position required for defensive replacement')
          return
        }
        requestDefensiveReplacement(playerOutLineupId, playerInCardId, newPosition, teamId)
        break
      case 'pitching_change':
        requestPitchingChange(playerOutLineupId, playerInCardId, teamId)
        break
      default:
        uiStore.showError(`Unknown substitution type: ${type}`)
    }
  }

  // ============================================================================
  // Undo/Rollback Actions
  // ============================================================================

  /**
   * Undo the last N plays
   * Rolls back plays from the database and reconstructs game state
   */
  function undoLastPlay(numPlays: number = 1) {
    if (!validateConnection()) return

    console.log('[GameActions] Undoing last', numPlays, 'play(s)')

    socket.value!.emit('rollback_play', {
      game_id: currentGameId.value!,
      num_plays: numPlays,
    })

    uiStore.showInfo(`Undoing ${numPlays} play(s)...`, 3000)
  }

  // ============================================================================
  // Data Request Actions
  // ============================================================================

  /**
   * Get lineup for a team
   */
  function getLineup(teamId: number) {
    if (!validateConnection()) return

    console.log('[GameActions] Requesting lineup for team:', teamId)

    socket.value!.emit('get_lineup', {
      game_id: currentGameId.value!,
      team_id: teamId,
    })
  }

  /**
   * Get bench players for a team (for substitutions)
   */
  function getBench(teamId: number) {
    if (!validateConnection()) return

    console.log('[GameActions] Requesting bench for team:', teamId)

    socket.value!.emit('get_bench', {
      game_id: currentGameId.value!,
      team_id: teamId,
    })
  }

  /**
   * Get box score
   */
  function getBoxScore() {
    if (!validateConnection()) return

    console.log('[GameActions] Requesting box score')

    socket.value!.emit('get_box_score', {
      game_id: currentGameId.value!,
    })
  }

  /**
   * Request full game state (for reconnection)
   */
  function requestGameState() {
    if (!validateConnection()) return

    console.log('[GameActions] Requesting full game state')

    socket.value!.emit('request_game_state', {
      game_id: currentGameId.value!,
    })

    uiStore.showInfo('Syncing game state...', 3000)
  }

  // ============================================================================
  // Return API
  // ============================================================================

  return {
    // Connection
    joinGame,
    leaveGame,

    // Strategic decisions
    submitDefensiveDecision,
    submitOffensiveDecision,

    // Manual workflow
    rollDice,
    submitManualOutcome,

    // Substitutions
    submitSubstitution,

    // Undo/Rollback
    undoLastPlay,

    // Data requests
    getLineup,
    getBench,
    getBoxScore,
    requestGameState,
  }
}
