import os
from builders import TextFileMazeBuilder
from strategies import BFSStrategy, DFSStrategy, AStarStrategy
from solver import MazeSolver
from observers import ConsoleView
from commands import Player
from experiments import run_all_experiments, save_results_to_csv, print_results_table


def create_test_mazes():
    """Создаёт тестовые лабиринты в папке mazes/"""
    os.makedirs("mazes", exist_ok=True)
    
    # Маленький лабиринт 10×10
    small = """##########
#S       #
# ### ## #
#   #    #
### # ####
#   #    #
# ### #  #
#     #  #
#     # E#
##########"""
    
    # Средний лабиринт 20×11
    medium = """####################
#S                 #
# # # # # # # # # #
#                 #
# # # # # # # # # #
#                 #
# # # # # # # # # #
#                 #
# # # # # # # # # #
#                 E#
####################"""
    
    # Большой лабиринт 30×15
    large = """##############################
#S                           #
# # # # # # # # # # # # # # #
#                           #
# # # # # # # # # # # # # # #
#                           #
# # # # # # # # # # # # # # #
#                           #
# # # # # # # # # # # # # # #
#                           #
# # # # # # # # # # # # # # #
#                           #
# # # # # # # # # # # # # # #
#                           E#
##############################"""
    
    # Пустой лабиринт (без стен)
    empty = "S" + " " * 28 + "E"
    
    # Лабиринт без выхода
    no_exit = """#######
#S    #
# ### #
#   # #
#######"""
    
    # Сохранение файлов
    with open("mazes/small.txt", "w") as f:
        f.write(small)
    with open("mazes/medium.txt", "w") as f:
        f.write(medium)
    with open("mazes/large.txt", "w") as f:
        f.write(large)
    with open("mazes/empty.txt", "w") as f:
        f.write(empty)
    with open("mazes/no_exit.txt", "w") as f:
        f.write(no_exit)
    
    print("✅ Тестовые лабиринты созданы в папке 'mazes/'")


def demo_maze_solver():
    """Демонстрация работы MazeSolver с разными стратегиями"""
    print("\n" + "=" * 60)
    print("ДЕМОНСТРАЦИЯ РАБОТЫ MAZE SOLVER")
    print("=" * 60)
    
    builder = TextFileMazeBuilder()
    view = ConsoleView()
    
    try:
        maze = builder.build_from_file("mazes/small.txt")
        view.update("maze_loaded", {"maze": maze})
        
        strategies = [
            ("BFS", BFSStrategy(), "BFS (поиск в ширину)"),
            ("DFS", DFSStrategy(), "DFS (поиск в глубину)"),
            ("A*", AStarStrategy(), "A* (A-star поиск)")
        ]
        
        for name, strategy, description in strategies:
            print(f"\n--- {description} ---")
            solver = MazeSolver(maze, strategy)
            view.update("search_start", {"algorithm": description})
            
            path, stats = solver.solve()
            
            if stats.path_found:
                view.update("path_found", {"maze": maze, "path": path, "stats": stats})
            else:
                view.update("no_path", {"stats": stats})
    
    except Exception as e:
        print(f"❌ Ошибка: {e}")


def demo_player_controls():
    """Демонстрация управления игроком (Command + Observer)"""
    print("\n" + "=" * 60)
    print("ДЕМОНСТРАЦИЯ УПРАВЛЕНИЯ (Command + Observer)")
    print("=" * 60)
    
    builder = TextFileMazeBuilder()
    view = ConsoleView()
    
    try:
        maze = builder.build_from_file("mazes/small.txt")
        player = Player(maze.start)
        
        view.update("maze_loaded", {"maze": maze})
        view.render(maze, player_position=player.current_cell)
        
        print("\n💡 Для управления игроком в консоли введите W/A/S/D")
        print("   (это демонстрация работы паттернов Command и Observer)")
        
    except Exception as e:
        print(f"❌ Ошибка: {e}")


def run_experiments():
    """Запуск экспериментов для сравнения алгоритмов"""
    print("\n" + "=" * 60)
    print("ЭКСПЕРИМЕНТАЛЬНОЕ СРАВНЕНИЕ АЛГОРИТМОВ")
    print("=" * 60)
    
    maze_files = [
        "mazes/small.txt",
        "mazes/medium.txt",
        "mazes/large.txt",
        "mazes/empty.txt",
        "mazes/no_exit.txt"
    ]
    
    results = run_all_experiments(maze_files, repeats=5)
    save_results_to_csv(results)
    print_results_table(results)


def main():
    """Главная функция"""
    print("=" * 60)
    print("🎯 ОБЪЕКТНО-ОРИЕНТИРОВАННАЯ РЕАЛИЗАЦИЯ ПОИСКА В ЛАБИРИНТЕ")
    print("📚 Применённые паттерны: Builder, Strategy, Observer, Command")
    print("=" * 60)
    
    # Создание тестовых лабиринтов
    create_test_mazes()
    
    # Демонстрация работы
    demo_maze_solver()
    demo_player_controls()
    
    # Эксперименты
    run_experiments()
    
    print("\n" + "=" * 60)
    print("✅ Программа завершена!")
    print("📊 Для построения графиков запустите: python visualize.py")
    print("=" * 60)


if __name__ == "__main__":
    main()