import pygame
import sys
import random
import math
import os

# Инициализация Pygame
pygame.init()

# Размеры экрана
WIDTH, HEIGHT = 800, 600
SCREEN = pygame.display.set_mode((WIDTH, HEIGHT))
pygame.display.set_caption("Игра Змейка")

# Цвета
BACKGROUND_COLOR = (20, 21, 31)
SNAKE_COLOR = (50, 205, 50)
FOOD_COLOR = (255, 69, 0)
PARTICLE_COLOR = (255, 69, 0)

# Цвета для свечения
SNAKE_GLOW_COLOR = (80, 220, 80, 76)  # RGBA для прозрачности
FOOD_GLOW_COLOR = (255, 100, 50, 76)

# Шрифты
FONT = pygame.font.SysFont('Arial', 20)
BIG_FONT = pygame.font.SysFont('Arial', 50)

# FPS
FPS = 60
CLOCK = pygame.time.Clock()

# Путь к файлу рекорда
HIGH_SCORE_FILE = "high_score.txt"

# Определение состояний игры
class GameState:
    MAIN_MENU = 'main_menu'
    PLAYING = 'playing'
    GAME_OVER = 'game_over'
    PAUSED = 'paused'

# Класс Затемнения экрана
class FadeScreen:
    def __init__(self, duration=30):
        self.surface = pygame.Surface((WIDTH, HEIGHT))
        self.surface.fill((0, 0, 0))
        self.alpha = 0
        self.duration = duration  # Количество кадров для завершения затемнения
        self.fade_in = True
        self.fade_out = False
        self.finished = False

    def start_fade_in(self):
        self.alpha = 255
        self.fade_in = True
        self.fade_out = False
        self.finished = False
        print("[ОТЛАДКА] FadeScreen: Начало затемнения (fade-in)")

    def start_fade_out(self):
        self.alpha = 0
        self.fade_in = False
        self.fade_out = True
        self.finished = False
        print("[ОТЛАДКА] FadeScreen: Начало затухания (fade-out)")

    def update(self):
        if self.fade_in:
            self.alpha -= 255 / self.duration
            if self.alpha <= 0:
                self.alpha = 0
                self.fade_in = False
                self.finished = True
                print("[ОТЛАДКА] FadeScreen: Затемнение (fade-in) завершено")
        elif self.fade_out:
            self.alpha += 255 / self.duration
            if self.alpha >= 255:
                self.alpha = 255
                self.fade_out = False
                self.finished = True
                print("[ОТЛАДКА] FadeScreen: Затухание (fade-out) завершено")
        self.surface.set_alpha(int(self.alpha))

    def draw(self, surface):
        if not self.finished:
            surface.blit(self.surface, (0, 0))

