<template>
  <div class="min-h-screen bg-gray-50 dark:bg-gray-900">
    <!-- Sticky ScoreBoard Header -->
    <div ref="scoreBoardRef" class="sticky top-0 z-20">
      <ScoreBoard
        :home-score="gameState?.home_score"
        :away-score="gameState?.away_score"
        :inning="gameState?.inning"
        :half="gameState?.half"
        :outs="gameState?.outs"
        :runners="runnersState"
      />
    </div>

    <!-- Main Game Container -->
    <div class="container mx-auto px-4 py-6 lg:py-8">
      <!-- Connection Status Banner -->
      <div
        v-if="!isConnected"
        class="mb-4 bg-yellow-50 border-l-4 border-yellow-400 p-4 rounded-lg"
      >
        <div class="flex items-center justify-between">
          <div class="flex items-center">
            <div class="flex-shrink-0">
              <svg class="h-5 w-5 text-yellow-400 animate-spin" xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24">
                <circle class="opacity-25" cx="12" cy="12" r="10" stroke="currentColor" stroke-width="4"/>
                <path class="opacity-75" fill="currentColor" d="M4 12a8 8 0 018-8V0C5.373 0 0 5.373 0 12h4zm2 5.291A7.962 7.962 0 014 12H0c0 3.042 1.135 5.824 3 7.938l3-2.647z"/>
              </svg>
            </div>
            <div class="ml-3">
              <p class="text-sm text-yellow-700">
                {{ connectionStatus === 'connecting' ? 'Connecting to game server...' : 'Disconnected from server. Attempting to reconnect...' }}
              </p>
            </div>
          </div>
          <button
            @click="forceReconnect"
            class="ml-4 px-3 py-1 text-sm font-medium text-yellow-700 bg-yellow-100 hover:bg-yellow-200 rounded-md transition"
          >
            Retry
          </button>
        </div>
      </div>

      <!-- Mobile Layout (Stacked) -->
      <div class="lg:hidden space-y-6">
        <!-- Current Situation -->
        <CurrentSituation
          :current-batter="gameState?.current_batter"
          :current-pitcher="gameState?.current_pitcher"
        />

        <!-- Game Board -->
        <GameBoard
          :runners="runnersState"
          :current-batter="gameState?.current_batter"
          :current-pitcher="gameState?.current_pitcher"
        />

        <!-- Play-by-Play Feed -->
        <div class="bg-white dark:bg-gray-800 rounded-lg p-4 shadow-md">
          <PlayByPlay
            :plays="playHistory"
            :limit="5"
            :compact="true"
          />
        </div>

        <!-- Decision Panel (Phase F3) -->
        <DecisionPanel
          v-if="showDecisions"
          :game-id="gameId"
          :current-team="currentTeam"
          :is-my-turn="isMyTurn"
          :phase="decisionPhase"
          :runners="runnersData"
          :current-defensive-setup="pendingDefensiveSetup ?? undefined"
          :current-offensive-decision="pendingOffensiveDecision ?? undefined"
          :current-steal-attempts="pendingStealAttempts"
          :decision-history="decisionHistory"
          @defensive-submit="handleDefensiveSubmit"
          @offensive-submit="handleOffensiveSubmit"
          @steal-attempts-submit="handleStealAttemptsSubmit"
        />

        <!-- Gameplay Panel (Phase F4) -->
        <GameplayPanel
          v-if="showGameplay"
          :game-id="gameId"
          :is-my-turn="isMyTurn"
          :can-roll-dice="canRollDice"
          :pending-roll="pendingRoll"
          :last-play-result="lastPlayResult"
          :can-submit-outcome="canSubmitOutcome"
          :outs="gameState?.outs ?? 0"
          :has-runners="!!(gameState?.on_first || gameState?.on_second || gameState?.on_third)"
          @roll-dice="handleRollDice"
          @submit-outcome="handleSubmitOutcome"
          @dismiss-result="handleDismissResult"
        />
      </div>

      <!-- Desktop Layout (Grid) -->
      <div class="hidden lg:grid lg:grid-cols-3 gap-6">
        <!-- Left Column: Game State -->
        <div class="lg:col-span-2 space-y-6">
          <!-- Current Situation -->
          <CurrentSituation
            :current-batter="gameState?.current_batter"
            :current-pitcher="gameState?.current_pitcher"
          />

          <!-- Game Board -->
          <div class="bg-white dark:bg-gray-800 rounded-xl p-6 shadow-lg">
            <GameBoard
              :runners="runnersState"
              :current-batter="gameState?.current_batter"
              :current-pitcher="gameState?.current_pitcher"
            />
          </div>

          <!-- Decision Panel (Phase F3) -->
          <DecisionPanel
            v-if="showDecisions"
            :game-id="gameId"
            :current-team="currentTeam"
            :is-my-turn="isMyTurn"
            :phase="decisionPhase"
            :runners="runnersData"
            :current-defensive-setup="pendingDefensiveSetup ?? undefined"
            :current-offensive-decision="pendingOffensiveDecision ?? undefined"
            :current-steal-attempts="pendingStealAttempts"
            :decision-history="decisionHistory"
            @defensive-submit="handleDefensiveSubmit"
            @offensive-submit="handleOffensiveSubmit"
            @steal-attempts-submit="handleStealAttemptsSubmit"
          />

          <!-- Gameplay Panel (Phase F4) -->
          <GameplayPanel
            v-if="showGameplay"
            :game-id="gameId"
            :is-my-turn="isMyTurn"
            :can-roll-dice="canRollDice"
            :pending-roll="pendingRoll"
            :last-play-result="lastPlayResult"
            :can-submit-outcome="canSubmitOutcome"
            :outs="gameState?.outs ?? 0"
            :has-runners="!!(gameState?.on_first || gameState?.on_second || gameState?.on_third)"
            @roll-dice="handleRollDice"
            @submit-outcome="handleSubmitOutcome"
            @dismiss-result="handleDismissResult"
          />
        </div>

        <!-- Right Column: Play-by-Play -->
        <div class="lg:col-span-1">
          <div
            class="bg-white dark:bg-gray-800 rounded-xl p-6 shadow-lg sticky"
            :style="{ top: `${scoreBoardHeight + 16}px` }"
          >
            <PlayByPlay
              :plays="playHistory"
              :scrollable="true"
              :max-height="600"
              :show-filters="true"
            />
          </div>
        </div>
      </div>

      <!-- Loading State -->
      <div
        v-if="isLoading"
        class="fixed inset-0 bg-black/50 backdrop-blur-sm flex items-center justify-center z-50"
      >
        <div class="bg-white dark:bg-gray-800 rounded-xl p-8 shadow-2xl text-center max-w-sm mx-4">
          <!-- Show spinner only if actively connecting -->
          <div v-if="isConnecting" class="w-16 h-16 mx-auto mb-4 border-4 border-primary border-t-transparent rounded-full animate-spin"/>

          <!-- Show error state if not connecting -->
          <div v-else class="w-16 h-16 mx-auto mb-4 bg-red-100 dark:bg-red-900 rounded-full flex items-center justify-center">
            <svg xmlns="http://www.w3.org/2000/svg" class="h-8 w-8 text-red-600 dark:text-red-400" fill="none" viewBox="0 0 24 24" stroke="currentColor">
              <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M12 9v2m0 4h.01m-6.938 4h13.856c1.54 0 2.502-1.667 1.732-3L13.732 4c-.77-1.333-2.694-1.333-3.464 0L3.34 16c-.77 1.333.192 3 1.732 3z" />
            </svg>
          </div>

          <p class="text-gray-900 dark:text-white font-semibold">
            {{ isConnecting ? 'Connecting to game...' : 'Connection Failed' }}
          </p>

          <!-- Status info -->
          <div class="mt-4 p-3 bg-gray-100 dark:bg-gray-700 rounded-lg text-left">
            <div class="flex items-center gap-2 text-sm">
              <span :class="authStore.isAuthenticated ? 'text-green-600' : authStore.isLoading ? 'text-yellow-600' : 'text-red-600'">●</span>
              <span class="text-gray-700 dark:text-gray-300">Auth: {{ authStore.isAuthenticated ? 'OK' : authStore.isLoading ? 'Checking...' : 'Failed' }}</span>
            </div>
            <div class="flex items-center gap-2 text-sm mt-1">
              <span :class="isConnected ? 'text-green-600' : isConnecting ? 'text-yellow-600' : 'text-red-600'">●</span>
              <span class="text-gray-700 dark:text-gray-300">WebSocket: {{ isConnected ? 'Connected' : isConnecting ? 'Connecting...' : 'Disconnected' }}</span>
            </div>
            <p v-if="connectionError" class="text-xs text-red-600 mt-2">Error: {{ connectionError }}</p>
            <!-- Debug info -->
            <div class="mt-2 text-xs text-gray-500 border-t pt-2">
              <p>WS URL: {{ wsDebugUrl }}</p>
              <p>Socket exists: {{ socketExists }}</p>
              <p class="mt-1 font-mono text-[10px] max-h-24 overflow-y-auto">{{ debugLog }}</p>
            </div>
          </div>

          <!-- Action buttons -->
          <div class="mt-4 flex flex-col gap-2">
            <button
              @click="forceReconnect"
              class="w-full px-4 py-2 text-sm font-medium text-white bg-blue-600 hover:bg-blue-700 rounded-lg transition"
            >
              Retry Connection
            </button>
            <button
              v-if="!authStore.isAuthenticated"
              @click="navigateTo('/auth/login?return_url=' + encodeURIComponent($route.fullPath))"
              class="w-full px-4 py-2 text-sm font-medium text-gray-700 dark:text-gray-200 bg-gray-200 dark:bg-gray-600 hover:bg-gray-300 dark:hover:bg-gray-500 rounded-lg transition"
            >
              Re-Login
            </button>
            <button
              @click="isLoading = false"
              class="w-full px-4 py-2 text-sm font-medium text-gray-500 hover:text-gray-700 dark:hover:text-gray-300 transition"
            >
              Dismiss (view page anyway)
            </button>
          </div>
        </div>
      </div>

      <!-- Game Not Started State -->
      <div
        v-if="gameState && gameState.status === 'pending'"
        class="mt-6 bg-blue-50 dark:bg-blue-900/20 border-2 border-blue-200 dark:border-blue-700 rounded-xl p-8 text-center"
      >
        <div class="w-20 h-20 mx-auto mb-4 bg-blue-100 dark:bg-blue-800 rounded-full flex items-center justify-center">
          <svg xmlns="http://www.w3.org/2000/svg" class="h-10 w-10 text-blue-600 dark:text-blue-400" fill="none" viewBox="0 0 24 24" stroke="currentColor">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M12 8v4l3 3m6-3a9 9 0 11-18 0 9 9 0 0118 0z" />
          </svg>
        </div>
        <h3 class="text-xl font-bold text-gray-900 dark:text-white mb-2">Game Starting Soon</h3>
        <p class="text-gray-600 dark:text-gray-400">
          Waiting for all players to join. The game will begin once everyone is ready.
        </p>
      </div>

      <!-- Game Ended State -->
      <div
        v-if="gameState && gameState.status === 'completed'"
        class="mt-6 bg-green-50 dark:bg-green-900/20 border-2 border-green-200 dark:border-green-700 rounded-xl p-8 text-center"
      >
        <div class="w-20 h-20 mx-auto mb-4 bg-green-100 dark:bg-green-800 rounded-full flex items-center justify-center">
          <svg xmlns="http://www.w3.org/2000/svg" class="h-10 w-10 text-green-600 dark:text-green-400" fill="none" viewBox="0 0 24 24" stroke="currentColor">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M9 12l2 2 4-4m6 2a9 9 0 11-18 0 9 9 0 0118 0z" />
          </svg>
        </div>
        <h3 class="text-2xl font-bold text-gray-900 dark:text-white mb-2">Game Complete!</h3>
        <p class="text-xl text-gray-700 dark:text-gray-300 mb-4">
          Final Score: {{ gameState.away_score }} - {{ gameState.home_score }}
        </p>
        <button
          class="px-6 py-3 bg-primary hover:bg-blue-700 text-white rounded-lg font-semibold transition shadow-md"
          @click="navigateTo('/games')"
        >
          Back to Games
        </button>
      </div>
    </div>

    <!-- Substitution Panel Modal (Phase F5) -->
    <Teleport to="body">
      <div
        v-if="showSubstitutions"
        class="fixed inset-0 bg-black/50 backdrop-blur-sm z-50 flex items-center justify-center p-4"
        @click.self="handleSubstitutionCancel"
      >
        <div class="bg-white dark:bg-gray-800 rounded-xl shadow-2xl max-w-4xl w-full max-h-[90vh] overflow-y-auto">
          <SubstitutionPanel
            v-if="myTeamId"
            :game-id="gameId"
            :team-id="myTeamId"
            :current-lineup="currentLineup"
            :bench-players="benchPlayers"
            :current-pitcher="currentPitcher"
            :current-batter="currentBatter"
            @pinch-hitter="handlePinchHitter"
            @defensive-replacement="handleDefensiveReplacement"
            @pitching-change="handlePitchingChange"
            @cancel="handleSubstitutionCancel"
          />
        </div>
      </div>
    </Teleport>

    <!-- Floating Action Buttons -->
    <div class="fixed bottom-6 right-6 flex flex-col gap-3 z-40">
      <!-- Undo Last Play Button -->
      <button
        v-if="canUndo"
        class="w-14 h-14 bg-amber-500 hover:bg-amber-600 text-white rounded-full shadow-lg flex items-center justify-center transition-all hover:scale-110"
        aria-label="Undo Last Play"
        title="Undo Last Play"
        @click="handleUndoLastPlay"
      >
        <svg xmlns="http://www.w3.org/2000/svg" class="h-7 w-7" fill="none" viewBox="0 0 24 24" stroke="currentColor">
          <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M3 10h10a8 8 0 018 8v2M3 10l6 6m-6-6l6-6" />
        </svg>
      </button>

      <!-- Substitutions Button -->
      <button
        v-if="canMakeSubstitutions"
        class="w-16 h-16 bg-primary hover:bg-blue-700 text-white rounded-full shadow-lg flex items-center justify-center transition-all hover:scale-110"
        aria-label="Open Substitutions"
        @click="showSubstitutions = true"
      >
        <svg xmlns="http://www.w3.org/2000/svg" class="h-8 w-8" fill="none" viewBox="0 0 24 24" stroke="currentColor">
          <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M17 20h5v-2a3 3 0 00-5.356-1.857M17 20H7m10 0v-2c0-.656-.126-1.283-.356-1.857M7 20H2v-2a3 3 0 015.356-1.857M7 20v-2c0-.656.126-1.283.356-1.857m0 0a5.002 5.002 0 019.288 0M15 7a3 3 0 11-6 0 3 3 0 016 0zm6 3a2 2 0 11-4 0 2 2 0 014 0zM7 10a2 2 0 11-4 0 2 2 0 014 0z" />
        </svg>
      </button>
    </div>
  </div>
