import sys
import os

# Добавляем корневую папку в путь поиска
sys.path.insert(0, r'C:\ivantsovma\docs\MazeProject')

from builders import TextFileMazeBuilder
from strategies import BFSStrategy, DFSStrategy, AStarStrategy
from solver import MazeSolver

def test_solver_basic():
    print("БАЗОВАЯ РАБОТА MAZESOLVER")
    
    # Загружаем лабиринт
    builder = TextFileMazeBuilder()
    maze = builder.build_from_file("mazes/small_maze.txt")
    
    print(f"\nЛабиринт загружен: {maze.width}x{maze.height}")
    print(f"Старт: ({maze.start.x}, {maze.start.y})")
    print(f"Выход: ({maze.exit.x}, {maze.exit.y})")
    
    # Создаем решатель с BFS стратегией
    solver = MazeSolver(maze, BFSStrategy())
    
    # Решаем лабиринт
    print("\nРешение лабиринта (BFS)")
    stats = solver.solve()
    
    print(f"\nРезультат:")
    print(f"   {stats}")
    
    # Показываем путь на карте
    print("\nВизуализация пути:")
    solver.print_maze_with_path()
    
    return solver, stats

#Тест динамической смены стратегии
def test_solver_dynamic_strategy():
    print("ДИНАМИЧЕСКАЯ СМЕНА СТРАТЕГИИ")
    
    # Загружаем лабиринт
    builder = TextFileMazeBuilder()
    maze = builder.build_from_file("mazes/small_maze.txt")
    
    # Создаем решатель без стратегии
    solver = MazeSolver(maze)
    
    # Пробуем разные стратегии
    strategies = [
        BFSStrategy(),
        DFSStrategy(),
        AStarStrategy()
    ]
    
    for strategy in strategies:
        print(f"\nУстановка стратегии: {strategy.name}")
        solver.set_strategy(strategy)
        stats = solver.solve()
        print(f"  {stats}")
    
    return solver

#Сравнение
def test_solver_comparison():
    print("СРАВНЕНИЕ ВСЕХ СТРАТЕГИЙ")
    
    # Загружаем лабиринт
    builder = TextFileMazeBuilder()
    maze = builder.build_from_file("mazes/small_maze.txt")
    
    # Создаем решатель
    solver = MazeSolver(maze)
    
    # Сравниваем стратегии
    strategies = [BFSStrategy(), DFSStrategy(), AStarStrategy()]
    results = solver.compare_strategies(strategies)
    
    #Сводную таблица
    print("СВОДНАЯ ТАБЛИЦА")
    print(f"\n  {'Стратегия':<10} {'Время(мс)':<10} {'Посещено':<10} {'Длина пути':<10} {'Статус':<10}")
    
    for name, data in results.items():
        stats = data['stats']
        print(f"  {name:<10} {stats.time_ms:<10.2f} {stats.visited_cells:<10} {stats.path_length:<10} {'OK' if stats.path_found else 'BULLSHIT'}")
    
    return results

#Тест на разных лабиринтах
def test_multiple_mazes():
    print("РАЗНЫЕ ЛАБИРИНТЫ")
    
    mazes_files = [
        ("mazes/simple_maze.txt", "Простой (5x3)"),
        ("mazes/small_maze.txt", "Средний (7x7)")
    ]
    
    strategies = [BFSStrategy(), DFSStrategy(), AStarStrategy()]
    
    for maze_file, maze_name in mazes_files:
        print(f"\n{maze_name}")
        try:
            builder = TextFileMazeBuilder()
            maze = builder.build_from_file(maze_file)
            solver = MazeSolver(maze)
            
            for strategy in strategies:
                solver.set_strategy(strategy)
                stats = solver.solve()
                status = "OK" if stats.path_found else "BULLSHIT"
                print(f"  {status} {strategy.name}: {stats.time_ms:.2f}мс | {stats.visited_cells} клеток | длина={stats.path_length}")
        except Exception as e:
            print(f" Ошибка загрузки {maze_file}: {e}")

def test_no_exit_maze():
    print("ЛАБИРИНТ БЕЗ ВЫХОДА")
    #Создаем простой лабиринт без выхода
    from models import Maze, Cell
    
    maze = Maze(5, 5)
    
    #Заполняем проходами
    for y in range(5):
        for x in range(5):
            cell = Cell(x, y, is_wall=False)
            maze.set_cell(x, y, cell)
    
    #Устанавливаем старт, но НЕ устанавливаем выход!
    start = maze.get_cell(0, 0)
    start.is_start = True
    maze.start = start
    
    # Выход не устанавливаем (maze.exit = None)
    
    # Создаем стену, чтобы заблокировать путь
    for x in range(5):
        wall = maze.get_cell(x, 4)
        wall.is_wall = True
    
    print(f"\nЛабиринт: {maze.width}x{maze.height}")
    print(f"Старт: ({maze.start.x}, {maze.start.y})")
    print(f"Выход: отсутствует (None)")
    
    # Пытаемся найти выход
    solver = MazeSolver(maze, BFSStrategy())
    
    try:
        stats = solver.solve()
        print(f"\nРезультат:")
        print(f" {stats}")
    except ValueError as e:
        print(f"\nРезультат:")
        print(f"Ошибка: {e}")
        print(f"\nКорректная обработка: программа обнаружила отсутствие выхода")

if __name__ == "__main__":
    # Запускаем все тесты
    test_solver_basic()
    test_solver_dynamic_strategy()
    test_solver_comparison()
    test_multiple_mazes()
    test_no_exit_maze()

    print("ВСЕ ТЕСТЫ ЗАВЕРШЕНЫ")