import time
import csv
import os
from lab2.maze_solver import TextFileMazeBuilder, BFSStrategy, DFSStrategy, AStarStrategy, MazeSolver

def save_maze_to_file(maze, filename):
    with open(filename, 'w') as f:
        for row in maze:
            f.write(''.join(row) + '\n')

def run_test(maze_file, strategy_class):
    builder = TextFileMazeBuilder()
    maze = builder.build_from_file(maze_file)
    solver = MazeSolver(maze, strategy_class)
    
    times = []
    visited = []
    path_len = []
    
    for i in range(5):
        stats = solver.solve()
        times.append(stats.time_ms)
        visited.append(stats.visited_count)
        path_len.append(stats.path_length)
    
    return {
        'time': sum(times) / 5,
        'visited': sum(visited) / 5,
        'path': sum(path_len) / 5,
        'path_found': max(path_len) > 0
    }

def main():

    print("Эксперименты по поиску пути в лабиринте")
   
    
    results = []
    
   
    print("\n1. Простой лабиринт (10x10)")
    
    
    
    simple = [
        "#######",
        "#S    #",
        "# ### #",
        "#   E #",
        "#######"
    ]
    with open('simple.txt', 'w') as f:
        for line in simple:
            f.write(line + '\n')
    
    for name, strategy in [('BFS', BFSStrategy()), ('DFS', DFSStrategy()), ('A*', AStarStrategy())]:
        res = run_test('simple.txt', strategy)
        print(f"{name}: время={res['time']:.3f}мс, посещено={res['visited']:.0f}, путь={res['path']:.0f}")
        results.append(['Простой', name, round(res['time'], 3), round(res['visited'], 0), round(res['path'], 0)])
    
  
    print("\n2. Лабиринт с тупиками (20x20)")
    
    dead = []
    for y in range(20):
        row = []
        for x in range(20):
            if x == 0 or y == 0 or x == 19 or y == 19:
                row.append('#')
            elif (x == 5 and y > 5 and y < 15) or (y == 5 and x > 5 and x < 15):
                row.append('#')
            else:
                row.append(' ')
        dead.append(row)
    dead[1][1] = 'S'
    dead[18][18] = 'E'
    
    with open('dead.txt', 'w') as f:
        for row in dead:
            f.write(''.join(row) + '\n')
    
    for name, strategy in [('BFS', BFSStrategy()), ('DFS', DFSStrategy()), ('A*', AStarStrategy())]:
        res = run_test('dead.txt', strategy)
        print(f"{name}: время={res['time']:.3f}мс, посещено={res['visited']:.0f}, путь={res['path']:.0f}")
        results.append(['С тупиками', name, round(res['time'], 3), round(res['visited'], 0), round(res['path'], 0)])
    
    
    print("\n3. Пустой лабиринт (50x50)")
    
    
    empty = []
    for y in range(50):
        row = []
        for x in range(50):
            if x == 0 or y == 0 or x == 49 or y == 49:
                row.append('#')
            else:
                row.append(' ')
        empty.append(row)
    empty[1][1] = 'S'
    empty[48][48] = 'E'
    
    with open('empty.txt', 'w') as f:
        for row in empty:
            f.write(''.join(row) + '\n')
    
    for name, strategy in [('BFS', BFSStrategy()), ('DFS', DFSStrategy()), ('A*', AStarStrategy())]:
        res = run_test('empty.txt', strategy)
        print(f"{name}: время={res['time']:.3f}мс, посещено={res['visited']:.0f}, путь={res['path']:.0f}")
        results.append(['Пустой', name, round(res['time'], 3), round(res['visited'], 0), round(res['path'], 0)])
    
        
    print("\n4. Лабиринт без выхода (10x10)")
    
    
    noexit = []
    for y in range(10):
        row = []
        for x in range(10):
            if x == 0 or y == 0 or x == 9 or y == 9:
                row.append('#')
            else:
                row.append('#')
        noexit.append(row)
    noexit[1][1] = 'S'
    noexit[8][8] = 'E' 
    
    with open('noexit.txt', 'w') as f:
        for row in noexit:
            f.write(''.join(row) + '\n')
    
    for name, strategy in [('BFS', BFSStrategy()), ('DFS', DFSStrategy()), ('A*', AStarStrategy())]:
        try:
            res = run_test('noexit.txt', strategy)
            if res['path_found']:
                print(f"{name}: путь найден! длина={res['path']:.0f}")
                results.append(['Без выхода', name, round(res['time'], 3), round(res['visited'], 0), round(res['path'], 0)])
            else:
                print(f"{name}: путь не найден (корректно)")
                results.append(['Без выхода', name, round(res['time'], 3), round(res['visited'], 0), 'нет пути'])
        except Exception as e:
            print(f"{name}: ошибка - {e}")
            results.append(['Без выхода', name, 0, 0, 'ошибка'])
    
    
    os.makedirs('docs/data', exist_ok=True)
    with open('docs/data/maze_experiments.csv', 'w', newline='', encoding='utf-8') as f:
        writer = csv.writer(f)
        writer.writerow(['Лабиринт', 'Стратегия', 'Время(мс)', 'Посещено клеток', 'Длина пути'])
        writer.writerows(results)
    

if __name__ == "__main__":
    main()