</template>

<script setup lang="ts">
import { useGameStore } from '~/store/game'
import { useAuthStore } from '~/store/auth'
import { useUiStore } from '~/store/ui'
import { useWebSocket } from '~/composables/useWebSocket'
import { useGameActions } from '~/composables/useGameActions'
import ScoreBoard from '~/components/Game/ScoreBoard.vue'
import GameBoard from '~/components/Game/GameBoard.vue'
import CurrentSituation from '~/components/Game/CurrentSituation.vue'
import PlayByPlay from '~/components/Game/PlayByPlay.vue'
import DecisionPanel from '~/components/Decisions/DecisionPanel.vue'
import GameplayPanel from '~/components/Gameplay/GameplayPanel.vue'
import SubstitutionPanel from '~/components/Substitutions/SubstitutionPanel.vue'
import type { DefensiveDecision, OffensiveDecision, PlayOutcome, RollData, PlayResult } from '~/types/game'
import type { Lineup } from '~/types/player'

definePageMeta({
  layout: 'game',
  middleware: ['auth'],
})

const route = useRoute()
const gameStore = useGameStore()
const authStore = useAuthStore()
const uiStore = useUiStore()

// Auth is initialized by the auth plugin automatically

// Get game ID from route
const gameId = computed(() => route.params.id as string)

