import time
from core.search_stats import SearchStats


class MazeSolver:
    def __init__(self, maze, strategy=None):
        self.maze = maze
        self.strategy = strategy
        self.observers = []

    def setStrategy(self, strategy):
        self.strategy = strategy

    def addObserver(self, observer):
        if observer not in self.observers:
            self.observers.append(observer)

    def removeObserver(self, observer):
        if observer in self.observers:
            self.observers.remove(observer)

    def notify(self, event):
        for observer in self.observers:
            observer.update(event)

    def solve(self):
        if self.strategy is None:
            raise ValueError("Strategy is not set")
        self.notify({"type": "search_started", "strategy": self.strategy.name})

        start_time = time.perf_counter()
        path = self.strategy.findPath(self.maze, self.maze.startCell, self.maze.exitCell)
        end_time = time.perf_counter()

        stats = SearchStats(
            timeMs=(end_time - start_time) * 1000.0,
            visitedCells=getattr(self.strategy, "visitedCount", 0),
            pathLength=len(path),
            path=path,
            found=bool(path),
            algorithm=getattr(self.strategy, "name", "")
        )

        if stats.found:
            self.notify({"type": "path_found", "strategy": stats.algorithm, "length": stats.pathLength})
        else:
            self.notify({"type": "path_not_found", "strategy": stats.algorithm})

        self.notify({"type": "search_finished", "stats": stats})
        return stats
