import React, { useState, useEffect, useMemo, useCallback } from "react"
import { getVerticalOffset } from "../../utils/randomUtils"
import Dice from "../../utils/dice/Dice"
import { useGameWebSocketContext } from "../../contexts/GameWebSocketContext"
import JokerApprovalModal from "./JokerApprovalModal"
import CardDisplayModal from "./CardDisplayModal"
import ConsequenceModal from "./ConsequenceModal"
import StepPredictionModal from "./StepPredictionModal"

// Constants - outside component to prevent recreation
const PLAYER_STYLES = [
  { color: "bg-blue-600", emoji: "🐍" },
  { color: "bg-green-600", emoji: "🐢" },
  { color: "bg-purple-600", emoji: "🐇" },
  { color: "bg-yellow-600", emoji: "🦊" },
  { color: "bg-red-600", emoji: "🦁" },
  { color: "bg-pink-600", emoji: "🐷" },
  { color: "bg-orange-600", emoji: "🐯" },
  { color: "bg-indigo-600", emoji: "🐺" },
]

const BOARD_CONFIG = {
  rows: 5,
  cols: 20,
  cellSize: 40,
  cellMargin: 2.5,
  rowSpacing: 70,
}

// Helper functions outside component
const mapFieldType = (backendType) => {
  switch (backendType) {
    case 'positive': return 'good'
    case 'negative': return 'bad'
    case 'luck': return 'clover'
    default: return 'regular'
  }
}

const getDefaultFieldType = (count) => {
  if (count % 17 === 0) return "clover"
  if (count % 13 === 0) return "bad"
  if ((count + 5) % 13 === 0) return "good"
  return "regular"
}