// WebSocket connection
const { socket, isConnected, isConnecting, connectionError, connect, forceReconnect } = useWebSocket()

// Debug info for troubleshooting Safari WebSocket issues
const config = useRuntimeConfig()
const wsDebugUrl = computed(() => config.public.wsUrl || 'not set')
const socketExists = computed(() => socket.value ? 'yes' : 'no')
const debugLog = ref('Loading...')

// Pass the raw string value from route params, not computed value
// useGameActions will create its own computed internally if needed
const actions = useGameActions(route.params.id as string)

// Destructure undoLastPlay for the undo button
const { undoLastPlay } = actions

// Game state from store
const gameState = computed(() => {
  const state = gameStore.gameState
  if (state) {
    const batterInfo = state.current_batter
      ? `lineup_id=${state.current_batter.lineup_id}, batting_order=${state.current_batter.batting_order}`
      : 'None'
    console.log('[Game Page] gameState computed - current_batter:', batterInfo)
  }
  return state
})
const playHistory = computed(() => gameStore.playHistory)
const canRollDice = computed(() => gameStore.canRollDice)
const canSubmitOutcome = computed(() => gameStore.canSubmitOutcome)
const pendingDefensiveSetup = computed(() => gameStore.pendingDefensiveSetup)
const pendingOffensiveDecision = computed(() => gameStore.pendingOffensiveDecision)
const pendingStealAttempts = computed(() => gameStore.pendingStealAttempts)
const decisionHistory = computed(() => gameStore.decisionHistory)
const needsDefensiveDecision = computed(() => gameStore.needsDefensiveDecision)
const needsOffensiveDecision = computed(() => gameStore.needsOffensiveDecision)
const basesEmpty = computed(() => gameStore.basesEmpty)
const pendingRoll = computed(() => gameStore.pendingRoll)
const lastPlayResult = computed(() => gameStore.lastPlayResult)
const currentDecisionPrompt = computed(() => gameStore.currentDecisionPrompt)

