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, 
    boardData: websocketBoardData, 
    currentTurn,
    error,
    rollDice,
    approveJoker,
    rejectJoker,
    submitAnswer,
    submitPositionGuess,
    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)

  // 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)

  // 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
  useEffect(() => {
    if (!backendPlayers?.length) return

    const mappedPlayers = backendPlayers.map((player, index) => ({
      id: player.playerId || player.id || index,
      name: player.playerName || player.name || `Player ${index + 1}`,
      position: player.boardPosition || 0,
      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])

  // Listen to player movement - optimized to update only moved player
  useEffect(() => {
    if (!addEventListener) return

    const handlePlayerMoved = (moveData) => {
      setPlayers(prev => 
        prev.map(p => 
          p.id === moveData.playerId 
            ? { ...p, position: moveData.newPosition }
            : p
        )
      )
    }

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

  // Listen to Joker card events (csak Gamemaster számára)
  useEffect(() => {
    if (!addEventListener) return

    const handleJokerDrawn = (jokerData) => {
      console.log('🃏 Joker kártya húzva:', jokerData)
      // Joker approval modal megjelenítése
      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)
    }

    // 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])

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

    const handleCardDrawn = (cardData) => {
      console.log('🎴 Kártya húzva:', cardData)
      setCurrentCard({
        id: cardData.cardId || cardData.id,
        type: cardData.cardType || cardData.type,
        question: cardData.question || cardData.text,
        answerOptions: cardData.answerOptions || cardData.options || [],
        correctAnswer: cardData.correctAnswer,
        points: cardData.points || 0,
        timeLimit: cardData.timeLimit || 60
      })
      setIsCardModalOpen(true)
    }

    // Listen for both generic and self-specific events
    addEventListener('game:card-drawn', handleCardDrawn)
    addEventListener('game:card-drawn-self', handleCardDrawn)
    
    return () => {
      removeEventListener('game:card-drawn')
      removeEventListener('game:card-drawn-self')
    }
  }, [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)
      
      setCurrentConsequence({
        isCorrect: true, // Luck cards don't have right/wrong answers
        consequenceType: luckData.consequenceType,
        consequenceValue: luckData.value || luckData.consequenceValue || 0,
        explanation: luckData.message || 'Szerencse kártya!',
        playerAnswer: null,
        correctAnswer: null
      })
      setIsConsequenceModalOpen(true)
    }

    addEventListener('game:answer-validated', handleAnswerValidated)
    addEventListener('game:luck-consequence', handleLuckConsequence)
    
    return () => {
      removeEventListener('game:answer-validated')
      removeEventListener('game:luck-consequence')
    }
  }, [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)
    }

    addEventListener('game:position-guess-request', handlePositionGuessRequest)
    return () => removeEventListener('game:position-guess-request')
  }, [addEventListener, removeEventListener])

  // Joker jóváhagyás
  const handleApproveJoker = useCallback(async (jokerRequest) => {
    console.log('✅ Joker feladat jóváhagyva:', jokerRequest)
    
    // WebSocket üzenet a backend felé
    approveJoker(jokerRequest.playerId, jokerRequest.cardId, 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é
    rejectJoker(jokerRequest.playerId, jokerRequest.cardId, jokerRequest.requestId)
    
    // 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)
    
    // WebSocket emit a backend felé
    if (currentCard?.id) {
      submitAnswer(currentCard.id, answer)
    }
    
    // A consequence modal automatikusan megnyílik a 'game:answer-validated' event hatására
  }, [currentCard?.id, submitAnswer])

  // 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é
    submitPositionGuess(predictedPosition)
    
    // Modal bezárása
    setIsPredictionModalOpen(false)
  }, [submitPositionGuess])

  // Sorted players - memoized
  const sortedPlayers = useMemo(
    () => [...players].sort((a, b) => b.position - a.position),
    [players]
  )

  // 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">
        {/* Connection Status Indicator */}
        <div className="fixed top-4 right-4 z-50">
          <div className={`px-4 py-2 rounded-lg shadow-lg flex items-center gap-2 ${
            isConnected 
              ? 'bg-green-600 text-white' 
              : 'bg-red-600 text-white'
          }`}>
            <div className={`w-3 h-3 rounded-full ${
              isConnected ? 'bg-green-300 animate-pulse' : 'bg-red-300'
            }`}></div>
          <span className="text-sm font-medium">
            {isConnected ? '🟢 Csatlakozva' : '🔴 Kapcsolódás...'}
          </span>
        </div>
        {error && !error.includes('Game not found') && !error.includes('token invalid') && (
          <div className="mt-2 px-4 py-2 rounded-lg shadow-lg bg-red-600 text-white text-xs">
            ⚠️ {error}
          </div>
        )}
      </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>
              {currentTurn && (
                <div className="text-gray-400 text-xs mt-1">
                  🎯 Köron: <span className="text-white">{players.find(p => p.id === currentTurn)?.name || 'Betöltés...'}</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) => (
                <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 animate-bounce`}
                  style={{
                    ...getPlayerPosition(player.position),
                    transform: "translate(17px, 17px)",
                  }}
                >
                  {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ó: {player.position} • 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>
              <p className="text-gray-300 text-sm mb-4">
                Kattints a kockára dobáshoz!
              </p>

              <Dice onRoll={handleDiceRoll} />
              
              {/* 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: {currentTurn || 'N/A'}</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}
      />

      {/* Consequence Modal - következmények megjelenítése */}
      <ConsequenceModal
        isOpen={isConsequenceModalOpen}
        onClose={() => setIsConsequenceModalOpen(false)}
        consequence={currentConsequence}
      />

      {/* Step Prediction Modal - pozíció tippelés */}
      <StepPredictionModal
        isOpen={isPredictionModalOpen}
        onClose={() => setIsPredictionModalOpen(false)}
        predictionData={currentPredictionData}
        onSubmitPrediction={handleSubmitPrediction}
      />
    </div>
  )
}

export default GameScreen
