from abc import ABC, abstractmethod
from typing import Tuple
import os
from maze_model import Maze, Cell


class MazeBuilder(ABC):

    @abstractmethod
    def build_from_file(self, filename: str) -> Maze:
        pass


class TextFileMazeBuilder(MazeBuilder):

    def build_from_file(self, filename: str) -> Maze:
        if not os.path.exists(filename):
            raise FileNotFoundError(f"Файл {filename} не найден..")

        with open(filename, 'r', encoding='utf-8') as file:
            lines = [line.rstrip('\n') for line in file.readlines()]

        if not lines:
            raise ValueError("Пусто(")

        height = len(lines)
        width = len(lines[0]) if lines else 0

        for i, line in enumerate(lines):
            if len(line) != width:
                raise ValueError(f"Лабиринт не прямоугольный, что-то не так с размерами!")

        maze = Maze(width, height)
        start_found = False
        exit_found = False

        for y, line in enumerate(lines):
            for x, char in enumerate(line):
                cell = Cell(x, y)

                if char == '#':
                    cell.is_wall = True
                elif char == 'S':
                    cell.is_start = True
                    cell.is_wall = False
                    maze.start = cell
                    start_found = True
                elif char == 'E':
                    cell.is_exit = True
                    cell.is_wall = False
                    maze.exit = cell
                    exit_found = True
                elif char == ' ':
                    cell.is_wall = False
                else:
                    raise ValueError(f"Недопустимый символ-'{char}' в позиции ({x}, {y}), уберите его")

                maze.set_cell(x, y, cell)

        if not start_found:
            raise ValueError("В лабиринте нет начала")
        if not exit_found:
            raise ValueError("В лабиринте нет конца")

        return maze