// Local UI state
const isLoading = ref(true)
const connectionStatus = ref<'connecting' | 'connected' | 'disconnected'>('connecting')
const showSubstitutions = ref(false)
const myTeamId = ref<number | null>(null) // TODO: Get from auth/game state

// Dynamic ScoreBoard height tracking
const scoreBoardRef = ref<HTMLElement | null>(null)
const scoreBoardHeight = ref(0)

// Computed helpers
const runnersState = computed(() => {
  if (!gameState.value) {
    return { first: false, second: false, third: false }
  }

  return {
    first: gameState.value.on_first !== null,
    second: gameState.value.on_second !== null,
    third: gameState.value.on_third !== null
  }
})

const runnersData = computed(() => {
  return {
    first: gameState.value?.on_first ?? null,
    second: gameState.value?.on_second ?? null,
    third: gameState.value?.on_third ?? null,
  }
})

const currentTeam = computed(() => {
  return gameState.value?.half === 'top' ? 'away' : 'home'
})

const isMyTurn = computed(() => {
  // TODO: Implement actual team ownership logic
  // For now, assume it's always the player's turn for testing
  return true
})

const decisionPhase = computed(() => {
  if (needsDefensiveDecision.value) return 'defensive'
  if (needsOffensiveDecision.value) return 'offensive'
  return 'idle'
})

