import pygame
import chess
import chess.engine

# Initialize Pygame
pygame.init()

# Constants
WIDTH = 800
HEIGHT = 600
SQ_SIZE = 60
EVAL_BAR_WIDTH = 60
IMAGES = {}

def load_images():
    pieces = ['wp', 'wN', 'wB', 'wR', 'wQ', 'wK', 'bp', 'bN', 'bB', 'bR', 'bQ', 'bK']
    for piece in pieces:
        try:
            image_path = f"F:/Chess Piece Images/{piece}.png"
            IMAGES[piece] = pygame.transform.scale(pygame.image.load(image_path), (SQ_SIZE, SQ_SIZE))
            print(f"Loaded image: {piece}.png")
        except pygame.error:
            print(f"Error loading image: {piece}.png from {image_path}")

def draw_board(screen):
    colors = [pygame.Color("white"), pygame.Color("gray")]
    for r in range(8):
        for c in range(8):
            color = colors[(r + c) % 2]
            pygame.draw.rect(screen, color, pygame.Rect(EVAL_BAR_WIDTH + c * SQ_SIZE, r * SQ_SIZE, SQ_SIZE, SQ_SIZE))

def highlight_square(screen, square, color):
    row, col = divmod(square, 8)
    pygame.draw.rect(screen, color, pygame.Rect(EVAL_BAR_WIDTH + col * SQ_SIZE, row * SQ_SIZE, SQ_SIZE, SQ_SIZE), 5)

def draw_pieces(screen, board, moves=None, pv_moves=None):
    for r in range(8):
        for c in range(8):
            piece = board.piece_at(chess.square(c, r))
            piece_image = piece_to_image(piece)
            if piece_image and piece_image in IMAGES:
                screen.blit(IMAGES[piece_image], (EVAL_BAR_WIDTH + c * SQ_SIZE, r * SQ_SIZE))
            elif piece_image:
                print(f"Piece image not found for: {piece_image}")
            else:
                print(f"No piece at position: ({c}, {r})")

    if moves:
        for move in moves:
            highlight_square(screen, move.from_square, pygame.Color("blue"))
            highlight_square(screen, move.to_square, pygame.Color("red"))

    if pv_moves:
        for move in pv_moves:
            highlight_square(screen, move.from_square, pygame.Color("green"))
            highlight_square(screen, move.to_square, pygame.Color("yellow"))

def piece_to_image(piece):
    if piece:
        color = 'w' if piece.color == chess.WHITE else 'b'
        piece_type = piece.piece_type
        if piece_type == chess.PAWN:
            piece_str = f"{color}p"
        elif piece_type == chess.KNIGHT:
            piece_str = f"{color}N"
        elif piece_type == chess.BISHOP:
            piece_str = f"{color}B"
        elif piece_type == chess.ROOK:
            piece_str = f"{color}R"
        elif piece_type == chess.QUEEN:
            piece_str = f"{color}Q"
        elif piece_type == chess.KING:
            piece_str = f"{color}K"
        else:
            piece_str = None
        return piece_str
    return None

def draw_evaluation_bar(screen, evaluation):
    eval_ratio = (evaluation + 1) / 2
    pygame.draw.rect(screen, pygame.Color("black"), pygame.Rect(0, 0, EVAL_BAR_WIDTH, HEIGHT))

    pygame.draw.rect(screen, pygame.Color("green"),
                     pygame.Rect(0, HEIGHT // 2 * (1 - eval_ratio), EVAL_BAR_WIDTH, HEIGHT * eval_ratio))
    pygame.draw.rect(screen, pygame.Color("red"),
                     pygame.Rect(0, HEIGHT // 2, EVAL_BAR_WIDTH, HEIGHT * (1 - eval_ratio)))

    font = pygame.font.Font(None, 36)
    white_engine_text = font.render("White: LcZero", True, pygame.Color("black"))
    black_engine_text = font.render("Black: Stockfish", True, pygame.Color("black"))
    screen.blit(white_engine_text, (EVAL_BAR_WIDTH + 10, 10))
    screen.blit(black_engine_text, (EVAL_BAR_WIDTH + 10, HEIGHT - black_engine_text.get_height() - 10))

def main():
    screen = pygame.display.set_mode((WIDTH, HEIGHT))
    clock = pygame.time.Clock()
    load_images()

    board = chess.Board()
    engine_lc0 = None

    selected_square = None
    player_move = None
    last_move_time = 0
    move_delay = 900  # Delay in milliseconds

    try:
        engine_lc0 = chess.engine.SimpleEngine.popen_uci("G:/LcZero/lc0-v0.31.0-windows-cpu-dnnl/lc0")
        running = True
        while running:
            for event in pygame.event.get():
                if event.type == pygame.QUIT:
                    running = False

                elif event.type == pygame.MOUSEBUTTONDOWN:
                    x, y = event.pos
                    if x > EVAL_BAR_WIDTH:
                        col = (x - EVAL_BAR_WIDTH) // SQ_SIZE
                        row = y // SQ_SIZE
                        square = chess.square(col, row)
                        if selected_square is None:
                            selected_square = square
                        else:
                            player_move = chess.Move(selected_square, square)
                            if player_move in board.legal_moves:
                                board.push(player_move)
                                selected_square = None
                            else:
                                selected_square = square

            if not board.is_game_over():
                draw_board(screen)
                draw_pieces(screen, board)

                if player_move:
                    info = engine_lc0.analyse(board, chess.engine.Limit(time=2.0), multipv=1)
                    pv_line = info[0]['pv']

                    current_time = pygame.time.get_ticks()
                    if current_time - last_move_time >= move_delay:
                        for move in pv_line:
                            board.push(move)
                            draw_board(screen)
                            draw_pieces(screen, board, pv_moves=[move])
                            pygame.display.flip()
                            last_move_time = pygame.time.get_ticks()
                            pygame.time.delay(int(move_delay))  # Use pygame delay for non-blocking pause

                        for move in reversed(pv_line):
                            board.pop()

                        result_lc0 = engine_lc0.play(board, chess.engine.Limit(time=2.0))
                        lc0_move = result_lc0.move
                        board.push(lc0_move)
                        draw_board(screen)
                        draw_pieces(screen, board, moves=[lc0_move])
                        player_move = None
                        last_move_time = pygame.time.get_ticks()

                pygame.display.flip()
                clock.tick(30)

    except Exception as e:
        print(f"An error occurred: {e}")

    finally:
        if engine_lc0:
            engine_lc0.quit()
        pygame.quit()

if __name__ == "__main__":
    main(). This code only show one top line but i wanna see multiple top engine lines . i should able to play aginst it and it should show me the top 3  lines . high light its  current move that it mad eafter i play a move after showing its top 3 lines on board.