from abc import ABC, abstractmethod
from typing import Any
from enum import Enum, auto

class EventType(Enum):
    MAZE_LOADED = auto()
    PATH_FOUND = auto()
    PATH_NOT_FOUND = auto()
    PLAYER_MOVED = auto()
    SEARCH_START = auto()
    SEARCH_END = auto()
    ERROR = auto()
    UNDO = auto()

class Event:
    def __init__(self, event_type: EventType, data: Any = None):
        self.event_type = event_type
        self.data = data

class Observer(ABC):    
    @abstractmethod
    def update(self, event: Event):
        pass

class Observable:
    def __init__(self):
        self._observers = []
    
    def attach(self, observer: Observer):
        if observer not in self._observers:
            self._observers.append(observer)
    
    def detach(self, observer: Observer):
        if observer in self._observers:
            self._observers.remove(observer)
    
    def notify(self, event: Event):
        for observer in self._observers:
            observer.update(event)