// Phase F6: Conditional panel rendering
const showDecisions = computed(() => {
  // Don't show decision panels if there's a result pending dismissal
  if (lastPlayResult.value) {
    return false
  }

  const result = gameState.value?.status === 'active' &&
         isMyTurn.value &&
         (needsDefensiveDecision.value || needsOffensiveDecision.value)

  // Debug logging
  console.log('[Game Page] Panel visibility check:', {
    gameStatus: gameState.value?.status,
    isMyTurn: isMyTurn.value,
    needsDefensiveDecision: needsDefensiveDecision.value,
    needsOffensiveDecision: needsOffensiveDecision.value,
    decision_phase: gameState.value?.decision_phase,
    showDecisions: result,
    currentDecisionPrompt: currentDecisionPrompt.value,
    hasLastPlayResult: !!lastPlayResult.value
  })

  return result
})

const showGameplay = computed(() => {
  // Show gameplay panel if there's a result to display OR if we're in the resolution phase
  if (lastPlayResult.value) {
    return true
  }

  return gameState.value?.status === 'active' &&
         isMyTurn.value &&
         !needsDefensiveDecision.value &&
         !needsOffensiveDecision.value
})

const canMakeSubstitutions = computed(() => {
  return gameState.value?.status === 'active' && isMyTurn.value
})

