import React, { useCallback, useState } from 'react'
import { Square } from 'chess.js'
import { ChessPiece } from './ChessPiece'
import { GameState, DraggedPiece } from '../types/chess'
import { isSquareLight } from '../utils/chessUtils'
import { AudioEngine } from '../engines/AudioEngine'
import '../styles/ChessBoard.css'
import '../styles/ChessSquare.css'

export const ChessBoard: React.FC<{
  gameState: GameState
  draggedPiece: DraggedPiece | null
  audioEngine: AudioEngine | null
  onSquareClick: (square: Square) => void
  onPieceDragStart: (square: Square) => void
  onPieceDrop: (targetSquare: Square | null) => void
}> = ({
  gameState,
  draggedPiece,
  audioEngine,
  onSquareClick,
  onPieceDragStart,
  onPieceDrop
}) => {
  const [mousePosition, setMousePosition] = useState({ x: 0, y: 0 })
  const [isDragging, setIsDragging] = useState(false)

  const handleMouseMove = useCallback((event: React.MouseEvent) => {
    setMousePosition({ x: event.clientX, y: event.clientY })
  }, [])

  const handleSquareClick = useCallback((square: Square) => {
    if (!isDragging) {
      onSquareClick(square)
    }
  }, [onSquareClick, isDragging])

  const handleMouseDown = useCallback((square: Square) => {
    const piece = gameState.board.get(square)
    if (piece && piece.color === gameState.playerColor) {
      setIsDragging(true)
      onPieceDragStart(square)
    }
  }, [gameState, onPieceDragStart])

  const handleMouseUp = useCallback((square: Square) => {
    if (isDragging) {
      onPieceDrop(square)
      setIsDragging(false)
    }
  }, [isDragging, onPieceDrop])

  const renderSquares = () => {
    const renderedSquares = []

    for (let rank = 8; rank >= 1; rank--) {
      for (let file = 0; file < 8; file++) {
        const square = (String.fromCharCode(97 + file) + rank) as Square
        
        let displayFile = file
        let displayRank = rank
        
        if (gameState.playerColor === 'b') {
          displayFile = 7 - file
          displayRank = 9 - rank
        }

        const piece = gameState.board.get(square) || null
        const isSelected = gameState.selectedSquare === square
        const isLegalMove = gameState.legalMoves.some(move => move.to === square)
        const isDraggedSquare = draggedPiece?.square === square
        const isLight = isSquareLight(square)

        renderedSquares.push(
          <div
            key={square}
            className={`chess-square ${isLight ? 'light' : 'dark'} ${isSelected ? 'selected' : ''} ${isLegalMove ? 'legal-move' : ''}`}
            style={{
              position: 'absolute',
              left: displayFile * 75,
              top: (8 - displayRank) * 75,
              width: 75,
              height: 75
            }}
            onClick={() => handleSquareClick(square)}
            onMouseDown={() => handleMouseDown(square)}
            onMouseUp={() => handleMouseUp(square)}
          >
            {piece && !isDraggedSquare && (
              <div className="piece-container">
                <ChessPiece piece={piece} size={75} />
              </div>
            )}
            
            {isLegalMove && (
              <div className="legal-move-indicator" />
            )}
          </div>
        )
      }
    }

    return renderedSquares
  }

  const renderDraggedPiece = () => {
    if (!draggedPiece) return null

    return (
      <div
        className="dragged-piece"
        style={{
          left: mousePosition.x - 37.5,
          top: mousePosition.y - 37.5,
          position: 'fixed',
          pointerEvents: 'none',
          zIndex: 1000
        }}
      >
        <ChessPiece
          piece={draggedPiece.piece}
          size={75}
        />
      </div>
    )
  }

  return (
    <div
      className="chess-board"
      onMouseMove={handleMouseMove}
    >
      <div className="board-container">
        <div className="board-squares">
          {renderSquares()}
        </div>
        
        <div className="board-border" />
        <div className="file-labels">
          {Array.from({ length: 8 }, (_, i) => {
            const fileIndex = gameState.playerColor === 'w' ? i : 7 - i
            const fileLabel = String.fromCharCode(97 + fileIndex)
            const noteName = audioEngine?.getFileNoteName(fileIndex) || ''
            return (
              <div key={fileLabel} className="file-label">
                <span className="file-letter">{fileLabel}</span>
                <span className="file-note">({noteName})</span>
              </div>
            )
          })}
        </div>
        <div className="rank-labels">
          {Array.from({ length: 8 }, (_, i) => {
            const rankIndex = gameState.playerColor === 'w' ? 8 - i : i + 1
            const octave = gameState.playerColor === 'w' ? 8 - i : i + 1
            return (
              <div key={rankIndex} className="rank-label">
                <span className="rank-number">{rankIndex}</span>
                <span className="rank-octave">(♪{octave})</span>
              </div>
            )
          })}
        </div>
      </div>
      
      {renderDraggedPiece()}
    </div>
  )
}