"""
experiment.py - экспериментальное сравнение стратегий поиска пути.

Для каждого лабиринта × стратегии:
    - запускаем solve() TRIALS раз
    - усредняем время в мс, фиксируем число посещённых клеток и длину пути
    - сохраняем в docs/data/results.csv
"""

import csv
import os

from maze_solver import (
    TextFileMazeBuilder, MazeSolver,
    BFSStrategy, DFSStrategy, AStarStrategy, DijkstraStrategy,
)


TRIALS = 7

MAZES = [
    ("small_10x10",    "mazes/small_10x10.txt"),
    ("medium_51x51",   "mazes/medium_51x51.txt"),
    ("large_101x101",  "mazes/large_101x101.txt"),
    ("empty_30x30",    "mazes/empty_30x30.txt"),
    ("nopath_15x15",   "mazes/nopath_15x15.txt"),
    ("weighted_31x31", "mazes/weighted_31x31.txt"),
    ("weighted_choice","mazes/weighted_choice.txt"),
]

STRATEGY_CLASSES = [BFSStrategy, DFSStrategy, AStarStrategy, DijkstraStrategy]

OUT_CSV = "docs/data/results.csv"


def main():
    os.makedirs(os.path.dirname(OUT_CSV), exist_ok=True)
    builder = TextFileMazeBuilder()

    rows = [["лабиринт", "стратегия", "trial",
             "время_мс", "посещено_клеток", "длина_пути", "стоимость_пути"]]
    summary = []

    for maze_name, maze_path in MAZES:
        maze = builder.build_from_file(maze_path)
        print(f"\n## {maze_name} ({maze.width}x{maze.height})")

        for cls in STRATEGY_CLASSES:
            times, visited_vals, path_vals, cost_vals = [], [], [], []
            for trial in range(TRIALS):
                solver = MazeSolver(maze, cls())
                stats = solver.solve()
                cost = sum(c.weight for c in stats["path"])
                times.append(stats["elapsed_ms"])
                visited_vals.append(stats["visited"])
                path_vals.append(stats["path_length"])
                cost_vals.append(cost)
                rows.append([maze_name, stats["strategy"], trial + 1,
                             f"{stats['elapsed_ms']:.4f}",
                             stats["visited"], stats["path_length"], cost])

            mean_t = sum(times) / TRIALS
            print(f"   {cls.name:9s}  t_avg={mean_t:7.3f} ms  "
                  f"visited={visited_vals[0]:5d}  "
                  f"path={path_vals[0]:5d}  cost={cost_vals[0]:5d}")
            summary.append((maze_name, cls.name, mean_t,
                            visited_vals[0], path_vals[0], cost_vals[0]))

    rows.append([])
    rows.append(["--- СРЕДНИЕ ---"])
    rows.append(["лабиринт", "стратегия", "среднее_время_мс",
                 "посещено_клеток", "длина_пути", "стоимость_пути"])
    for r in summary:
        rows.append([r[0], r[1], f"{r[2]:.4f}", r[3], r[4], r[5]])

    with open(OUT_CSV, "w", newline="", encoding="utf-8") as f:
        csv.writer(f).writerows(rows)
    print(f"\nГотово. Результаты записаны в {OUT_CSV}")


if __name__ == "__main__":
    main()