const canUndo = computed(() => {
  // Can only undo if game is active and there are plays to undo
  return gameState.value?.status === 'active' && (gameState.value?.play_count ?? 0) > 0
})

// Lineup helpers for substitutions
const currentLineup = computed(() => {
  if (!myTeamId.value) return []
  return myTeamId.value === gameState.value?.home_team_id
    ? gameStore.homeLineup.filter(l => l.is_active)
    : gameStore.awayLineup.filter(l => l.is_active)
})

const benchPlayers = computed(() => {
  if (!myTeamId.value) return []
  return myTeamId.value === gameState.value?.home_team_id
    ? gameStore.homeLineup.filter(l => !l.is_active)
    : gameStore.awayLineup.filter(l => !l.is_active)
})

const currentBatter = computed(() => {
  const batterState = gameState.value?.current_batter
  if (!batterState) return null
  return gameStore.findPlayerInLineup(batterState.lineup_id)
})

const currentPitcher = computed(() => {
  const pitcherState = gameState.value?.current_pitcher
  if (!pitcherState) return null
  return gameStore.findPlayerInLineup(pitcherState.lineup_id)
})

// Methods - Gameplay (Phase F4)
const handleRollDice = async () => {
  console.log('[Game Page] Rolling dice')
  try {
    await actions.rollDice()
    // The dice_rolled event will update pendingRoll via WebSocket
  } catch (error) {
    console.error('[Game Page] Failed to roll dice:', error)
  }
}

const handleSubmitOutcome = async (data: { outcome: PlayOutcome; hitLocation?: string }) => {
  console.log('[Game Page] Submitting outcome:', data)
  try {
    await actions.submitManualOutcome(
      data.outcome,
      data.hitLocation
    )
    // Pending roll will be cleared by backend after successful submission
  } catch (error) {
    console.error('[Game Page] Failed to submit outcome:', error)
  }
}

const handleDismissResult = () => {
  console.log('[Game Page] Dismissing result')
  gameStore.clearLastPlayResult()
}

const handleDefensiveSubmit = async (decision: DefensiveDecision) => {
  console.log('[Game Page] Submitting defensive decision:', decision)
  try {
    await actions.submitDefensiveDecision(decision)
    gameStore.setPendingDefensiveSetup(decision)
    gameStore.addDecisionToHistory('Defensive', `${decision.infield_depth} infield, ${decision.outfield_depth} outfield`)
  } catch (error) {
    console.error('[Game Page] Failed to submit defensive decision:', error)
  }
}