# Класс Меню
class Menu:
    def __init__(self, title, options, on_select):
        """
        title: Текст заголовка меню.
        options: Список текстов опций.
        on_select: Функция обратного вызова, принимающая индекс выбранной опции.
        """
        self.title = title
        self.options = options
        self.on_select = on_select
        self.selected_index = 0
        self.alpha = 0
        self.show_menu_surface = True
        self.fade_in = True
        self.fade_out = False
        self.menu_surface = pygame.Surface((WIDTH, HEIGHT), pygame.SRCALPHA)
        self.setup_buttons()
        print(f"[ОТЛАДКА] Меню '{self.title}' инициализировано")

    def setup_buttons(self):
        # Расположение кнопок по вертикали
        self.buttons = []
        button_width = 200
        button_height = 50
        spacing = 20
        total_height = len(self.options) * (button_height + spacing) - spacing
        start_y = HEIGHT // 2 - total_height // 2

        for idx, option in enumerate(self.options):
            rect = pygame.Rect(WIDTH//2 - button_width//2, start_y + idx * (button_height + spacing), button_width, button_height)
            self.buttons.append(rect)
        print(f"[ОТЛАДКА] Кнопки меню '{self.title}' установлены")

    def handle_event(self, event):
        if event.type == pygame.MOUSEBUTTONDOWN:
            for idx, button in enumerate(self.buttons):
                if button.collidepoint(event.pos):
                    self.selected_index = idx  # Обновляем выбранный индекс на основе клика
                    print(f"[ОТЛАДКА] В меню '{self.title}' выбрана опция '{self.options[idx]}'")
                    self.fade_out = True

        elif event.type == pygame.KEYDOWN:
            if event.key == pygame.K_UP:
                self.selected_index = (self.selected_index - 1) % len(self.options)
                print(f"[ОТЛАДКА] В меню '{self.title}' выбран пункт '{self.options[self.selected_index]}'")
            elif event.key == pygame.K_DOWN:
                self.selected_index = (self.selected_index + 1) % len(self.options)
                print(f"[ОТЛАДКА] В меню '{self.title}' выбран пункт '{self.options[self.selected_index]}'")
            elif event.key in [pygame.K_RETURN, pygame.K_SPACE]:
                print(f"[ОТЛАДКА] В меню '{self.title}' активирована опция '{self.options[self.selected_index]}' с клавиатуры")
                self.on_select(self.selected_index)
                self.fade_out = True

    def update(self):
        if self.fade_in and self.alpha < 255:
            self.alpha += 5
            if self.alpha >= 255:
                self.alpha = 255
                self.fade_in = False
                print(f"[ОТЛАДКА] Меню '{self.title}' появилось полностью")
        elif self.fade_out and self.alpha > 0:
            self.alpha -= 5
            if self.alpha <= 0:
                self.alpha = 0
                self.show_menu_surface = False
                print(f"[ОТЛАДКА] Меню '{self.title}' исчезло полностью")
                # Вызов callback-функции после завершения анимации
                if self.on_select:
                    self.on_select(self.selected_index)

        # Заполнение поверхности меню
        self.menu_surface.fill((0, 0, 0, self.alpha))

    def draw(self, surface):
        if self.show_menu_surface:
            surface.blit(self.menu_surface, (0, 0))
            # Рисуем заголовок
            title_text = BIG_FONT.render(self.title, True, (255, 255, 255))
            surface.blit(title_text, (WIDTH//2 - title_text.get_width()//2, HEIGHT//2 - 200))
            # Рисуем кнопки
            for idx, button in enumerate(self.buttons):
                color = (150, 150, 150) if idx != self.selected_index else (100, 100, 255)
                pygame.draw.rect(surface, color, button)
                # Рисуем текст кнопки
                option_text = FONT.render(self.options[idx], True, (255, 255, 255))
                surface.blit(option_text, (button.x + button.width//2 - option_text.get_width()//2,
                                           button.y + button.height//2 - option_text.get_height()//2))

# Класс Game Over Меню
class GameOverMenu(Menu):
    def __init__(self, score, high_score, on_restart, on_main_menu):
        self.score = score
        self.high_score = high_score
        self.on_restart = on_restart
        self.on_main_menu = on_main_menu
        options = ["Перезапустить", "Главное Меню"]
        super().__init__("Игра окончена", options, self.handle_selection)
        self.fade = FadeScreen()
        self.fade.start_fade_in()
        print("[ОТЛАДКА] Меню 'Игра окончена' инициализировано")

    def handle_selection(self, selected_index):
        if selected_index == 0:
            print("[ОТЛАДКА] Меню 'Игра окончена': Выбрана опция 'Перезапустить'")
            self.on_restart()
        elif selected_index == 1:
            print("[ОТЛАДКА] Меню 'Игра окончена': Выбрана опция 'Главное Меню'")
            self.on_main_menu()

    def handle_event(self, event):
        # Не обрабатываем события во время затемнения
        if not self.fade.finished:
            return
        self.menu.handle_event(event)

    def update(self):
        self.fade.update()
        if self.fade.finished:
            self.menu.update()

    def draw(self, surface):
        self.menu.draw(surface)
        self.fade.draw(surface)

# Класс Паузы
class PauseMenu(Menu):
    def __init__(self, on_resume, on_main_menu):
        self.on_resume = on_resume
        self.on_main_menu = on_main_menu
        options = ["Возобновить", "Главное Меню"]
        super().__init__("Пауза", options, self.handle_selection)
        self.fade = FadeScreen()
        self.fade.start_fade_out()  # Начинаем как невидимое
        self.is_active = False
        print("[ОТЛАДКА] Меню паузы инициализировано")

    def handle_selection(self, selected_index):
        if selected_index == 0:
            print("[ОТЛАДКА] Меню паузы: Выбрана опция 'Возобновить'")
            self.fade.start_fade_out()
            self.on_resume()
        elif selected_index == 1:
            print("[ОТЛАДКА] Меню паузы: Выбрана опция 'Главное Меню'")
            self.fade.start_fade_out()
            self.on_main_menu()

    def handle_event(self, event):
        # Не обрабатываем события во время затемнения
        if not self.fade.finished:
            return
        self.menu.handle_event(event)

    def show(self):
        self.is_active = True
        self.fade.start_fade_in()
        print("[ОТЛАДКА] Меню паузы показано")

    def hide(self):
        self.is_active = False
        self.fade.start_fade_out()
        print("[ОТЛАДКА] Меню паузы скрыто")

    def update(self):
        if not self.is_active:
            return
        self.fade.update()
        if self.fade.finished:
            self.menu.update()

    def draw(self, surface):
        if not self.is_active:
            return
        self.menu.draw(surface)
        self.fade.draw(surface)

# Класс Змейки остается неизменным, используя список сегментов
class Snake:
    def __init__(self, x, y):
        self.angle = -90  # Направление вверх
        self.turn_direction = 0  # -1 для поворота влево, 1 для поворота вправо, 0 для прямого движения
        self.speed = 5  # Скорость змейки
        self.turn_speed = 3  # Градусов за кадр
        self.radius = 10
        self.length = 5  # Начальная длина змейки
        self.spacing = 20  # Расстояние между сегментами

        # Список сегментов. Первый элемент - голова
        self.segments = [(x, y)]
        print(f"[ОТЛАДКА] Змея инициализирована с головой в позиции ({x}, {y})")

    def turn(self, direction):
        # Избегаем обратного поворота
        if direction * self.turn_direction < 0:
            return
        self.turn_direction = direction
        print(f"[ОТЛАДКА] Направление поворота змейки установлено на {direction}")

    def grow(self):
        self.length += 1
        print(f"[ОТЛАДКА] Змея выросла до длины {self.length}")

    def update(self):
        # Обновляем угол направления
        self.angle += self.turn_direction * self.turn_speed
        self.angle %= 360  # Угол остаётся в диапазоне [0, 360)
        radians = math.radians(self.angle)
        dx = math.cos(radians) * self.speed
        dy = math.sin(radians) * self.speed

        # Новая позиция головы
        new_head_x = self.segments[0][0] + dx
        new_head_y = self.segments[0][1] + dy
        self.segments.insert(0, (new_head_x, new_head_y))
        print(f"[ОТЛАДКА] Головка змейки переместилась в позицию ({new_head_x:.2f}, {new_head_y:.2f})")

        # Удаляем последний сегмент, если длина превышена
        if len(self.segments) > self.length:
            removed_segment = self.segments.pop()
            print(f"[ОТЛАДКА] Удалён сегмент хвоста из позиции: {removed_segment}")

        # Проверка выхода за границы экрана
        if not (0 <= new_head_x <= WIDTH and 0 <= new_head_y <= HEIGHT):
            print("[ОТЛАДКА] Змея столкнулась со стеной")
            return True

        return False

    def draw(self, surface):
        # Рисуем сегменты змейки
        for idx, (x, y) in enumerate(self.segments):
            if idx == 0:
                # Головка змейки
                pygame.draw.circle(surface, SNAKE_COLOR, (int(x), int(y)), self.radius)
                pygame.draw.circle(surface, (64, 255, 64), (int(x), int(y)), self.radius, 2)
            else:
                # Тело змейки
                pygame.draw.circle(surface, SNAKE_COLOR, (int(x), int(y)), self.radius)
                pygame.draw.circle(surface, (64, 255, 64), (int(x), int(y)), self.radius, 2)

    def check_self_collision(self):
        head = self.segments[0]
        body = self.segments[1:]
        for idx, segment in enumerate(body, start=1):
            distance = math.hypot(head[0] - segment[0], head[1] - segment[1])
            if distance < self.radius * 2:
                print(f"[ОТЛАДКА] Змея столкнулась сама с собой на сегменте {idx} в позиции ({segment[0]:.2f}, {segment[1]:.2f})")
                return True
        return False

# Класс Еды остается неизменным
class Food:
    def __init__(self):
        self.radius = 6
        self.respawn()
        print(f"[ОТЛАДКА] Еда инициализирована в позиции ({self.x}, {self.y})")

    def respawn(self):
        self.x = random.randint(self.radius, WIDTH - self.radius)
        self.y = random.randint(self.radius, HEIGHT - self.radius)
        print(f"[ОТЛАДКА] Еда перемещена в позицию ({self.x}, {self.y})")

    def draw(self, surface):
        # Эффект свечения
        glow_surface = pygame.Surface((self.radius * 2 + 8, self.radius * 2 + 8), pygame.SRCALPHA)
        pygame.draw.circle(glow_surface, FOOD_GLOW_COLOR, (self.radius + 4, self.radius + 4), self.radius + 4)
        surface.blit(glow_surface, (self.x - self.radius - 4, self.y - self.radius - 4))
        
        # Рисуем еду
        pygame.draw.circle(surface, FOOD_COLOR, (int(self.x), int(self.y)), self.radius)
        pygame.draw.circle(surface, (255, 99, 71), (int(self.x), int(self.y)), self.radius, 2)

# Класс Частиц остается неизменным
class ParticleSystem:
    def __init__(self):
        self.particles = []
        print("[ОТЛАДКА] Система частиц инициализирована")

    def emit(self, x, y):
        for _ in range(20):
            angle = random.uniform(0, 2 * math.pi)
            speed = random.uniform(1, 4)
            self.particles.append({
                'x': x,
                'y': y,
                'dx': math.cos(angle) * speed,
                'dy': math.sin(angle) * speed,
                'life': 1.0,
                'color': PARTICLE_COLOR
            })
        print(f"[ОТЛАДКА] Выдано 20 частиц в позиции ({x}, {y})")

    def update(self):
        original_count = len(self.particles)
        self.particles = [p for p in self.particles if p['life'] > 0]
        removed_particles = original_count - len(self.particles)
        if removed_particles > 0:
            print(f"[ОТЛАДКА] Удалено {removed_particles} частиц")
        for p in self.particles:
            p['x'] += p['dx']
            p['y'] += p['dy']
            p['life'] -= 0.02

    def draw(self, surface):
        for p in self.particles:
            if p['life'] <= 0:
                continue
            alpha = max(int(255 * p['life']), 0)
            particle_surface = pygame.Surface((4, 4), pygame.SRCALPHA)
            particle_surface.fill((*p['color'], alpha))
            surface.blit(particle_surface, (int(p['x']), int(p['y'])))

# Класс GameOver Меню
class GameOverMenu(Menu):
    def __init__(self, score, high_score, on_restart, on_main_menu):
        self.score = score
        self.high_score = high_score
        self.on_restart = on_restart
        self.on_main_menu = on_main_menu
        options = ["Перезапустить", "Главное Меню"]
        super().__init__("Игра окончена", options, self.handle_selection)
        self.fade = FadeScreen()
        self.fade.start_fade_in()
        print("[ОТЛАДКА] Меню 'Игра окончена' инициализировано")

    def handle_selection(self, selected_index):
        if selected_index == 0:
            print("[ОТЛАДКА] Меню 'Игра окончена': Выбрана опция 'Перезапустить'")
            self.on_restart()
        elif selected_index == 1:
            print("[ОТЛАДКА] Меню 'Игра окончена': Выбрана опция 'Главное Меню'")
            self.on_main_menu()

    def handle_event(self, event):
        # Не обрабатываем события во время затемнения
        if not self.fade.finished:
            return
        self.menu.handle_event(event)

    def update(self):
        self.fade.update()
        if self.fade.finished:
            self.menu.update()

    def draw(self, surface):
        self.menu.draw(surface)
        self.fade.draw(surface)

# Класс Паузы
class PauseMenu(Menu):
    def __init__(self, on_resume, on_main_menu):
        self.on_resume = on_resume
        self.on_main_menu = on_main_menu
        options = ["Возобновить", "Главное Меню"]
        super().__init__("Пауза", options, self.handle_selection)
        self.fade = FadeScreen()
        self.fade.start_fade_out()  # Начинаем как невидимое
        self.is_active = False
        print("[ОТЛАДКА] Меню паузы инициализировано")

    def handle_selection(self, selected_index):
        if selected_index == 0:
            print("[ОТЛАДКА] Меню паузы: Выбрана опция 'Возобновить'")
            self.fade.start_fade_out()
            self.on_resume()
        elif selected_index == 1:
            print("[ОТЛАДКА] Меню паузы: Выбрана опция 'Главное Меню'")
            self.fade.start_fade_out()
            self.on_main_menu()

    def handle_event(self, event):
        # Не обрабатываем события во время затемнения
        if not self.fade.finished:
            return
        self.menu.handle_event(event)

    def show(self):
        self.is_active = True
        self.fade.start_fade_in()
        print("[ОТЛАДКА] Меню паузы показано")

    def hide(self):
        self.is_active = False
        self.fade.start_fade_out()
        print("[ОТЛАДКА] Меню паузы скрыто")

    def update(self):
        if not self.is_active:
            return
        self.fade.update()
        if self.fade.finished:
            self.menu.update()

    def draw(self, surface):
        if not self.is_active:
            return
        self.menu.draw(surface)
        self.fade.draw(surface)

# Класс Игры
class Game:
    def __init__(self, on_game_over, on_exit):
        self.snake = Snake(WIDTH / 2, HEIGHT / 2)
        self.food = Food()
        self.particles = ParticleSystem()
        self.score = 0
        self.high_score = self.load_high_score()
        self.on_game_over = on_game_over
        self.on_exit = on_exit
        self.is_paused = False
        self.active = True
        self.game_over = False
        self.start_delay_frames = FPS * 2  # 2 секунды задержки
        self.pause_menu = PauseMenu(self.resume, self.return_to_main_menu)
        print("[ОТЛАДКА] Игра инициализирована")

    def load_high_score(self):
        if not os.path.exists(HIGH_SCORE_FILE):
            # Создаём файл с начальным значением 0
            try:
                with open(HIGH_SCORE_FILE, 'w') as f:
                    f.write('0')
                print(f"[ОТЛАДКА] Файл рекордов создан: {HIGH_SCORE_FILE}")
            except Exception as e:
                print(f"[ОШИБКА] Не удалось создать файл рекордов: {e}")
            return 0
        try:
            with open(HIGH_SCORE_FILE, 'r') as f:
                high_score = int(f.read())
                print(f"[ОТЛАДКА] Рекорд загружен: {high_score}")
                return high_score
        except ValueError:
            print(f"[ОТЛАДКА] Файл рекордов повреждён. Сброс рекорда до 0.")
            return 0
        except Exception as e:
            print(f"[ОШИБКА] Ошибка загрузки рекорда: {e}")
            return 0

    def save_high_score(self):
        try:
            with open(HIGH_SCORE_FILE, 'w') as f:
                f.write(str(self.high_score))
            print(f"[ОТЛАДКА] Рекорд {self.high_score} сохранён в файл {HIGH_SCORE_FILE}")
        except Exception as e:
            print(f"[ОШИБКА] Ошибка сохранения рекорда: {e}")

    def handle_events(self, events):
        if self.is_paused:
            self.pause_menu.handle_event(events)
            return

        for event in events:
            if event.type == pygame.QUIT:
                self.save_high_score()
                pygame.quit()
                sys.exit()
            elif event.type == pygame.KEYDOWN:
                if event.key == pygame.K_ESCAPE:
                    self.toggle_pause()
                elif not self.is_paused and not self.game_over:
                    if event.key == pygame.K_LEFT:
                        self.snake.turn(-1)
                        print("[ОТЛАДКА] Нажата клавиша Влево")
                    elif event.key == pygame.K_RIGHT:
                        self.snake.turn(1)
                        print("[ОТЛАДКА] Нажата клавиша Вправо")
            elif event.type == pygame.KEYUP:
                if not self.is_paused and not self.game_over:
                    if event.key in [pygame.K_LEFT, pygame.K_RIGHT]:
                        self.snake.turn(0)
                        print("[ОТЛАДКА] Отпущена клавиша Влево или Вправо")
        if self.is_paused:
            self.pause_menu.handle_event(events)

    def toggle_pause(self):
        self.is_paused = not self.is_paused
        if self.is_paused:
            self.pause_menu.show()
            print("[ОТЛАДКА] Игра на паузе")
        else:
            self.pause_menu.hide()
            print("[ОТЛАДКА] Игра возобновлена")

    def resume(self):
        self.is_paused = False
        self.pause_menu.hide()
        print("[ОТЛАДКА] Выполнено возобновление игры")

    def return_to_main_menu(self):
        self.save_high_score()
        self.active = False
        self.game_over = False
        self.pause_menu.hide()
        print("[ОТЛАДКА] Возврат в Главное Меню")

    def update(self):
        if not self.is_paused and not self.game_over:
            collision_with_wall = self.snake.update()
            self.particles.update()
            self.check_collisions()
            if collision_with_wall:
                self.handle_game_over()

            if self.start_delay_frames <= 0:
                if self.snake.check_self_collision():
                    self.handle_game_over()
            else:
                self.start_delay_frames -=1
                if self.start_delay_frames == 0:
                    print("[ОТЛАДКА] Проверка столкновений активирована")

    def handle_game_over(self):
        self.save_high_score()
        self.game_over = True
        self.active = False
        self.on_game_over(self.score, self.high_score)
        print("[ОТЛАДКА] Проигрыш завершён")

    def check_collisions(self):
        head = self.snake.segments[0]
        distance = math.hypot(head[0] - self.food.x, head[1] - self.food.y)
        if distance < self.snake.radius + self.food.radius:
            print("[ОТЛАДКА] Змея съела еду")
            self.snake.grow()
            self.particles.emit(self.food.x, self.food.y)
            self.food.respawn()
            self.score += 10
            if self.score > self.high_score:
                self.high_score = self.score
                print(f"[ОТЛАДКА] Новый рекорд: {self.high_score}")

    def draw(self, surface):
        surface.fill(BACKGROUND_COLOR)
        self.food.draw(surface)
        self.snake.draw(surface)
        self.particles.draw(surface)
        # Рисуем счёт
        score_text = FONT.render(f"Счёт: {self.score}", True, (255, 255, 255))
        high_score_text = FONT.render(f"Рекорд: {self.high_score}", True, (255, 255, 255))
        surface.blit(score_text, (20, 20))
        surface.blit(high_score_text, (20, 50))

        if self.is_paused:
            self.pause_menu.draw(surface)
        if self.game_over_menu:
            self.game_over_menu.draw(surface)

# Класс Главного Меню
class MainMenu:
    def __init__(self, on_start_game, on_exit_game):
        self.menu = Menu(
            title="Главное Меню",
            options=["Начать игру", "Выйти"],
            on_select=self.handle_selection
        )
        self.on_start_game = on_start_game
        self.on_exit_game = on_exit_game
        self.active = True
        self.game_instance = None  # Изначально игра отсутствует
        print("[ОТЛАДКА] Главное Меню инициализировано")

    def handle_selection(self, selected_index):
        if selected_index == 0:
            print("[ОТЛАДКА] Главное Меню: Выбрана опция 'Начать игру'")
            self.on_start_game()
        elif selected_index == 1:
            print("[ОТЛАДКА] Главное Меню: Выбрана опция 'Выйти'")
            self.on_exit_game()

    def handle_events(self, events):
        for event in events:
            self.menu.handle_event(event)

    def update(self):
        self.menu.update()

    def draw(self, surface):
        self.menu.draw(surface)

    def show_menu(self):
        print("[ОТЛАДКА] Возврат в Главное Меню")
        if self.game_instance:
            self.game_instance.save_high_score()
            self.game_instance = None
        self.active = True

# Класс GameOver Меню
class GameOverMenu(Menu):
    def __init__(self, score, high_score, on_restart, on_main_menu):
        self.score = score
        self.high_score = high_score
        self.on_restart = on_restart
        self.on_main_menu = on_main_menu
        options = ["Перезапустить", "Главное Меню"]
        super().__init__("Игра окончена", options, self.handle_selection)
        self.fade = FadeScreen()
        self.fade.start_fade_in()
        print("[ОТЛАДКА] Меню 'Игра окончена' инициализировано")

    def handle_selection(self, selected_index):
        if selected_index == 0:
            print("[ОТЛАДКА] Меню 'Игра окончена': Выбрана опция 'Перезапустить'")
            self.on_restart()
        elif selected_index == 1:
            print("[ОТЛАДКА] Меню 'Игра окончена': Выбрана опция 'Главное Меню'")
            self.on_main_menu()

    def handle_event(self, event):
        # Не обрабатываем события во время затемнения
        if not self.fade.finished:
            return
        self.menu.handle_event(event)

    def update(self):
        self.fade.update()
        if self.fade.finished:
            self.menu.update()

    def draw(self, surface):
        self.menu.draw(surface)
        self.fade.draw(surface)

# Класс Паузы
class PauseMenu(Menu):
    def __init__(self, on_resume, on_main_menu):
        self.on_resume = on_resume
        self.on_main_menu = on_main_menu
        options = ["Возобновить", "Главное Меню"]
        super().__init__("Пауза", options, self.handle_selection)
        self.fade = FadeScreen()
        self.fade.start_fade_out()  # Начинаем как невидимое
        self.is_active = False
        print("[ОТЛАДКА] Меню паузы инициализировано")

    def handle_selection(self, selected_index):
        if selected_index == 0:
            print("[ОТЛАДКА] Меню паузы: Выбрана опция 'Возобновить'")
            self.fade.start_fade_out()
            self.on_resume()
        elif selected_index == 1:
            print("[ОТЛАДКА] Меню паузы: Выбрана опция 'Главное Меню'")
            self.fade.start_fade_out()
            self.on_main_menu()

    def handle_event(self, event):
        # Не обрабатываем события во время затемнения
        if not self.fade.finished:
            return
        self.menu.handle_event(event)

    def show(self):
        self.is_active = True
        self.fade.start_fade_in()
        print("[ОТЛАДКА] Меню паузы показано")

    def hide(self):
        self.is_active = False
        self.fade.start_fade_out()
        print("[ОТЛАДКА] Меню паузы скрыто")

    def update(self):
        if not self.is_active:
            return
        self.fade.update()
        if self.fade.finished:
            self.menu.update()

    def draw(self, surface):
        if not self.is_active:
            return
        self.menu.draw(surface)
        self.fade.draw(surface)

# Класс Управления игрой
class GameManager:
    def __init__(self):
        self.state = GameState.MAIN_MENU
        self.main_menu = MainMenu(self.start_game, self.exit_game)
        self.game = None
        self.game_over_menu = None
        print("[ОТЛАДКА] Менеджер игры инициализирован")

    def start_game(self):
        self.game = Game(self.game_over, self.show_main_menu)
        self.state = GameState.PLAYING
        print("[ОТЛАДКА] Игра началась")

    def exit_game(self):
        print("[ОТЛАДКА] Выход из игры")
        if self.game:
            self.game.save_high_score()
        pygame.quit()
        sys.exit()

    def game_over(self, score, high_score):
        self.state = GameState.GAME_OVER
        self.game_over_menu = GameOverMenu(score, high_score, self.start_game, self.show_main_menu)
        print("[ОТЛАДКА] Переход в меню 'Игра окончена'")

    def show_main_menu(self):
        if self.game:
            self.game = None
        self.game_over_menu = None
        self.main_menu = MainMenu(self.start_game, self.exit_game)
        self.state = GameState.MAIN_MENU
        print("[ОТЛАДКА] Возврат в Главное Меню")

    def handle_events(self, events):
        if self.state == GameState.MAIN_MENU:
            self.main_menu.handle_events(events)
        elif self.state == GameState.PLAYING:
            self.game.handle_events(events)
        elif self.state == GameState.GAME_OVER:
            for event in events:
                self.game_over_menu.handle_event(event)

    def update(self):
        if self.state == GameState.MAIN_MENU:
            self.main_menu.update()
        elif self.state == GameState.PLAYING:
            self.game.update()
        elif self.state == GameState.GAME_OVER:
            self.game_over_menu.update()
            # После завершения затемнения и скрытия меню очищаем ссылку на GameOverMenu
            if self.game_over_menu.fade.finished and not self.game_over_menu.show_menu_surface:
                self.game_over_menu = None

    def draw(self, surface):
        if self.state == GameState.MAIN_MENU:
            self.main_menu.draw(surface)
        elif self.state == GameState.PLAYING:
            self.game.draw(surface)
        elif self.state == GameState.GAME_OVER:
            if self.game_over_menu:
                self.game_over_menu.draw(surface)

    def run(self):
        while True:
            events = pygame.event.get()
            # Обработка событий выхода из игры
            for event in events:
                if event.type == pygame.QUIT:
                    self.exit_game()
            self.handle_events(events)
            self.update()
            self.draw(SCREEN)

            pygame.display.flip()
            CLOCK.tick(FPS)

# Класс Главного Меню является подклассом Menu и управляет переходами
class MainMenu:
    def __init__(self, on_start_game, on_exit_game):
        self.menu = Menu(
            title="Главное Меню",
            options=["Начать игру", "Выйти"],
            on_select=self.handle_selection
        )
        self.on_start_game = on_start_game
        self.on_exit_game = on_exit_game
        self.active = True
        self.game_instance = None  # Изначально игра отсутствует
        print("[ОТЛАДКА] Главное Меню инициализировано")

    def handle_selection(self, selected_index):
        if selected_index == 0:
            print("[ОТЛАДКА] Главное Меню: Выбрана опция 'Начать игру'")
            self.on_start_game()
        elif selected_index == 1:
            print("[ОТЛАДКА] Главное Меню: Выбрана опция 'Выйти'")
            self.on_exit_game()

    def handle_events(self, events):
        for event in events:
            self.menu.handle_event(event)

    def update(self):
        self.menu.update()

    def draw(self, surface):
        self.menu.draw(surface)

    def show_menu(self):
        print("[ОТЛАДКА] Возврат в Главное Меню")
        if self.game_instance:
            self.game_instance.save_high_score()
            self.game_instance = None
        self.active = True

# Класс GameOver Меню остаётся как наследник Menu
class GameOverMenu(Menu):
    def __init__(self, score, high_score, on_restart, on_main_menu):
        self.score = score
        self.high_score = high_score
        self.on_restart = on_restart
        self.on_main_menu = on_main_menu
        options = ["Перезапустить", "Главное Меню"]
        super().__init__("Игра окончена", options, self.handle_selection)
        self.fade = FadeScreen()
        self.fade.start_fade_in()
        print("[ОТЛАДКА] Меню 'Игра окончена' инициализировано")

    def handle_selection(self, selected_index):
        if selected_index == 0:
            print("[ОТЛАДКА] Меню 'Игра окончена': Выбрана опция 'Перезапустить'")
            self.on_restart()
        elif selected_index == 1:
            print("[ОТЛАДКА] Меню 'Игра окончена': Выбрана опция 'Главное Меню'")
            self.on_main_menu()

    def handle_event(self, event):
        # Не обрабатываем события во время затемнения
        if not self.fade.finished:
            return
        self.menu.handle_event(event)

    def update(self):
        self.fade.update()
        if self.fade.finished:
            self.menu.update()

    def draw(self, surface):
        self.menu.draw(surface)
        self.fade.draw(surface)

# Класс Паузы наследуется от Menu и использует FadeScreen
class PauseMenu(Menu):
    def __init__(self, on_resume, on_main_menu):
        self.on_resume = on_resume
        self.on_main_menu = on_main_menu
        options = ["Возобновить", "Главное Меню"]
        super().__init__("Пауза", options, self.handle_selection)
        self.fade = FadeScreen()
        self.fade.start_fade_out()  # Начинаем как невидимое
        self.is_active = False
        print("[ОТЛАДКА] Меню паузы инициализировано")

    def handle_selection(self, selected_index):
        if selected_index == 0:
            print("[ОТЛАДКА] Меню паузы: Выбрана опция 'Возобновить'")
            self.fade.start_fade_out()
            self.on_resume()
        elif selected_index == 1:
            print("[ОТЛАДКА] Меню паузы: Выбрана опция 'Главное Меню'")
            self.fade.start_fade_out()
            self.on_main_menu()

    def handle_event(self, event):
        # Не обрабатываем события во время затемнения
        if not self.fade.finished:
            return
        self.menu.handle_event(event)

    def show(self):
        self.is_active = True
        self.fade.start_fade_in()
        print("[ОТЛАДКА] Меню паузы показано")

    def hide(self):
        self.is_active = False
        self.fade.start_fade_out()
        print("[ОТЛАДКА] Меню паузы скрыто")

    def update(self):
        if not self.is_active:
            return
        self.fade.update()
        if self.fade.finished:
            self.menu.update()

    def draw(self, surface):
        if not self.is_active:
            return
        self.menu.draw(surface)
        self.fade.draw(surface)

# Класс Змейки остается неизменным, используя список сегментов
class Snake:
    def __init__(self, x, y):
        self.angle = -90  # Направление вверх
        self.turn_direction = 0  # -1 для поворота влево, 1 для поворота вправо, 0 для прямого движения
        self.speed = 5  # Скорость змейки
        self.turn_speed = 3  # Градусов за кадр
        self.radius = 10
        self.length = 5  # Начальная длина змейки
        self.spacing = 20  # Расстояние между сегментами

        # Список сегментов. Первый элемент - голова
        self.segments = [(x, y)]
        print(f"[ОТЛАДКА] Змея инициализирована с головой в позиции ({x}, {y})")

    def turn(self, direction):
        # Избегаем обратного поворота
        if direction * self.turn_direction < 0:
            return
        self.turn_direction = direction
        print(f"[ОТЛАДКА] Направление поворота змейки установлено на {direction}")

    def grow(self):
        self.length += 1
        print(f"[ОТЛАДКА] Змея выросла до длины {self.length}")

    def update(self):
        # Обновляем угол направления
        self.angle += self.turn_direction * self.turn_speed
        self.angle %= 360  # Угол остаётся в диапазоне [0, 360)
        radians = math.radians(self.angle)
        dx = math.cos(radians) * self.speed
        dy = math.sin(radians) * self.speed

        # Новая позиция головы
        new_head_x = self.segments[0][0] + dx
        new_head_y = self.segments[0][1] + dy
        self.segments.insert(0, (new_head_x, new_head_y))
        print(f"[ОТЛАДКА] Головка змейки переместилась в позицию ({new_head_x:.2f}, {new_head_y:.2f})")

        # Удаляем последний сегмент, если длина превышена
        if len(self.segments) > self.length:
            removed_segment = self.segments.pop()
            print(f"[ОТЛАДКА] Удалён сегмент хвоста из позиции: {removed_segment}")

        # Проверка выхода за границы экрана
        if not (0 <= new_head_x <= WIDTH and 0 <= new_head_y <= HEIGHT):
            print("[ОТЛАДКА] Змея столкнулась со стеной")
            return True

        return False

    def draw(self, surface):
        # Рисуем сегменты змейки
        for idx, (x, y) in enumerate(self.segments):
            if idx == 0:
                # Головка змейки
                pygame.draw.circle(surface, SNAKE_COLOR, (int(x), int(y)), self.radius)
                pygame.draw.circle(surface, (64, 255, 64), (int(x), int(y)), self.radius, 2)
            else:
                # Тело змейки
                pygame.draw.circle(surface, SNAKE_COLOR, (int(x), int(y)), self.radius)
                pygame.draw.circle(surface, (64, 255, 64), (int(x), int(y)), self.radius, 2)

    def check_self_collision(self):
        head = self.segments[0]
        body = self.segments[1:]
        for idx, segment in enumerate(body, start=1):
            distance = math.hypot(head[0] - segment[0], head[1] - segment[1])
            if distance < self.radius * 2:
                print(f"[ОТЛАДКА] Змея столкнулась сама с собой на сегменте {idx} в позиции ({segment[0]:.2f}, {segment[1]:.2f})")
                return True
        return False

# Класс Еды остается неизменным
class Food:
    def __init__(self):
        self.radius = 6
        self.respawn()
        print(f"[ОТЛАДКА] Еда инициализирована в позиции ({self.x}, {self.y})")

    def respawn(self):
        self.x = random.randint(self.radius, WIDTH - self.radius)
        self.y = random.randint(self.radius, HEIGHT - self.radius)
        print(f"[ОТЛАДКА] Еда перемещена в позицию ({self.x}, {self.y})")

    def draw(self, surface):
        # Эффект свечения
        glow_surface = pygame.Surface((self.radius * 2 + 8, self.radius * 2 + 8), pygame.SRCALPHA)
        pygame.draw.circle(glow_surface, FOOD_GLOW_COLOR, (self.radius + 4, self.radius + 4), self.radius + 4)
        surface.blit(glow_surface, (self.x - self.radius - 4, self.y - self.radius - 4))
        
        # Рисуем еду
        pygame.draw.circle(surface, FOOD_COLOR, (int(self.x), int(self.y)), self.radius)
        pygame.draw.circle(surface, (255, 99, 71), (int(self.x), int(self.y)), self.radius, 2)

# Класс Частиц остается неизменным
class ParticleSystem:
    def __init__(self):
        self.particles = []
        print("[ОТЛАДКА] Система частиц инициализирована")

    def emit(self, x, y):
        for _ in range(20):
            angle = random.uniform(0, 2 * math.pi)
            speed = random.uniform(1, 4)
            self.particles.append({
                'x': x,
                'y': y,
                'dx': math.cos(angle) * speed,
                'dy': math.sin(angle) * speed,
                'life': 1.0,
                'color': PARTICLE_COLOR
            })
        print(f"[ОТЛАДКА] Выдано 20 частиц в позиции ({x}, {y})")

    def update(self):
        original_count = len(self.particles)
        self.particles = [p for p in self.particles if p['life'] > 0]
        removed_particles = original_count - len(self.particles)
        if removed_particles > 0:
            print(f"[ОТЛАДКА] Удалено {removed_particles} частиц")
        for p in self.particles:
            p['x'] += p['dx']
            p['y'] += p['dy']
            p['life'] -= 0.02

    def draw(self, surface):
        for p in self.particles:
            if p['life'] <= 0:
                continue
            alpha = max(int(255 * p['life']), 0)
            particle_surface = pygame.Surface((4, 4), pygame.SRCALPHA)
            particle_surface.fill((*p['color'], alpha))
            surface.blit(particle_surface, (int(p['x']), int(p['y'])))

# Класс GameOver Меню
class GameOverMenu(Menu):
    def __init__(self, score, high_score, on_restart, on_main_menu):
        self.score = score
        self.high_score = high_score
        self.on_restart = on_restart
        self.on_main_menu = on_main_menu
        options = ["Перезапустить", "Главное Меню"]
        super().__init__("Игра окончена", options, self.handle_selection)
        self.fade = FadeScreen()
        self.fade.start_fade_in()
        print("[ОТЛАДКА] Меню 'Игра окончена' инициализировано")

    def handle_selection(self, selected_index):
        if selected_index == 0:
            print("[ОТЛАДКА] Меню 'Игра окончена': Выбрана опция 'Перезапустить'")
            self.on_restart()
        elif selected_index == 1:
            print("[ОТЛАДКА] Меню 'Игра окончена': Выбрана опция 'Главное Меню'")
            self.on_main_menu()

    def handle_event(self, event):
        # Не обрабатываем события во время затемнения
        if not self.fade.finished:
            return
        self.menu.handle_event(event)

    def update(self):
        self.fade.update()
        if self.fade.finished:
            self.menu.update()

    def draw(self, surface):
        self.menu.draw(surface)
        self.fade.draw(surface)

# Класс Паузы
class PauseMenu(Menu):
    def __init__(self, on_resume, on_main_menu):
        self.on_resume = on_resume
        self.on_main_menu = on_main_menu
        options = ["Возобновить", "Главное Меню"]
        super().__init__("Пауза", options, self.handle_selection)
        self.fade = FadeScreen()
        self.fade.start_fade_out()  # Начинаем как невидимое
        self.is_active = False
        print("[ОТЛАДКА] Меню паузы инициализировано")

    def handle_selection(self, selected_index):
        if selected_index == 0:
            print("[ОТЛАДКА] Меню паузы: Выбрана опция 'Возобновить'")
            self.fade.start_fade_out()
            self.on_resume()
        elif selected_index == 1:
            print("[ОТЛАДКА] Меню паузы: Выбрана опция 'Главное Меню'")
            self.fade.start_fade_out()
            self.on_main_menu()

    def handle_event(self, event):
        # Не обрабатываем события во время затемнения
        if not self.fade.finished:
            return
        self.menu.handle_event(event)

    def show(self):
        self.is_active = True
        self.fade.start_fade_in()
        print("[ОТЛАДКА] Меню паузы показано")

    def hide(self):
        self.is_active = False
        self.fade.start_fade_out()
        print("[ОТЛАДКА] Меню паузы скрыто")

    def update(self):
        if not self.is_active:
            return
        self.fade.update()
        if self.fade.finished:
            self.menu.update()

    def draw(self, surface):
        if not self.is_active:
            return
        self.menu.draw(surface)
        self.fade.draw(surface)

# Класс Игры
class Game:
    def __init__(self, on_game_over, on_exit):
        self.snake = Snake(WIDTH / 2, HEIGHT / 2)
        self.food = Food()
        self.particles = ParticleSystem()
        self.score = 0
        self.high_score = self.load_high_score()
        self.on_game_over = on_game_over
        self.on_exit = on_exit
        self.is_paused = False
        self.active = True
        self.game_over = False
        self.start_delay_frames = FPS * 2  # 2 секунды задержки
        self.pause_menu = PauseMenu(self.resume, self.return_to_main_menu)
        print("[ОТЛАДКА] Игра инициализирована")

    def load_high_score(self):
        if not os.path.exists(HIGH_SCORE_FILE):
            # Создаём файл с начальным значением 0
            try:
                with open(HIGH_SCORE_FILE, 'w') as f:
                    f.write('0')
                print(f"[ОТЛАДКА] Файл рекордов создан: {HIGH_SCORE_FILE}")
            except Exception as e:
                print(f"[ОШИБКА] Не удалось создать файл рекордов: {e}")
            return 0
        try:
            with open(HIGH_SCORE_FILE, 'r') as f:
                high_score = int(f.read())
                print(f"[ОТЛАДКА] Рекорд загружен: {high_score}")
                return high_score
        except ValueError:
            print(f"[ОТЛАДКА] Файл рекордов повреждён. Сброс рекорда до 0.")
            return 0
        except Exception as e:
            print(f"[ОШИБКА] Ошибка загрузки рекорда: {e}")
            return 0

    def save_high_score(self):
        try:
            with open(HIGH_SCORE_FILE, 'w') as f:
                f.write(str(self.high_score))
            print(f"[ОТЛАДКА] Рекорд {self.high_score} сохранён в файл {HIGH_SCORE_FILE}")
        except Exception as e:
            print(f"[ОШИБКА] Ошибка сохранения рекорда: {e}")

    def handle_events(self, events):
        if self.is_paused:
            self.pause_menu.handle_event(events)
            return

        for event in events:
            if event.type == pygame.QUIT:
                self.save_high_score()
                pygame.quit()
                sys.exit()
            elif event.type == pygame.KEYDOWN:
                if event.key == pygame.K_ESCAPE:
                    self.toggle_pause()
                elif not self.is_paused and not self.game_over:
                    if event.key == pygame.K_LEFT:
                        self.snake.turn(-1)
                        print("[ОТЛАДКА] Нажата клавиша Влево")
                    elif event.key == pygame.K_RIGHT:
                        self.snake.turn(1)
                        print("[ОТЛАДКА] Нажата клавиша Вправо")
            elif event.type == pygame.KEYUP:
                if not self.is_paused and not self.game_over:
                    if event.key in [pygame.K_LEFT, pygame.K_RIGHT]:
                        self.snake.turn(0)
                        print("[ОТЛАДКА] Отпущена клавиша Влево или Вправо")
        if self.is_paused:
            self.pause_menu.handle_event(events)

    def toggle_pause(self):
        self.is_paused = not self.is_paused
        if self.is_paused:
            self.pause_menu.show()
            print("[ОТЛАДКА] Игра на паузе")
        else:
            self.pause_menu.hide()
            print("[ОТЛАДКА] Игра возобновлена")

    def resume(self):
        self.is_paused = False
        self.pause_menu.hide()
        print("[ОТЛАДКА] Выполнено возобновление игры")

    def return_to_main_menu(self):
        self.save_high_score()
        self.active = False
        self.game_over = False
        self.pause_menu.hide()
        print("[ОТЛАДКА] Возврат в Главное Меню")

    def update(self):
        if not self.is_paused and not self.game_over:
            collision_with_wall = self.snake.update()
            self.particles.update()
            self.check_collisions()
            if collision_with_wall:
                self.handle_game_over()

            if self.start_delay_frames <= 0:
                if self.snake.check_self_collision():
                    self.handle_game_over()
            else:
                self.start_delay_frames -=1
                if self.start_delay_frames == 0:
                    print("[ОТЛАДКА] Проверка столкновений активирована")

    def handle_game_over(self):
        self.save_high_score()
        self.game_over = True
        self.active = False
        self.on_game_over(self.score, self.high_score)
        print("[ОТЛАДКА] Проигрыш завершён")

    def check_collisions(self):
        head = self.snake.segments[0]
        distance = math.hypot(head[0] - self.food.x, head[1] - self.food.y)
        if distance < self.snake.radius + self.food.radius:
            print("[ОТЛАДКА] Змея съела еду")
            self.snake.grow()
            self.particles.emit(self.food.x, self.food.y)
            self.food.respawn()
            self.score += 10
            if self.score > self.high_score:
                self.high_score = self.score
                print(f"[ОТЛАДКА] Новый рекорд: {self.high_score}")

    def draw(self, surface):
        surface.fill(BACKGROUND_COLOR)
        self.food.draw(surface)
        self.snake.draw(surface)
        self.particles.draw(surface)
        # Рисуем счёт
        score_text = FONT.render(f"Счёт: {self.score}", True, (255, 255, 255))
        high_score_text = FONT.render(f"Рекорд: {self.high_score}", True, (255, 255, 255))
        surface.blit(score_text, (20, 20))
        surface.blit(high_score_text, (20, 50))

        if self.is_paused:
            self.pause_menu.draw(surface)
        if self.game_over_menu:
            self.game_over_menu.draw(surface)

# Класс Главного Меню
class MainMenu:
    def __init__(self, on_start_game, on_exit_game):
        self.menu = Menu(
            title="Главное Меню",
            options=["Начать игру", "Выйти"],
            on_select=self.handle_selection
        )
        self.on_start_game = on_start_game
        self.on_exit_game = on_exit_game
        self.active = True
        self.game_instance = None  # Изначально игра отсутствует
        print("[ОТЛАДКА] Главное Меню инициализировано")

    def handle_selection(self, selected_index):
        if selected_index == 0:
            print("[ОТЛАДКА] Главное Меню: Выбрана опция 'Начать игру'")
            self.on_start_game()
        elif selected_index == 1:
            print("[ОТЛАДКА] Главное Меню: Выбрана опция 'Выйти'")
            self.on_exit_game()

    def handle_events(self, events):
        for event in events:
            self.menu.handle_event(event)

    def update(self):
        self.menu.update()

    def draw(self, surface):
        self.menu.draw(surface)

    def show_menu(self):
        print("[ОТЛАДКА] Возврат в Главное Меню")
        if self.game_instance:
            self.game_instance.save_high_score()
            self.game_instance = None
        self.active = True

# Класс GameOver Меню
class GameOverMenu(Menu):
    def __init__(self, score, high_score, on_restart, on_main_menu):
        self.score = score
        self.high_score = high_score
        self.on_restart = on_restart
        self.on_main_menu = on_main_menu
        options = ["Перезапустить", "Главное Меню"]
        super().__init__("Игра окончена", options, self.handle_selection)
        self.fade = FadeScreen()
        self.fade.start_fade_in()
        print("[ОТЛАДКА] Меню 'Игра окончена' инициализировано")

    def handle_selection(self, selected_index):
        if selected_index == 0:
            print("[ОТЛАДКА] Меню 'Игра окончена': Выбрана опция 'Перезапустить'")
            self.on_restart()
        elif selected_index == 1:
            print("[ОТЛАДКА] Меню 'Игра окончена': Выбрана опция 'Главное Меню'")
            self.on_main_menu()

    def handle_event(self, event):
        # Не обрабатываем события во время затемнения
        if not self.fade.finished:
            return
        self.menu.handle_event(event)

    def update(self):
        self.fade.update()
        if self.fade.finished:
            self.menu.update()

    def draw(self, surface):
        self.menu.draw(surface)
        self.fade.draw(surface)

# Класс Паузы
class PauseMenu(Menu):
    def __init__(self, on_resume, on_main_menu):
        self.on_resume = on_resume
        self.on_main_menu = on_main_menu
        options = ["Возобновить", "Главное Меню"]
        super().__init__("Пауза", options, self.handle_selection)
        self.fade = FadeScreen()
        self.fade.start_fade_out()  # Начинаем как невидимое
        self.is_active = False
        print("[ОТЛАДКА] Меню паузы инициализировано")

    def handle_selection(self, selected_index):
        if selected_index == 0:
            print("[ОТЛАДКА] Меню паузы: Выбрана опция 'Возобновить'")
            self.fade.start_fade_out()
            self.on_resume()
        elif selected_index == 1:
            print("[ОТЛАДКА] Меню паузы: Выбрана опция 'Главное Меню'")
            self.fade.start_fade_out()
            self.on_main_menu()

    def handle_event(self, event):
        # Не обрабатываем события во время затемнения
        if not self.fade.finished:
            return
        self.menu.handle_event(event)

    def show(self):
        self.is_active = True
        self.fade.start_fade_in()
        print("[ОТЛАДКА] Меню паузы показано")

    def hide(self):
        self.is_active = False
        self.fade.start_fade_out()
        print("[ОТЛАДКА] Меню паузы скрыто")

    def update(self):
        if not self.is_active:
            return
        self.fade.update()
        if self.fade.finished:
            self.menu.update()

    def draw(self, surface):
        if not self.is_active:
            return
        self.menu.draw(surface)
        self.fade.draw(surface)

# Класс Игры
class Game:
    def __init__(self, on_game_over, on_exit):
        self.snake = Snake(WIDTH / 2, HEIGHT / 2)
        self.food = Food()
        self.particles = ParticleSystem()
        self.score = 0
        self.high_score = self.load_high_score()
        self.on_game_over = on_game_over
        self.on_exit = on_exit
        self.is_paused = False
        self.active = True
        self.game_over = False
        self.start_delay_frames = FPS * 2  # 2 секунды задержки
        self.pause_menu = PauseMenu(self.resume, self.return_to_main_menu)
        print("[ОТЛАДКА] Игра инициализирована")

    def load_high_score(self):
        if not os.path.exists(HIGH_SCORE_FILE):
            # Создаём файл с начальным значением 0
            try:
                with open(HIGH_SCORE_FILE, 'w') as f:
                    f.write('0')
                print(f"[ОТЛАДКА] Файл рекордов создан: {HIGH_SCORE_FILE}")
            except Exception as e:
                print(f"[ОШИБКА] Не удалось создать файл рекордов: {e}")
            return 0
        try:
            with open(HIGH_SCORE_FILE, 'r') as f:
                high_score = int(f.read())
                print(f"[ОТЛАДКА] Рекорд загружен: {high_score}")
                return high_score
        except ValueError:
            print(f"[ОТЛАДКА] Файл рекордов повреждён. Сброс рекорда до 0.")
            return 0
        except Exception as e:
            print(f"[ОШИБКА] Ошибка загрузки рекорда: {e}")
            return 0

    def save_high_score(self):
        try:
            with open(HIGH_SCORE_FILE, 'w') as f:
                f.write(str(self.high_score))
            print(f"[ОТЛАДКА] Рекорд {self.high_score} сохранён в файл {HIGH_SCORE_FILE}")
        except Exception as e:
            print(f"[ОШИБКА] Ошибка сохранения рекорда: {e}")

    def handle_events(self, events):
        if self.is_paused:
            self.pause_menu.handle_event(events)
            return

        for event in events:
            if event.type == pygame.QUIT:
                self.save_high_score()
                pygame.quit()
                sys.exit()
            elif event.type == pygame.KEYDOWN:
                if event.key == pygame.K_ESCAPE:
                    self.toggle_pause()
                elif not self.is_paused and not self.game_over:
                    if event.key == pygame.K_LEFT:
                        self.snake.turn(-1)
                        print("[ОТЛАДКА] Нажата клавиша Влево")
                    elif event.key == pygame.K_RIGHT:
                        self.snake.turn(1)
                        print("[ОТЛАДКА] Нажата клавиша Вправо")
            elif event.type == pygame.KEYUP:
                if not self.is_paused and not self.game_over:
                    if event.key in [pygame.K_LEFT, pygame.K_RIGHT]:
                        self.snake.turn(0)
                        print("[ОТЛАДКА] Отпущена клавиша Влево или Вправо")
        if self.is_paused:
            self.pause_menu.handle_event(events)

    def toggle_pause(self):
        self.is_paused = not self.is_paused
        if self.is_paused:
            self.pause_menu.show()
            print("[ОТЛАДКА] Игра на паузе")
        else:
            self.pause_menu.hide()
            print("[ОТЛАДКА] Игра возобновлена")

    def resume(self):
        self.is_paused = False
        self.pause_menu.hide()
        print("[ОТЛАДКА] Выполнено возобновление игры")

    def return_to_main_menu(self):
        self.save_high_score()
        self.active = False
        self.game_over = False
        self.pause_menu.hide()
        print("[ОТЛАДКА] Возврат в Главное Меню")

    def update(self):
        if not self.is_paused and not self.game_over:
            collision_with_wall = self.snake.update()
            self.particles.update()
            self.check_collisions()
            if collision_with_wall:
                self.handle_game_over()

            if self.start_delay_frames <= 0:
                if self.snake.check_self_collision():
                    self.handle_game_over()
            else:
                self.start_delay_frames -=1
                if self.start_delay_frames == 0:
                    print("[ОТЛАДКА] Проверка столкновений активирована")

    def handle_game_over(self):
        self.save_high_score()
        self.game_over = True
        self.active = False
        self.on_game_over(self.score, self.high_score)
        print("[ОТЛАДКА] Проигрыш завершён")

    def check_collisions(self):
        head = self.snake.segments[0]
        distance = math.hypot(head[0] - self.food.x, head[1] - self.food.y)
        if distance < self.snake.radius + self.food.radius:
            print("[ОТЛАДКА] Змея съела еду")
            self.snake.grow()
            self.particles.emit(self.food.x, self.food.y)
            self.food.respawn()
            self.score += 10
            if self.score > self.high_score:
                self.high_score = self.score
                print(f"[ОТЛАДКА] Новый рекорд: {self.high_score}")

    def draw(self, surface):
        surface.fill(BACKGROUND_COLOR)
        self.food.draw(surface)
        self.snake.draw(surface)
        self.particles.draw(surface)
        # Рисуем счёт
        score_text = FONT.render(f"Счёт: {self.score}", True, (255, 255, 255))
        high_score_text = FONT.render(f"Рекорд: {self.high_score}", True, (255, 255, 255))
        surface.blit(score_text, (20, 20))
        surface.blit(high_score_text, (20, 50))

        if self.is_paused:
            self.pause_menu.draw(surface)
        if self.game_over_menu:
            self.game_over_menu.draw(surface)

# Класс Главного Меню
class MainMenu:
    def __init__(self, on_start_game, on_exit_game):
        self.menu = Menu(
            title="Главное Меню",
            options=["Начать игру", "Выйти"],
            on_select=self.handle_selection
        )
        self.on_start_game = on_start_game
        self.on_exit_game = on_exit_game
        self.active = True
        self.game_instance = None  # Изначально игра отсутствует
        print("[ОТЛАДКА] Главное Меню инициализировано")

    def handle_selection(self, selected_index):
        if selected_index == 0:
            print("[ОТЛАДКА] Главное Меню: Выбрана опция 'Начать игру'")
            self.on_start_game()
        elif selected_index == 1:
            print("[ОТЛАДКА] Главное Меню: Выбрана опция 'Выйти'")
            self.on_exit_game()

    def handle_events(self, events):
        for event in events:
            self.menu.handle_event(event)

    def update(self):
        self.menu.update()

    def draw(self, surface):
        self.menu.draw(surface)

    def show_menu(self):
        print("[ОТЛАДКА] Возврат в Главное Меню")
        if self.game_instance:
            self.game_instance.save_high_score()
            self.game_instance = None
        self.active = True

# Класс GameOver Меню уже определён выше

# Класс Паузы Меню уже определён выше

# Класс GameManager для управления состояниями игры
class GameManager:
    def __init__(self):
        self.state = GameState.MAIN_MENU
        self.main_menu = MainMenu(self.start_game, self.exit_game)
        self.game = None
        self.game_over_menu = None
        print("[ОТЛАДКА] Менеджер игры инициализирован")

    def start_game(self):
        self.game = Game(self.game_over, self.show_main_menu)
        self.state = GameState.PLAYING
        print("[ОТЛАДКА] Игра началась")

    def exit_game(self):
        print("[ОТЛАДКА] Выход из игры")
        if self.game:
            self.game.save_high_score()
        pygame.quit()
        sys.exit()

    def game_over(self, score, high_score):
        self.state = GameState.GAME_OVER
        self.game_over_menu = GameOverMenu(score, high_score, self.start_game, self.show_main_menu)
        print("[ОТЛАДКА] Переход в меню 'Игра окончена'")

    def show_main_menu(self):
        if self.game:
            self.game = None
        self.game_over_menu = None
        self.main_menu = MainMenu(self.start_game, self.exit_game)
        self.state = GameState.MAIN_MENU
        print("[ОТЛАДКА] Возврат в Главное Меню")

    def handle_events(self, events):
        if self.state == GameState.MAIN_MENU:
            self.main_menu.handle_events(events)
        elif self.state == GameState.PLAYING:
            self.game.handle_events(events)
        elif self.state == GameState.GAME_OVER:
            for event in events:
                self.game_over_menu.handle_event(event)

    def update(self):
        if self.state == GameState.MAIN_MENU:
            self.main_menu.update()
        elif self.state == GameState.PLAYING:
            self.game.update()
        elif self.state == GameState.GAME_OVER:
            self.game_over_menu.update()
            # После завершения затемнения и скрытия меню очищаем ссылку на GameOverMenu
            if self.game_over_menu.fade.finished and not self.game_over_menu.show_menu_surface:
                self.game_over_menu = None

    def draw(self, surface):
        if self.state == GameState.MAIN_MENU:
            self.main_menu.draw(surface)
        elif self.state == GameState.PLAYING:
            self.game.draw(surface)
        elif self.state == GameState.GAME_OVER:
            if self.game_over_menu:
                self.game_over_menu.draw(surface)

    def run(self):
        while True:
            events = pygame.event.get()
            self.handle_events(events)
            self.update()
            self.draw(SCREEN)

            pygame.display.flip()
            CLOCK.tick(FPS)

# Главный запуск игры
def main():
    game_manager = GameManager()
    game_manager.run()

# Запуск Игры
if __name__ == "__main__":
    main()