import { useState, useEffect, useRef, useCallback } from 'react'

const BOARD_SIZE = 20
const INITIAL_SNAKE = [{ x: 10, y: 10 }]
const INITIAL_FOOD = { x: 15, y: 15 }
const INITIAL_DIRECTION = { x: 0, y: -1 }
const GAME_SPEED = 150

const DIRECTIONS = {
  UP: { x: 0, y: -1 },
  DOWN: { x: 0, y: 1 },
  LEFT: { x: -1, y: 0 },
  RIGHT: { x: 1, y: 0 }
}

export default function SnakeGame() {
  const canvasRef = useRef(null)
  const gameLoopRef = useRef(null)
  const [snake, setSnake] = useState(INITIAL_SNAKE)
  const [food, setFood] = useState(INITIAL_FOOD)
  const [direction, setDirection] = useState(INITIAL_DIRECTION)
  const [gameOver, setGameOver] = useState(false)
  const [score, setScore] = useState(0)
  const [isPlaying, setIsPlaying] = useState(false)
  const [isPaused, setIsPaused] = useState(false)

  // Generate random food position
  const generateFood = useCallback((currentSnake) => {
    let newFood
    do {
      newFood = {
        x: Math.floor(Math.random() * BOARD_SIZE),
        y: Math.floor(Math.random() * BOARD_SIZE)
      }
    } while (currentSnake.some(segment => segment.x === newFood.x && segment.y === newFood.y))
    return newFood
  }, [])

  // Check collision with walls or self
  const checkCollision = useCallback((head, body) => {
    // Wall collision
    if (head.x < 0 || head.x >= BOARD_SIZE || head.y < 0 || head.y >= BOARD_SIZE) {
      return true
    }
    // Self collision
    return body.some(segment => segment.x === head.x && segment.y === head.y)
  }, [])

  // Move snake
  const moveSnake = useCallback(() => {
    if (gameOver || isPaused || !isPlaying) return

    setSnake(currentSnake => {
      const newSnake = [...currentSnake]
      const head = { ...newSnake[0] }
      
      head.x += direction.x
      head.y += direction.y

      // Check collision
      if (checkCollision(head, newSnake)) {
        setGameOver(true)
        setIsPlaying(false)
        return currentSnake
      }

      newSnake.unshift(head)

      // Check if food is eaten
      if (head.x === food.x && head.y === food.y) {
        setScore(prev => prev + 10)
        setFood(generateFood(newSnake))
      } else {
        newSnake.pop()
      }

      return newSnake
    })
  }, [direction, food, gameOver, isPaused, isPlaying, checkCollision, generateFood])

  // Game loop
  useEffect(() => {
    if (isPlaying && !gameOver && !isPaused) {
      gameLoopRef.current = setInterval(moveSnake, GAME_SPEED)
    } else {
      clearInterval(gameLoopRef.current)
    }

    return () => clearInterval(gameLoopRef.current)
  }, [isPlaying, gameOver, isPaused, moveSnake])

  // Draw game
  const draw = useCallback(() => {
    const canvas = canvasRef.current
    if (!canvas) return

    const ctx = canvas.getContext('2d')
    const cellSize = canvas.width / BOARD_SIZE

    // Clear canvas
    ctx.fillStyle = '#000'
    ctx.fillRect(0, 0, canvas.width, canvas.height)

    // Draw snake
    ctx.fillStyle = '#4ade80'
    snake.forEach((segment, index) => {
      if (index === 0) {
        // Head
        ctx.fillStyle = '#22c55e'
      } else {
        ctx.fillStyle = '#4ade80'
      }
      ctx.fillRect(
        segment.x * cellSize,
        segment.y * cellSize,
        cellSize - 2,
        cellSize - 2
      )
    })

    // Draw food
    ctx.fillStyle = '#ef4444'
    ctx.fillRect(
      food.x * cellSize,
      food.y * cellSize,
      cellSize - 2,
      cellSize - 2
    )

    // Draw grid
    ctx.strokeStyle = '#333'
    ctx.lineWidth = 1
    for (let i = 0; i <= BOARD_SIZE; i++) {
      ctx.beginPath()
      ctx.moveTo(i * cellSize, 0)
      ctx.lineTo(i * cellSize, canvas.height)
      ctx.stroke()

      ctx.beginPath()
      ctx.moveTo(0, i * cellSize)
      ctx.lineTo(canvas.width, i * cellSize)
      ctx.stroke()
    }
  }, [snake, food])

  // Redraw when snake or food changes
  useEffect(() => {
    draw()
  }, [draw])

  // Handle keyboard input
  const handleKeyPress = useCallback((e) => {
    if (!isPlaying) return

    const { key } = e
    const currentDirection = direction

    switch (key) {
      case 'ArrowUp':
      case 'w':
      case 'W':
        if (currentDirection.y !== 1) {
          setDirection(DIRECTIONS.UP)
        }
        break
      case 'ArrowDown':
      case 's':
      case 'S':
        if (currentDirection.y !== -1) {
          setDirection(DIRECTIONS.DOWN)
        }
        break
      case 'ArrowLeft':
      case 'a':
      case 'A':
        if (currentDirection.x !== 1) {
          setDirection(DIRECTIONS.LEFT)
        }
        break
      case 'ArrowRight':
      case 'd':
      case 'D':
        if (currentDirection.x !== -1) {
          setDirection(DIRECTIONS.RIGHT)
        }
        break
      case ' ':
        e.preventDefault()
        setIsPaused(prev => !prev)
        break
    }
  }, [isPlaying, direction])

  useEffect(() => {
    window.addEventListener('keydown', handleKeyPress)
    return () => window.removeEventListener('keydown', handleKeyPress)
  }, [handleKeyPress])

  // Touch controls
  const handleDirection = useCallback((newDirection) => {
    if (!isPlaying || isPaused) return

    const currentDirection = direction
    // Prevent reverse direction
    if (
      (newDirection === DIRECTIONS.UP && currentDirection.y === 1) ||
      (newDirection === DIRECTIONS.DOWN && currentDirection.y === -1) ||
      (newDirection === DIRECTIONS.LEFT && currentDirection.x === 1) ||
      (newDirection === DIRECTIONS.RIGHT && currentDirection.x === -1)
    ) {
      return
    }

    setDirection(newDirection)
  }, [isPlaying, isPaused, direction])

  // Start new game
  const startNewGame = () => {
    setSnake(INITIAL_SNAKE)
    setFood(generateFood(INITIAL_SNAKE))
    setDirection(INITIAL_DIRECTION)
    setGameOver(false)
    setScore(0)
    setIsPlaying(true)
    setIsPaused(false)
  }

  return (
    <div className="flex flex-col items-center space-y-6">
      {/* Score */}
      <div className="text-center">
        <div className="score-display">
          Score: {score}
        </div>
        <div className="text-gray-400">
          Length: {snake.length}
        </div>
      </div>

      {/* Game Canvas */}
      <div className="relative">
        <canvas
          ref={canvasRef}
          width={400}
          height={400}
          className="block bg-gray-900"
        />
        
        {/* Game Over Overlay */}
        {gameOver && (
          <div className="absolute inset-0 bg-black bg-opacity-80 flex items-center justify-center rounded-lg">
            <div className="text-center text-white">
              <h2 className="text-3xl font-bold mb-4">Game Over!</h2>
              <p className="text-xl mb-4">Final Score: {score}</p>
              <button
                onClick={startNewGame}
                className="game-button"
              >
                Play Again
              </button>
            </div>
          </div>
        )}

        {/* Pause Overlay */}
        {isPaused && !gameOver && (
          <div className="absolute inset-0 bg-black bg-opacity-60 flex items-center justify-center rounded-lg">
            <div className="text-center text-white">
              <h2 className="text-3xl font-bold mb-4">Paused</h2>
              <p className="text-lg">Press SPACE or tap Resume to continue</p>
            </div>
          </div>
        )}
      </div>

      {/* Controls */}
      <div className="flex flex-col items-center space-y-4">
        {!isPlaying || gameOver ? (
          <button
            onClick={startNewGame}
            className="game-button text-lg px-8 py-4"
          >
            {gameOver ? 'Play Again' : 'Start Game'}
          </button>
        ) : (
          <div className="flex space-x-4">
            <button
              onClick={() => setIsPaused(!isPaused)}
              className="game-button"
            >
              {isPaused ? 'Resume' : 'Pause'}
            </button>
            <button
              onClick={startNewGame}
              className="game-button bg-red-600 hover:bg-red-700"
            >
              Restart
            </button>
          </div>
        )}
      </div>

      {/* Mobile Touch Controls */}
      <div className="md:hidden">
        <div className="text-center text-white mb-4">Touch Controls</div>
        <div className="grid grid-cols-3 gap-2 w-48">
          <div></div>
          <button
            onClick={() => handleDirection(DIRECTIONS.UP)}
            className="control-button text-2xl h-16"
            disabled={!isPlaying || isPaused}
          >
            ↑
          </button>
          <div></div>
          <button
            onClick={() => handleDirection(DIRECTIONS.LEFT)}
            className="control-button text-2xl h-16"
            disabled={!isPlaying || isPaused}
          >
            ←
          </button>
          <div></div>
          <button
            onClick={() => handleDirection(DIRECTIONS.RIGHT)}
            className="control-button text-2xl h-16"
            disabled={!isPlaying || isPaused}
          >
            →
          </button>
          <div></div>
          <button
            onClick={() => handleDirection(DIRECTIONS.DOWN)}
            className="control-button text-2xl h-16"
            disabled={!isPlaying || isPaused}
          >
            ↓
          </button>
          <div></div>
        </div>
      </div>

      {/* Instructions */}
      <div className="text-center text-gray-400 text-sm max-w-md">
        <p className="mb-2">
          <strong>Keyboard:</strong> Arrow keys or WASD to move, SPACE to pause
        </p>
        <p>
          <strong>Mobile:</strong> Use touch controls below
        </p>
      </div>
    </div>
  )
}