const GameScreen = () => {
  // WebSocket connection from context (maintains connection across navigation)
  const { 
    isConnected, 
    gameState, 
    players: backendPlayers, 
    playerPositions, // NEW: Get dedicated position tracking state
    boardData: websocketBoardData, 
    currentTurn,
    currentTurnName,
    isMyTurn,
    playerIdentifier,
    isGamemaster,
    error,
    playerDiceRolls,
    rollDice,
    approveJoker,
    rejectJoker,
    submitAnswer,
    submitPositionGuess,
    submitJokerPositionGuess,
    leaveGame,
    addEventListener,
    removeEventListener
  } = useGameWebSocketContext()
  
  // Try to get boardData from WebSocket, fallback to localStorage
  const boardData = useMemo(() => {
    if (websocketBoardData) return websocketBoardData
    
    try {
      const stored = localStorage.getItem('boardData')
      if (stored) {
        console.log('📦 Loading boardData from localStorage')
        return JSON.parse(stored)
      }
    } catch (err) {
      console.error('Failed to parse boardData from localStorage:', err)
    }
    
    return null
  }, [websocketBoardData])
  
  const [path, setPath] = useState([])
  const [players, setPlayers] = useState([])
  
  // Joker approval modal state
  const [isJokerModalOpen, setIsJokerModalOpen] = useState(false)
  const [currentJokerRequest, setCurrentJokerRequest] = useState(null)

  // Card display modal state
  const [isCardModalOpen, setIsCardModalOpen] = useState(false)
  const [currentCard, setCurrentCard] = useState(null)
  const [isMyCardTurn, setIsMyCardTurn] = useState(false) // Track if I'm the one answering

  // Consequence modal state
  const [isConsequenceModalOpen, setIsConsequenceModalOpen] = useState(false)
  const [currentConsequence, setCurrentConsequence] = useState(null)

  // Step prediction modal state
  const [isPredictionModalOpen, setIsPredictionModalOpen] = useState(false)
  const [currentPredictionData, setCurrentPredictionData] = useState(null)

  // End game modal state
  const [isEndGameModalOpen, setIsEndGameModalOpen] = useState(false)
  const [endGameData, setEndGameData] = useState(null)

  // Animation state management
  const [animatingPlayers, setAnimatingPlayers] = useState({}) // { playerId: { from, to, startTime, duration } }
  const [animatedPositions, setAnimatedPositions] = useState({}) // { playerId: currentAnimatedPosition }

  // Memoized board dimensions
  const { rows, cols, totalCells, cellSize, cellMargin, rowSpacing, topOffset, width, height } = useMemo(() => {
    const { rows, cols, cellSize, cellMargin, rowSpacing } = BOARD_CONFIG
    const topOffset = rowSpacing * 0.5
    const bottomOffset = rowSpacing * 0.5
    const totalCells = rows * cols
    
    return {
      rows,
      cols,
      totalCells,
      cellSize,
      cellMargin,
      rowSpacing,
      topOffset,
      bottomOffset,
      width: cols * (cellSize + cellMargin * 2),
      height: rows * (cellSize + cellMargin * 2 + rowSpacing) + topOffset + bottomOffset - rowSpacing,
    }
  }, [])

  // Memoized path generator - Snake pattern with proper turn handling
  const generateWindingPath = useCallback((backendFields = null) => {
    const path = []
    const hasBackendData = backendFields && Array.isArray(backendFields)
    
    let currentNum = 1
    
    // Generate all 100 positions
    while (currentNum <= totalCells) {
      const row = Math.floor((currentNum - 1) / cols)
      const posInRow = (currentNum - 1) % cols
      const isLeftToRight = row % 2 === 0
      
      // Calculate column based on direction
      const col = isLeftToRight ? posInRow : (cols - 1 - posInRow)
      
      // Base Y position for this row
      let baseYPosition = topOffset + row * (cellSize + cellMargin * 2 + rowSpacing)
      
      // Apply vertical offset for wave effect
      let yOffset = getVerticalOffset(currentNum - 1)
      
      // Special handling for turn positions (21, 41, 61, 81)
      // These should be positioned between rows to show the turn
      if (currentNum % cols === 1 && currentNum > 1) {
        // This is the first element of a new row (21, 41, 61, 81)
        // Position it halfway between the previous row and current row
        baseYPosition = topOffset + (row - 0.5) * (cellSize + cellMargin * 2 + rowSpacing)
        yOffset = 0 // Reset wave offset for turn positions
      }
      
      const backendField = hasBackendData ? backendFields.find(f => f.position === currentNum) : null
      
      path.push({
        number: currentNum,
        x: col * (cellSize + cellMargin * 2),
        y: baseYPosition + yOffset,
        type: backendField ? mapFieldType(backendField.type) : getDefaultFieldType(currentNum - 1),
        stepValue: backendField?.stepValue || 0,
      })
      
      currentNum++
    }

    return path
  }, [rows, cols, totalCells, cellSize, cellMargin, rowSpacing, topOffset])

  // Update path when boardData changes
  useEffect(() => {
    if (boardData?.fields) {
      setPath(generateWindingPath(boardData.fields))
    } else if (path.length === 0) {
      setPath(generateWindingPath())
    }
  }, [boardData, generateWindingPath])

  // Update players from backend - memoized mapping (UI properties only, no position)
  useEffect(() => {
    if (!backendPlayers?.length) return

    const mappedPlayers = backendPlayers.map((player, index) => {
      const playerName = player.playerName || player.name || `Player ${index + 1}`;
      
      return {
        id: player.playerId || player.id || index,
        name: playerName,
        // NO position stored here - always read from context playerPositions
        score: player.score || 0,
        color: PLAYER_STYLES[index % PLAYER_STYLES.length].color,
        emoji: PLAYER_STYLES[index % PLAYER_STYLES.length].emoji,
        isOnline: player.isOnline !== undefined ? player.isOnline : true,
        isReady: player.isReady || false,
      };
    })
    
    setPlayers(mappedPlayers)
  }, [backendPlayers])

  // Debug: Log playerPositions changes
  useEffect(() => {
    console.log('🔍 [GameScreen] playerPositions changed:', JSON.stringify(playerPositions));
    players.forEach(p => {
      const pos = playerPositions?.[p.name];
      console.log(`🔍 [GameScreen] Player ${p.name} position from context: ${pos}`);
    });
  }, [playerPositions, players]);

  // Animation loop using requestAnimationFrame
  useEffect(() => {
    let animationFrameId

    const animate = () => {
      const now = Date.now()
      const updates = {}
      let hasActiveAnimations = false

      Object.entries(animatingPlayers).forEach(([playerId, animation]) => {
        const elapsed = now - animation.startTime
        const progress = Math.min(elapsed / animation.duration, 1)
        
        // Easing function (ease-in-out)
        const eased = progress < 0.5
          ? 2 * progress * progress
          : 1 - Math.pow(-2 * progress + 2, 2) / 2

        // Interpolate position
        const currentPos = Math.round(
          animation.from + (animation.to - animation.from) * eased
        )
        
        updates[playerId] = currentPos

        if (progress < 1) {
          hasActiveAnimations = true
        }
        // Animation complete - no local position update needed
        // Position always comes from context playerPositions
      })

      if (Object.keys(updates).length > 0) {
        setAnimatedPositions(updates)
      }

      // Clean up completed animations
      if (!hasActiveAnimations && Object.keys(animatingPlayers).length > 0) {
        setAnimatingPlayers({})
        setAnimatedPositions({})
      } else if (hasActiveAnimations) {
        animationFrameId = requestAnimationFrame(animate)
      }
    }

    if (Object.keys(animatingPlayers).length > 0) {
      animationFrameId = requestAnimationFrame(animate)
    }

    return () => {
      if (animationFrameId) {
        cancelAnimationFrame(animationFrameId)
      }
    }
  }, [animatingPlayers])

  // Listen to player-moving event to start animation
  useEffect(() => {
    if (!addEventListener) return

    const handlePlayerMoving = (moveData) => {
      const duration = Math.abs(moveData.toPosition - moveData.fromPosition) * 50 // 50ms per position
      const clampedDuration = Math.max(500, Math.min(duration, 2000)) // Between 0.5s and 2s

      // Backend sends 1-based positions (1-100), use directly
      setAnimatingPlayers(prev => ({
        ...prev,
        [moveData.playerId]: {
          from: moveData.fromPosition,
          to: moveData.toPosition,
          startTime: Date.now(),
          duration: clampedDuration
        }
      }))
    }

    addEventListener('game:player-moving', handlePlayerMoving)
    return () => removeEventListener('game:player-moving')
  }, [addEventListener, removeEventListener])

  // Listen to errors and close modals
  useEffect(() => {
    if (!addEventListener) return

    const handleGameError = (errorData) => {
      console.error('❌ Game error:', errorData)
      // Close any open modals on error
      setIsCardModalOpen(false)
      setIsPredictionModalOpen(false)
      setIsJokerModalOpen(false)
      // Show error in consequence modal if severe
      if (errorData.message && errorData.message.includes('card')) {
        setCurrentConsequence({
          isCorrect: false,
          explanation: errorData.message || 'An error occurred',
          consequenceType: null,
          consequenceValue: 0
        })
        setIsConsequenceModalOpen(true)
      }
    }

    addEventListener('game:error', handleGameError)
    return () => removeEventListener('game:error')
  }, [addEventListener, removeEventListener])

  // Listen to player-arrived event (trigger animation for position changes)
  useEffect(() => {
    const handlePlayerArrived = (event) => {
      const arrivalData = event.detail
      
      // Context manager already updated playerPositions
      // Just set animation flag for visual animation
      const player = players.find(p => p.id === arrivalData.playerId || p.name === arrivalData.playerName)
      if (player) {
        setAnimatingPlayers(prevAnimating => ({
          ...prevAnimating,
          [player.id]: true
        }))
        
        // Clear animation flag after animation completes (2 seconds)
        setTimeout(() => {
          setAnimatingPlayers(prevAnimating => {
            const newAnimating = { ...prevAnimating }
            delete newAnimating[player.id]
            return newAnimating
          })
        }, 2000)
      }
    }

    // Listen to window CustomEvent instead of socket event (context already handles socket)
    window.addEventListener('game:player-arrived', handlePlayerArrived)
    return () => window.removeEventListener('game:player-arrived', handlePlayerArrived)
  }, [players])

  // Listen to Joker card events
  useEffect(() => {
    if (!addEventListener) return

    const handleJokerDrawn = (jokerData) => {
      console.log('🃏 Joker kártya húzva:', jokerData)
      
      if (isGamemaster) {
        // Gamemaster sees approval modal with approve/deny buttons
        console.log('👑 Gamemaster látja a jóváhagyási modal-t')
        setCurrentJokerRequest({
          playerId: jokerData.playerId,
          playerName: jokerData.playerName,
          playerEmoji: jokerData.playerEmoji || "🎭",
          cardTitle: jokerData.cardTitle || jokerData.jokerCard?.question,
          cardDescription: jokerData.cardDescription || jokerData.jokerCard?.consequence?.description,
          points: jokerData.points || jokerData.jokerCard?.consequence?.value,
          cardId: jokerData.cardId || jokerData.jokerCard?.id,
          requestId: jokerData.requestId, // Important: requestId from backend
          timestamp: Date.now()
        })
        setIsJokerModalOpen(true)
      } else {
        // Other players see the joker card as a read-only card display
        console.log('👥 Játékosok látják a joker kártyát (csak olvasás)')
        setCurrentCard({
          type: 'JOKER',
          question: jokerData.jokerCard?.question || jokerData.cardTitle || 'Joker Kártya Feladat',
          consequence: jokerData.jokerCard?.consequence?.description || jokerData.cardDescription,
          playerName: jokerData.playerName,
          playerEmoji: jokerData.playerEmoji || "🎭",
          isReadOnly: true,
          waitingForGamemaster: true
        })
        setIsCardModalOpen(true)
        setIsMyCardTurn(false) // Not my turn to answer
      }
    }

    // Listen for gamemaster decision request (correct event name per docs)
    addEventListener('game:joker-drawn', handleJokerDrawn)
    addEventListener('game:gamemaster-decision-request', handleJokerDrawn)
    
    return () => {
      removeEventListener('game:joker-drawn')
      removeEventListener('game:gamemaster-decision-request')
    }
  }, [addEventListener, removeEventListener, isGamemaster])

  // Listen to card drawn events (kártya megjelenítés)
  useEffect(() => {
    if (!addEventListener) return

    // Handle card drawn FOR ME (I need to answer)
    const handleCardDrawnSelf = (data) => {
      console.log('🎴 Kártya húzva NEKEM:', data)
      const cardData = data.cardData || data;
      console.log('📦 Card data structure:', cardData)
      setCurrentCard({
        id: cardData.cardid || cardData.id,
        type: cardData.type,
        question: cardData.question || cardData.text || cardData.statement,
        answerOptions: cardData.answerOptions || [],
        sentencePairs: cardData.sentencePairs || [],
        words: cardData.words || [],
        acceptableAnswers: cardData.acceptableAnswers || [],
        correctAnswer: cardData.correctAnswer,
        hint: cardData.hint,
        points: cardData.points || 0,
        timeLimit: data.timeLimit || cardData.timeLimit || 60
      })
      setIsMyCardTurn(true) // I need to answer
      setIsCardModalOpen(true)
    }

    // Handle card drawn by ANOTHER PLAYER (spectator mode)
    const handleCardDrawn = (data) => {
      console.log('👀 Kártya húzva más játékos által:', data)
      const cardData = data.cardData || data;
      setCurrentCard({
        id: cardData.cardid || cardData.id,
        type: cardData.type,
        question: cardData.question || cardData.text || cardData.statement,
        answerOptions: cardData.answerOptions || [],
        sentencePairs: cardData.sentencePairs || [],
        words: cardData.words || [],
        timeLimit: data.timeLimit || cardData.timeLimit || 60
      })
      setIsMyCardTurn(false) // Spectator mode
      setIsCardModalOpen(true)
    }

    addEventListener('game:card-drawn-self', handleCardDrawnSelf)
    addEventListener('game:card-drawn', handleCardDrawn)
    
    return () => {
      removeEventListener('game:card-drawn-self')
      removeEventListener('game:card-drawn')
    }
  }, [addEventListener, removeEventListener])

  // Listen to answer validation (következmény megjelenítés)
  useEffect(() => {
    if (!addEventListener) return

    const handleAnswerValidated = (resultData) => {
      console.log('✅ Válasz kiértékelve:', resultData)
      
      // Close card modal first
      setIsCardModalOpen(false)
      
      // Show consequence modal
      setCurrentConsequence({
        isCorrect: resultData.isCorrect || resultData.correct,
        playerAnswer: resultData.playerAnswer || resultData.answer,
        correctAnswer: resultData.correctAnswer,
        explanation: resultData.explanation || '',
        consequenceType: resultData.consequenceType || resultData.consequence?.type,
        consequenceValue: resultData.consequenceValue || resultData.consequence?.value || 0,
        points: resultData.pointsEarned || resultData.points || 0
      })
      setIsConsequenceModalOpen(true)
    }

    // Also listen for luck consequences (instant consequences from luck cards)
    const handleLuckConsequence = (luckData) => {
      console.log('🍀 Szerencse kártya következménye:', luckData)
      
      // Close card modal if it's open (shouldn't be for luck, but just in case)
      setIsCardModalOpen(false)
      
      setCurrentConsequence({
        isCorrect: true, // Luck cards don't have right/wrong answers
        consequenceType: luckData.consequenceType,
        consequenceValue: luckData.value || luckData.consequenceValue || 0,
        explanation: luckData.description || luckData.message || 'Szerencse kártya!',
        playerAnswer: null,
        correctAnswer: null
      })
      setIsConsequenceModalOpen(true)
    }

    const handleCardResult = (resultData) => {
      console.log('🎴 Card result (luck):', resultData)
      // This is for luck cards that use game:card-result event
      setIsCardModalOpen(false)
      
      setCurrentConsequence({
        isCorrect: true,
        consequenceType: resultData.consequence?.type,
        consequenceValue: resultData.consequence?.value || 0,
        explanation: resultData.description || 'Szerencse kártya!',
        playerAnswer: null,
        correctAnswer: null
      })
      setIsConsequenceModalOpen(true)
    }

    addEventListener('game:answer-validated', handleAnswerValidated)
    addEventListener('game:luck-consequence', handleLuckConsequence)
    addEventListener('game:card-result', handleCardResult)
    
    return () => {
      removeEventListener('game:answer-validated')
      removeEventListener('game:luck-consequence')
      removeEventListener('game:card-result')
    }
  }, [addEventListener, removeEventListener])

  // Listen to position guess requests (lépés tippelés)
  useEffect(() => {
    if (!addEventListener) return

    const handlePositionGuessRequest = (predictionData) => {
      console.log('🎯 Pozíció tippelés kérés:', predictionData)
      setCurrentPredictionData({
        currentPosition: predictionData.currentPosition,
        diceRoll: predictionData.diceRoll || predictionData.dice,
        fieldStepValue: predictionData.fieldStepValue || predictionData.fieldStep || 0,
        patternModifier: predictionData.patternModifier || predictionData.zoneModifier || 0,
        cardText: predictionData.cardText || predictionData.text || 'Tippeld meg, hova fogsz lépni!',
        timeLimit: predictionData.timeLimit || 30
      })
      setIsPredictionModalOpen(true)
    }

    const handleJokerPositionGuessRequest = (predictionData) => {
      console.log('🃏🎯 Joker után pozíció tippelés kérés:', predictionData)
      setCurrentPredictionData({
        currentPosition: predictionData.currentPosition,
        diceRoll: predictionData.diceRoll || predictionData.dice,
        fieldStepValue: predictionData.fieldStepValue || predictionData.fieldStep || 0,
        patternModifier: predictionData.patternModifier || predictionData.zoneModifier || 0,
        cardText: predictionData.message || 'Tippeld meg a végső pozíciódat joker után!',
        timeLimit: predictionData.timeLimit || 30,
        isJoker: true // Mark this as joker guess
      })
      setIsPredictionModalOpen(true)
    }

    const handleGuessResult = (resultData) => {
      console.log('✅ Tippelés eredménye:', resultData)
      // Close prediction modal
      setIsPredictionModalOpen(false)
      
      // Backend already emits game:player-arrived before this event
      // Position is handled by context manager, no need for pendingPositionUpdate
      setCurrentConsequence({
        isCorrect: resultData.guessCorrect,
        playerAnswer: resultData.guessedPosition,
        correctAnswer: resultData.actualPosition,
        explanation: resultData.message,
        consequenceType: resultData.penaltyApplied ? 'penalty' : 'success',
        consequenceValue: resultData.penaltyApplied ? -2 : 0
      })
      setIsConsequenceModalOpen(true)
    }

    const handleJokerComplete = (resultData) => {
      console.log('🃏✅ Joker tippelés eredménye:', resultData)
      // Close prediction modal
      setIsPredictionModalOpen(false)
      
      // Backend already emits game:player-arrived before this event (if moved)
      // Position is handled by context manager, no need for pendingPositionUpdate
      setCurrentConsequence({
        isCorrect: resultData.guessCorrect,
        playerAnswer: resultData.guessedPosition,
        correctAnswer: resultData.actualPosition,
        explanation: resultData.message,
        consequenceType: resultData.penaltyApplied ? 'penalty' : (resultData.moved ? 'success' : 'neutral'),
        consequenceValue: resultData.penaltyApplied ? -2 : 0
      })
      setIsConsequenceModalOpen(true)
    }

    addEventListener('game:position-guess-request', handlePositionGuessRequest)
    addEventListener('game:joker-position-guess-request', handleJokerPositionGuessRequest)
    addEventListener('game:guess-result', handleGuessResult)
    addEventListener('game:joker-complete', handleJokerComplete)
    return () => {
      removeEventListener('game:position-guess-request')
      removeEventListener('game:joker-position-guess-request')
      removeEventListener('game:guess-result')
      removeEventListener('game:joker-complete')
    }
  }, [addEventListener, removeEventListener])

  // Listen to game end event
  useEffect(() => {
    if (!addEventListener) return

    const handleGameEnded = (endData) => {
      console.log('🏆 Játék vége:', endData)
      setEndGameData({
        winnerName: endData.winnerName,
        winnerId: endData.winner,
        finalPositions: endData.finalPositions || [],
        message: endData.message
      })
      setIsEndGameModalOpen(true)
    }

    const handleGamemasterDecision = (decisionData) => {
      console.log('👑 Gamemaster döntés:', decisionData)
      // Close joker card modal for non-gamemaster players when decision is made
      if (!isGamemaster) {
        setIsCardModalOpen(false)
      }
    }

    addEventListener('game:ended', handleGameEnded)
    addEventListener('game:gamemaster-decision-result', handleGamemasterDecision)
    return () => {
      removeEventListener('game:ended')
      removeEventListener('game:gamemaster-decision-result')
    }
  }, [addEventListener, removeEventListener, isGamemaster])

  // Joker jóváhagyás
  const handleApproveJoker = useCallback(async (jokerRequest) => {
    console.log('✅ Joker feladat jóváhagyva:', jokerRequest)
    
    // WebSocket üzenet a backend felé - csak requestId kell
    approveJoker(jokerRequest.requestId)
    
    // Modal bezárása
    setIsJokerModalOpen(false)
  }, [approveJoker])

  // Joker elutasítás
  const handleRejectJoker = useCallback(async (jokerRequest) => {
    console.log('❌ Joker feladat elutasítva:', jokerRequest)
    
    // WebSocket üzenet a backend felé - csak requestId kell
    rejectJoker(jokerRequest.requestId, 'Joker rejected by gamemaster')
    
    // Modal bezárása
    setIsJokerModalOpen(false)
  }, [rejectJoker])

  // Kártya válasz beküldése
  const handleSubmitAnswer = useCallback((answer) => {
    console.log('📝 Válasz beküldve:', answer, 'Card ID:', currentCard?.id)
    
    // WebSocket emit a backend felé - uses context method with card ID
    submitAnswer(answer, currentCard?.id)
    
    // A consequence modal automatikusan megnyílik a 'game:answer-validated' event hatására
  }, [submitAnswer, currentCard])

  // Consequence modal bezárása
  const handleConsequenceClose = useCallback(() => {
    // Position updates are handled by game:player-arrived event in context
    // No need to manually update positions here
    setIsConsequenceModalOpen(false)
  }, [])

  // Pozíció tippelés beküldése
  const handleSubmitPrediction = useCallback((predictedPosition) => {
    console.log('🎯 Pozíció tippelés beküldve:', predictedPosition)
    
    // WebSocket emit a backend felé (különböző event joker-nél)
    if (currentPredictionData?.isJoker) {
      console.log('🃏 Joker pozíció tipp beküldése')
      submitJokerPositionGuess(predictedPosition)
    } else {
      submitPositionGuess(predictedPosition)
    }
    
    // Modal bezárása
    setIsPredictionModalOpen(false)
  }, [submitPositionGuess, submitJokerPositionGuess, currentPredictionData])

  // Sorted players - memoized (sort by context position)
  const sortedPlayers = useMemo(
    () => [...players].sort((a, b) => {
      const posA = playerPositions?.[a.name] || 0
      const posB = playerPositions?.[b.name] || 0
      return posB - posA
    }),
    [players, playerPositions]
  )

  // Handle dice roll
  const handleDiceRoll = useCallback((value) => {
    console.log('🎲 Dobás:', value)
    const success = rollDice(value)
    if (success) {
      console.log('✅ Kockadobás elküldve a szervernek')
    } else {
      console.warn('⚠️ Kockadobás sikertelen - nincs kapcsolat vagy nem te következel')
    }
  }, [rollDice])

  // Get field style - memoized
  const getFieldStyle = useCallback((type) => {
    switch (type) {
      case "clover":
        return "bg-teal-700 border-teal-500 shadow-teal-800"
      case "bad":
        return "bg-red-800 border-red-600 shadow-red-900"
      case "good":
        return "bg-blue-800 border-blue-600 shadow-blue-900"
      default:
        return "bg-gray-800 border-gray-600 shadow-gray-900"
    }
  }, [])

  // Get player position - memoized
  const getPlayerPosition = useCallback((playerPosition) => {
    const field = path.find((p) => p.number === playerPosition)
    return field ? { top: `${field.y}px`, left: `${field.x}px` } : { top: 0, left: 0 }
  }, [path])

  // Get medal style - memoized
  const getMedalStyle = useCallback((rank) => {
    switch (rank) {
      case 1:
        return "bg-yellow-400 text-yellow-900 border-yellow-500 shadow-yellow-600"
      case 2:
        return "bg-gray-400 text-gray-900 border-gray-500 shadow-gray-600"
      case 3:
        return "bg-orange-500 text-orange-900 border-orange-600 shadow-orange-700"
      default:
        return "bg-gray-700 text-gray-300 border-gray-600 shadow-gray-800"
    }
  }, [])

  return (
    <div className="p-4 bg-gradient-to-br from-gray-900 via-gray-800 to-teal-900 min-h-screen flex items-center justify-center">
      <div className="w-full">
      {/* Exit Game Button - Top Right Corner */}
      <div className="fixed top-4 right-4 z-50">
        <button
          onClick={() => {
            if (window.confirm('Biztosan ki szeretnél lépni a játékból?')) {
              leaveGame()
              window.location.href = '/'
            }
          }}
          className="bg-red-600 hover:bg-red-700 text-white font-semibold py-2 px-4 rounded-lg shadow-lg transition-colors duration-200 flex items-center gap-2 cursor-pointer"
          title="Kilépés a játékból"
        >
          🚪 Kilépés
        </button>
      </div>

      {/* Game Info Bar */}
        {gameState && (
          <div className="fixed top-4 left-4 z-50">
            <div className="bg-gray-800 border border-teal-700 px-4 py-2 rounded-lg shadow-lg">
              <div className="text-teal-300 text-sm font-medium">
                🎮 Játék kód: <span className="font-bold text-white">{gameState.gameCode || 'N/A'}</span>
              </div>
              <div className="flex items-center gap-2 mt-1">
                <div className={`w-2 h-2 rounded-full ${
                  isConnected ? 'bg-green-400 animate-pulse' : 'bg-red-400'
                }`}></div>
                <span className={`text-xs ${
                  isConnected ? 'text-green-400' : 'text-red-400'
                }`}>
                  {isConnected ? 'Csatlakozva' : 'Kapcsolódás...'}
                </span>
              </div>
              {currentTurn && (
                <div className="text-gray-400 text-xs mt-1">
                  🎯 Köron: <span className={`font-bold ${isMyTurn ? 'text-green-400' : 'text-white'}`}>
                    {currentTurnName || players.find(p => p.id === currentTurn || p.playerName === currentTurn || p.name === currentTurn)?.name || currentTurn || 'Betöltés...'}
                  </span>
                  {isMyTurn && <span className="ml-2 text-green-400 animate-pulse">← Te vagy!</span>}
                </div>
              )}
            </div>
          </div>
        )}

        <div className="flex flex-col md:flex-row gap-6 justify-center">
          {/* Game Board */}
          <div className="relative bg-gray-800 p-6 rounded-2xl shadow-xl border border-teal-700 flex flex-col items-center justify-center overflow-hidden">
            {/* Background decoration */}
            <div className="absolute w-full h-full opacity-10 pointer-events-none overflow-hidden">
              {[...Array(35)].map((_, i) => (
                <div
                  key={i}
                  className="absolute rounded-full bg-teal-600 animate-pulse"
                  style={{
                    width: Math.random() * 120 + 40 + "px",
                    height: Math.random() * 120 + 40 + "px",
                    top: Math.random() * 100 + "%",
                    left: Math.random() * 100 + "%",
                    transform: "translate(-50%, -50%)",
                  }}
                ></div>
              ))}
            </div>
            
            <div className="relative" style={{ height: `${height}px`, width: `${width}px` }}>
              {/* Fields */}
              {path.map((field) => (
                <div
                  key={field.number}
                  className={`absolute w-10 h-10 border-2 flex items-center justify-center transition-all shadow-md hover:scale-110 ${getFieldStyle(
                    field.type
                  )}`}
                  style={{
                    top: `${field.y}px`,
                    left: `${field.x}px`,
                    width: `${cellSize}px`,
                    height: `${cellSize}px`,
                    margin: `${cellMargin}px`,
                  }}
                >
                  <span className="text-gray-300 text-sm font-bold">{field.number}</span>
                </div>
              ))}

              {/* Player tokens */}
              {players.map((player) => {
                // ALWAYS read position from context playerPositions, not local state
                // Backend uses 1-based indexing (1-100)
                const contextPosition = playerPositions?.[player.name] ?? 1
                // Use animated position if player is currently animating, otherwise use context position
                const displayPosition = animatedPositions[player.id] ?? contextPosition
                const isAnimating = animatingPlayers[player.id] !== undefined

                return (
                  <div
                    key={player.id}
                    className={`absolute w-6 h-6 ${player.color} rounded-full border-2 border-white shadow-lg flex items-center justify-center text-white text-xs font-bold z-10 transition-transform ${isAnimating ? 'scale-110' : ''}`}
                    style={{
                      ...getPlayerPosition(displayPosition),
                      transform: "translate(17px, 17px)",
                      transition: isAnimating ? 'none' : 'all 0.3s ease'
                    }}
                  >
                    {player.emoji}
                  </div>
                )
              })}
            </div>
          </div>

          {/* Right sidebar */}
          <div className="flex-1 max-w-md">
            <div className="bg-gray-800 rounded-xl p-4 shadow-lg mb-4 border border-teal-700">
              <h2 className="text-xl font-semibold mb-3 text-teal-300">Játékosok</h2>
              
              {/* Empty state */}
              {players.length === 0 && (
                <div className="text-center py-8 text-gray-400">
                  <div className="text-4xl mb-2">👥</div>
                  <p className="text-sm">Várakozás játékosokra...</p>
                </div>
              )}

              {/* Players list */}
              {sortedPlayers.map((player, index) => (
                <div
                  key={player.id}
                  className="flex items-center mb-3 p-2 bg-gray-900 rounded-lg hover:bg-gray-700 transition-colors relative"
                >
                  {/* Online indicator */}
                  {player.isOnline && (
                    <div className="absolute top-1 right-1 w-2 h-2 bg-green-500 rounded-full animate-pulse"></div>
                  )}
                  
                  <div
                    className={`w-8 h-8 ${player.color} rounded-full mr-3 flex items-center justify-center text-white text-sm font-bold shadow-md`}
                  >
                    {player.emoji}
                  </div>
                  <div className="flex-1">
                    <div className="font-medium text-sm text-gray-300 flex items-center gap-2 flex-wrap">
                      {player.name}
                      
                      {/* Ready indicator */}
                      {player.isReady && (
                        <span className="px-2 py-0.5 bg-green-600 text-white text-xs rounded-full">
                          ✓ Kész
                        </span>
                      )}
                      
                      {/* Current turn indicator */}
                      {currentTurn === player.id && (
                        <span className="px-2 py-0.5 bg-yellow-500 text-gray-900 text-xs rounded-full font-bold animate-pulse">
                          ▶ Köre
                        </span>
                      )}
                      
                      {/* Rank medal */}
                      <span
                        className={`ml-auto px-2 py-1 rounded-full border text-xs font-bold shadow-md ${getMedalStyle(
                          index + 1
                        )}`}
                      >
                        {index + 1 === 1
                          ? "🥇 1st"
                          : index + 1 === 2
                          ? "🥈 2nd"
                          : index + 1 === 3
                          ? "🥉 3rd"
                          : `${index + 1}th`}
                      </span>
                    </div>
                    <div className="text-xs text-gray-500">
                      Pozíció: {playerPositions?.[player.name] ?? 1} • Pontszám: {player.score}
                    </div>
                  </div>
                </div>
              ))}
            </div>

            {/* Dice Container */}
            <div className="bg-gray-800 rounded-xl p-4 shadow-lg border border-teal-700 text-center">
              <h2 className="text-xl font-semibold mb-3 text-teal-300">Dobókocka</h2>
              {isMyTurn ? (
                <>
                  <p className="text-green-400 text-sm mb-4 font-bold animate-pulse">
                    🎯 A te köröd! Kattints a kockára dobáshoz!
                  </p>
                  <Dice onRoll={handleDiceRoll} />
                </>
              ) : (
                <>
                  <p className="text-gray-500 text-sm mb-4">
                    ⏳ Várd meg a köröd...
                  </p>
                  <div className="opacity-50 pointer-events-none">
                    <Dice onRoll={handleDiceRoll} />
                  </div>
                </>
              )}
              
              {/* Connection warning */}
              {!isConnected && (
                <div className="mt-3 text-xs text-red-400">
                  ⚠️ Nincs kapcsolat a szerverrel
                </div>
              )}
            </div>

            {/* Debug Info Panel (Development only) */}
            {import.meta.env.DEV && (
              <div className="bg-gray-900 rounded-xl p-4 shadow-lg border border-gray-700 text-left mt-4">
                <h3 className="text-sm font-semibold mb-2 text-gray-400">🔧 Debug Info</h3>
                <div className="text-xs text-gray-500 space-y-1">
                  <div>📡 Connected: {isConnected ? '✅' : '❌'}</div>
                  <div>🎮 Game Code: {gameState?.gameCode || 'N/A'}</div>
                  <div>👥 Players: {backendPlayers?.length || 0}</div>
                  <div>🎲 Board Fields: {boardData?.fields?.length || 0}</div>
                  <div>🏁 Current Turn: {currentTurnName || currentTurn || 'N/A'}</div>
                  <div>🆔 My ID: {playerIdentifier || 'N/A'}</div>
                  <div>✅ Is My Turn: {isMyTurn ? 'YES' : 'NO'}</div>
                  {/* <div>🔑 Token: {gameToken ? '✅' : '❌'}</div> */}
                </div>
              </div>
            )}
          </div>
        </div>
      </div>

      {/* Joker Approval Modal - csak Gamemaster számára */}
      <JokerApprovalModal
        isOpen={isJokerModalOpen}
        onClose={() => setIsJokerModalOpen(false)}
        jokerRequest={currentJokerRequest}
        onApprove={handleApproveJoker}
        onReject={handleRejectJoker}
        playerName={currentJokerRequest?.playerName}
        playerEmoji={currentJokerRequest?.playerEmoji}
      />

      {/* Card Display Modal - kártya megjelenítés */}
      <CardDisplayModal
        isOpen={isCardModalOpen}
        onClose={() => setIsCardModalOpen(false)}
        card={currentCard}
        onSubmitAnswer={handleSubmitAnswer}
        isMyTurn={isMyCardTurn}
      />

      {/* Consequence Modal - következmények megjelenítése */}
      <ConsequenceModal
        isOpen={isConsequenceModalOpen}
        onClose={handleConsequenceClose}
        isCorrect={currentConsequence?.isCorrect}
        consequenceType={currentConsequence?.consequenceType}
        consequenceValue={currentConsequence?.consequenceValue}
        playerAnswer={currentConsequence?.playerAnswer}
        correctAnswer={currentConsequence?.correctAnswer}
        explanation={currentConsequence?.explanation}
      />

      {/* End Game Modal */}
      {isEndGameModalOpen && endGameData && (
        <div className="fixed inset-0 z-50 flex items-center justify-center p-4 bg-black/90">
          <div className="relative bg-gradient-to-br from-yellow-900 via-yellow-800 to-yellow-900 rounded-2xl shadow-2xl border-4 border-yellow-500 max-w-2xl w-full p-8 text-center">
            <div className="absolute inset-0 bg-gradient-to-r from-transparent via-white/10 to-transparent animate-pulse" />
            
            <div className="relative">
              <div className="text-8xl mb-4 animate-bounce">🏆</div>
              <h1 className="text-5xl font-bold text-white mb-4">
                Játék vége!
              </h1>
              <div className="bg-black/30 rounded-xl p-6 mb-6">
                <p className="text-6xl font-bold text-yellow-300 mb-2">
                  {endGameData.winnerName}
                </p>
                <p className="text-2xl text-yellow-100">
                  🎉 Nyert! 🎉
                </p>
              </div>
              
              {endGameData.finalPositions && endGameData.finalPositions.length > 0 && (
                <div className="bg-black/30 rounded-xl p-4 mb-6">
                  <h3 className="text-xl font-semibold text-yellow-300 mb-3">Végső állás:</h3>
                  <div className="space-y-2">
                    {endGameData.finalPositions
                      .sort((a, b) => b.boardPosition - a.boardPosition)
                      .map((player, index) => (
                        <div key={player.playerId} className="flex items-center justify-between bg-yellow-900/30 rounded-lg p-3">
                          <div className="flex items-center gap-3">
                            <span className="text-2xl">
                              {index === 0 ? '🥇' : index === 1 ? '🥈' : index === 2 ? '🥉' : '🎮'}
                            </span>
                            <span className="text-white font-semibold">{player.playerName}</span>
                          </div>
                          <span className="text-yellow-300 font-bold">Pozíció: {player.boardPosition}</span>
                        </div>
                      ))}
                  </div>
                </div>
              )}

              <button
                onClick={() => window.location.href = '/'}
                className="bg-gradient-to-r from-yellow-600 to-orange-600 hover:from-yellow-500 hover:to-orange-500 text-white font-bold py-4 px-8 rounded-xl shadow-lg transform transition-all duration-200 hover:scale-105 text-xl"
              >
                Vissza a főoldalra
              </button>
            </div>
          </div>
        </div>
      )}

      {/* Step Prediction Modal - pozíció tippelés */}
      <StepPredictionModal
        isOpen={isPredictionModalOpen}
        onClose={() => setIsPredictionModalOpen(false)}
        currentPosition={currentPredictionData?.currentPosition || 0}
        diceRoll={currentPredictionData?.diceRoll || 0}
        fieldStepValue={currentPredictionData?.fieldStepValue || 0}
        patternModifier={currentPredictionData?.patternModifier || 0}
        cardText={currentPredictionData?.cardText || "Tippeld meg, melyik pozícióra fogsz lépni!"}
        hints={currentPredictionData?.hints || []}
        timeLimit={currentPredictionData?.timeLimit || 30}
        isJoker={currentPredictionData?.isJoker || false}
        onSubmitPrediction={handleSubmitPrediction}
      />
    </div>
  )
}

export default GameScreen
