from abc import ABC, abstractmethod
from classes import Cell, Maze


class MazeBuilder(ABC):
      #Интерфейс строителя лабиринта (паттерн Builder).

    @abstractmethod
    def build_from_file(self, filename: str) -> Maze:
       #Читает файл и возвращает готовый объект Maze.
        ...


class TextFileMazeBuilder(MazeBuilder):

    def build_from_file(self, filename: str) -> Maze:
        with open(filename, "r", encoding="utf-8") as f:
            lines = f.read().splitlines()

        if not lines:
            raise ValueError("Файл лабиринта пуст.")

        height = len(lines)
        width = max(len(line) for line in lines)

        # Дополняем строки до одинаковой длины (стенами)
        lines = [line.ljust(width, "#") for line in lines]

        cells: list[list[Cell]] = []
        start: Cell | None = None
        exit_cell: Cell | None = None

        for y, line in enumerate(lines):
            row = []
            for x, ch in enumerate(line):
                is_wall = ch == "#"
                is_start = ch == "S"
                is_exit = ch == "E"
                cell = Cell(x, y, is_wall=is_wall, is_start=is_start, is_exit=is_exit)
                if is_start:
                    start = cell
                if is_exit:
                    exit_cell = cell
                row.append(cell)
            cells.append(row)

        if start is None:
            raise ValueError("Лабиринт не содержит стартовой клетки (S).")
        if exit_cell is None:
            raise ValueError("Лабиринт не содержит выхода (E).")

        return Maze(width, height, cells, start, exit_cell)