const handleOffensiveSubmit = async (decision: Omit<OffensiveDecision, 'steal_attempts'>) => {
  console.log('[Game Page] Submitting offensive decision:', decision)
  try {
    // Combine with steal attempts
    const fullDecision: OffensiveDecision = {
      ...decision,
      steal_attempts: pendingStealAttempts.value,
    }
    await actions.submitOffensiveDecision(fullDecision)
    gameStore.setPendingOffensiveDecision(decision)
    const actionLabels: Record<string, string> = {
      swing_away: 'Swing Away',
      steal: 'Steal',
      check_jump: 'Check Jump',
      hit_and_run: 'Hit & Run',
      sac_bunt: 'Sac Bunt',
      squeeze_bunt: 'Squeeze Bunt',
    }
    gameStore.addDecisionToHistory('Offensive', actionLabels[decision.action] || decision.action)
  } catch (error) {
    console.error('[Game Page] Failed to submit offensive decision:', error)
  }
}

const handleStealAttemptsSubmit = (attempts: number[]) => {
  console.log('[Game Page] Updating steal attempts:', attempts)
  gameStore.setPendingStealAttempts(attempts)
}

// Methods - Substitutions (Phase F5)
const handlePinchHitter = async (data: { playerOutLineupId: number; playerInCardId: number; teamId: number }) => {
  console.log('[Game Page] Submitting pinch hitter:', data)
  try {
    await actions.submitSubstitution(
      'pinch_hitter',
      data.playerOutLineupId,
      data.playerInCardId,
      data.teamId
    )
    showSubstitutions.value = false
  } catch (error) {
    console.error('[Game Page] Failed to submit pinch hitter:', error)
  }
}

const handleDefensiveReplacement = async (data: { playerOutLineupId: number; playerInCardId: number; newPosition: string; teamId: number }) => {
  console.log('[Game Page] Submitting defensive replacement:', data)
  try {
    await actions.submitSubstitution(
      'defensive_replacement',
      data.playerOutLineupId,
      data.playerInCardId,
      data.teamId,
      data.newPosition
    )
    showSubstitutions.value = false
  } catch (error) {
    console.error('[Game Page] Failed to submit defensive replacement:', error)
  }
}

const handlePitchingChange = async (data: { playerOutLineupId: number; playerInCardId: number; teamId: number }) => {
  console.log('[Game Page] Submitting pitching change:', data)
  try {
    await actions.submitSubstitution(
      'pitching_change',
      data.playerOutLineupId,
      data.playerInCardId,
      data.teamId
    )
    showSubstitutions.value = false
  } catch (error) {
    console.error('[Game Page] Failed to submit pitching change:', error)
  }
}

const handleSubstitutionCancel = () => {
  console.log('[Game Page] Cancelling substitution')
  showSubstitutions.value = false
}

// Undo handler
const handleUndoLastPlay = () => {
  console.log('[Game Page] Undoing last play')
  undoLastPlay(1)
}

// Retry connection with auth check
const retryWithAuth = async () => {
  console.log('[Game Page] Retry with auth check')
  isLoading.value = true
  connectionStatus.value = 'connecting'

  // First check auth
  const isAuthed = await authStore.checkAuth()
  console.log('[Game Page] Auth result:', isAuthed, 'isAuthenticated:', authStore.isAuthenticated)

  if (!isAuthed) {
    console.error('[Game Page] Auth failed')
    isLoading.value = false
    connectionStatus.value = 'disconnected'
    return
  }

  // Force reconnect
  forceReconnect()
}

// Measure ScoreBoard height dynamically
const updateScoreBoardHeight = () => {
  if (scoreBoardRef.value) {
    scoreBoardHeight.value = scoreBoardRef.value.offsetHeight
    console.log('[Game Page] ScoreBoard height:', scoreBoardHeight.value)
  }
}

