from abc import ABC, abstractmethod
from typing import List, Optional

from maze import Maze, Cell


class Observer(ABC):
    """Интерфейс наблюдателя (Observer pattern)."""
    
    @abstractmethod
    def update(self, event: str):
        pass


class ConsoleView(Observer):
    """
    Консольное представление лабиринта.
    """
    
    def __init__(self):
        self.events: List[str] = []
    
    def update(self, event: str):
        """Получаем уведомление о событии."""
        self.events.append(event)
        print(f"[Observer] Событие: {event}")
    
    def render(self, maze: Maze, player_position: Cell = None, path: List[Cell] = None):
        """
        Отрисовка лабиринта в консоли.
        """
        path_set = set(path) if path else set()
        
        for y in range(maze.height):
            row = []
            for x in range(maze.width):
                cell = maze.get_cell(x, y)
                
                if player_position and cell == player_position:
                    row.append('P')
                elif cell in path_set:
                    row.append('*')
                else:
                    row.append(str(cell))
                
            print(''.join(row))
        print()
    
    def render_stats(self, stats):
        """Отрисовка статистики поиска."""
        print(f"Алгоритм: {stats.algorithm_name}")
        print(f"Время: {stats.time_ms:.4f} мс")
        print(f"Посещено клеток: {stats.visited_cells}")
        print(f"Длина пути: {stats.path_length}")