from collections import deque


from source.strategy import PathFindingStrategy, reconstruct_path
from source.classes import Maze, Cell

class BFS(PathFindingStrategy):
    @property
    def name(self):
        """Возвращает название метода"""
        return "BFS"
    
    def findPath(self, maze: Maze) -> tuple[list[Cell], int]:
        start_cell = maze.start
        exit_cell = maze.exit

        # print(f"Старт: {start_cell.getXY()}")
        # print(f"Выход: {exit_cell.getXY()}")
        # print(f"Соседи старта: {[n.getXY() for n in maze.getNeighbors(start_cell)]}")

        queue = deque([start_cell])

        parents = {start_cell.getXY(): Cell(-1, -1)}
        visited = {start_cell.getXY()}
        count_visited = 1

        while queue:
            current = queue.popleft()

            if current.getXY() == exit_cell.getXY():
                return reconstruct_path(
                    came_from=parents, 
                    start=start_cell, 
                    end=current
                        ), count_visited

            # neigbours = maze.getNeighbors(current)
            # print(f"для клекти {current.getXY()} соседи: {[neigbour.getXY() for neigbour in neigbours]}")

            for neighbor in maze.getNeighbors(current):
                neig_xy = neighbor.getXY()

                if neig_xy not in visited:
                    visited.add(neig_xy)
                    parents[neig_xy] = current
                    count_visited += 1
                    queue.append(neighbor)

        return [], count_visited