// Lifecycle
onMounted(async () => {
  // Debug logging for Safari troubleshooting
  debugLog.value = `Mounted at ${new Date().toLocaleTimeString()}\n`
  debugLog.value += `isConnected: ${isConnected.value}, isConnecting: ${isConnecting.value}\n`

  // Try to connect WebSocket immediately - cookies will be sent automatically
  // Backend will authenticate via cookies and reject if invalid
  if (!isConnected.value && !isConnecting.value) {
    debugLog.value += 'Calling connect()...\n'
    connect()
    debugLog.value += 'connect() called\n'
  } else {
    debugLog.value += 'Skipped connect (already connected/connecting)\n'
  }

  // Also check auth store (for display purposes)
  authStore.checkAuth()

  // Wait for connection, then join game
  watch(isConnected, async (connected) => {
    if (connected) {
      connectionStatus.value = 'connected'
      console.log('[Game Page] Connected - Joining game as player')

      // Join game room
      await actions.joinGame('player')

      // Request current game state
      await actions.requestGameState()

      isLoading.value = false
    } else {
      connectionStatus.value = 'disconnected'
    }
  }, { immediate: true })

  // Timeout fallback - if not connected after 5 seconds, stop loading
  setTimeout(() => {
    if (isLoading.value) {
      console.error('[Game Page] Connection timeout - stopping loading state')
      isLoading.value = false
      connectionStatus.value = 'disconnected'
    }
  }, 5000)

  // Measure ScoreBoard height after initial render
  setTimeout(() => {
    updateScoreBoardHeight()
  }, 100)

  // Update on window resize
  if (import.meta.client) {
    window.addEventListener('resize', updateScoreBoardHeight)
  }
})

// Watch for game state to load lineups
watch(gameState, (state, oldState) => {
  if (state && state.home_team_id && state.away_team_id) {
    const oldBatter = oldState?.current_batter
    const newBatter = state?.current_batter
    const oldBatterInfo = oldBatter
      ? `lineup_id=${oldBatter.lineup_id}, batting_order=${oldBatter.batting_order}`
      : 'None'
    const newBatterInfo = newBatter
      ? `lineup_id=${newBatter.lineup_id}, batting_order=${newBatter.batting_order}`
      : 'None'
    console.log('[Game Page] gameState watch - current_batter:', oldBatterInfo, '->', newBatterInfo)
    // Request lineup data for both teams to populate player names
    console.log('[Game Page] Game state received - requesting lineups for teams:', state.home_team_id, state.away_team_id)
    actions.getLineup(state.home_team_id)
    actions.getLineup(state.away_team_id)
  }
}, { immediate: true })

// Quality of Life: Auto-submit default decisions when bases are empty
watch([needsDefensiveDecision, needsOffensiveDecision, basesEmpty], ([defensive, offensive, empty]) => {
  // Only auto-submit if it's the player's turn and bases are empty
  if (!isMyTurn.value || !empty) return

  // Auto-submit defensive decision with defaults
  if (defensive && !pendingDefensiveSetup.value) {
    const defaultDefense: DefensiveDecision = {
      infield_depth: 'normal',
      outfield_depth: 'normal',
      hold_runners: []
    }
    console.log('[Game Page] Bases empty - auto-submitting default defensive decision')
    uiStore.showInfo('Bases empty - auto-submitting default defensive setup', 2000)
    handleDefensiveSubmit(defaultDefense)
  }

  // Auto-submit offensive decision with swing away
  if (offensive && !pendingOffensiveDecision.value) {
    const defaultOffense = {
      action: 'swing_away' as const
    }
    console.log('[Game Page] Bases empty - auto-submitting default offensive decision')
    uiStore.showInfo('Bases empty - auto-submitting swing away', 2000)
    handleOffensiveSubmit(defaultOffense)
  }
})

onUnmounted(() => {
  console.log('[Game Page] Unmounted - Leaving game')

  // Leave game room
  actions.leaveGame()

  // Reset game store
  gameStore.resetGame()

  // Cleanup resize listener
  if (import.meta.client) {
    window.removeEventListener('resize', updateScoreBoardHeight)
  }
})

// Watch for connection errors
watch(connectionError, (error) => {
  if (error) {
    console.error('[Game Page] Connection error:', error)
  }
})
</script>

<style scoped>
/* Additional styling if needed */
</style>
