import sys
from pathlib import Path

from builders import TextFileMazeBuilder
from solver import MazeSolver
from strategies import BFSStrategy, DFSStrategy, AStarStrategy
from visualization import ConsoleView
from experiments import ExperimentRunner


def create_test_maze_file(filename: str, maze_data: list):
    Path("mazes").mkdir(exist_ok=True)
    with open(f"mazes/{filename}", 'w', encoding='utf-8') as f:
        f.write('\n'.join(maze_data))


def setup_test_mazes():
    
    
    small_maze = [
        "##########",
        "#S       #",
        "# ####### #",
        "#       # #",
        "##### # # #",
        "#     #   #",
        "# ### ### #",
        "#   #     #",
        "#   #### E#",
        "##########"
    ]
    create_test_maze_file("small_maze.txt", small_maze)
    
    
    simple_maze = [
        "##########",
        "#S       #",
        "#        #",
        "#        #",
        "#        #",
        "#        #",
        "#        #",
        "#        #",
        "#       E#",
        "##########"
    ]
    create_test_maze_file("simple_maze.txt", simple_maze)
    
    
    no_exit_maze = [
        "##########",
        "#S       #",
        "# ####### #",
        "#       # #",
        "##### # # #",
        "#     #   #",
        "# ### ### #",
        "#   #     #",
        "#   #######",
        "##########"
    ]
    
    create_test_maze_file("no_exit_maze.txt", no_exit_maze)
    
   
    blocked_maze = [
        "##########",
        "#S#      #",
        "# #      #",
        "# #      #",
        "# #      #",
        "# #      #",
        "# #      #",
        "# #      #",
        "# #######E",
        "##########"
    ]
    create_test_maze_file("blocked_maze.txt", blocked_maze)


def interactive_mode():
    
    print("=" * 50)
    print("Интерактивный режим")
    print("=" * 50)
    
    builder = TextFileMazeBuilder()
    view = ConsoleView()
    
    maze_file = input("Введите путь к файлу (по умолчанию: mazes/small_maze.txt): ")
    if not maze_file:
        maze_file = "mazes/small_maze.txt"
    
    try:
        maze = builder.build_from_file(maze_file)
        view.update("maze_loaded", {"maze": maze})
    except Exception as e:
        print(f"Ошибка: {e}")
        return
    
    print("\nСтратегии:")
    print("1. BFS")
    print("2. DFS")
    print("3. A*")
    
    choice = input("Выберите (1-3): ")
    strategies = {"1": BFSStrategy(), "2": DFSStrategy(), "3": AStarStrategy()}
    strategy = strategies.get(choice, BFSStrategy())
    
    print(f"\nВыбрана: {strategy.name}")
    
    solver = MazeSolver(maze, strategy)
    path, stats = solver.solve()
    
    if path:
        view.update("path_found", {"path": path, "maze": maze})
        print(f"\n{stats}")
    else:
        view.update("path_not_found", {})
        print("Путь не найден!")


def experiment_mode():
    
    print("\n" + "=" * 50)
    print("Экспериментальное сравнение")
    print("=" * 50)
    
    setup_test_mazes()
    
    runner = ExperimentRunner()
    maze_files = ["mazes/small_maze.txt", "mazes/simple_maze.txt", "mazes/no_exit_maze.txt"]
    results = runner.run_all_experiments(maze_files, runs=10)
    
    print("\n" + "=" * 50)
    print("Результаты:")
    print("=" * 50)
    print(f"{'Лабиринт':<15} {'Стратегия':<8} {'Ср. время (мс)':<15} {'Длина пути':<10}")
    print("-" * 50)
    
    for r in results:
        print(f"{r['maze']:<15} {r['strategy']:<8} {r['avg_time_ms']:<15.3f} {r['path_length']:<10}")


def main():
    print("\n" + "=" * 50)
    print("Лабораторная: Поиск выхода из лабиринта")
    print("Паттерны: Builder, Strategy, Observer, Command")
    print("=" * 50)
    
    print("\n1. Интерактивный режим")
    print("2. Экспериментальный режим")
    
    choice = input("\nВыберите (1-2): ")
    
    if choice == "1":
        interactive_mode()
    elif choice == "2":
        experiment_mode()
    else:
        print("Неверный выбор!")


if __name__ == "__main__":
    main()