import csv
import os

try:
    import matplotlib.pyplot as plt
    import matplotlib.patches as mpatches
    HAS_MPL = True
except ImportError:
    HAS_MPL = False
    print(" matplotlib не установлен: pip install matplotlib\n")

CSV_PATH = os.path.join(os.path.dirname(os.path.abspath(__file__)), 'results.csv')
OUT_DIR  = os.path.dirname(os.path.abspath(__file__))

COLORS = {'BFS': '#4E9AF1', 'DFS': '#F4845F', 'A*': '#6BCB77'}
STRATEGIES = ['BFS', 'DFS', 'A*']
METRICS = [
    ('время_мс',          'Среднее время (мс)'),
    ('посещено_клеток',   'Посещено клеток'),
    ('длина_пути',        'Длина пути (шагов)'),
]


def load_csv(path):
    data = {}
    with open(path, newline='', encoding='utf-8') as f:
        reader = csv.DictReader(f)
        for row in reader:
            key = (row['лабиринт'], row['стратегия'])
            data[key] = {
                'время_мс':        float(row['время_мс']),
                'посещено_клеток': float(row['посещено_клеток']),
                'длина_пути':      float(row['длина_пути']),
            }
    return data


def get_mazes(data):
    seen = []
    for (maze, _) in data:
        if maze not in seen:
            seen.append(maze)
    return seen


def plot_by_metric(data):
    mazes = get_mazes(data)
    x = range(len(mazes))
    w = 0.25

    for metric_key, metric_label in METRICS:
        fig, ax = plt.subplots(figsize=(12, 5))
        fig.suptitle(f'{metric_label} по лабиринтам', fontweight='bold')

        for i, strat in enumerate(STRATEGIES):
            vals = [data.get((m, strat), {}).get(metric_key, 0) for m in mazes]
            offset = [xi + (i - 1) * w for xi in x]
            bars = ax.bar(offset, vals, width=w,
                          label=strat, color=COLORS[strat], edgecolor='white')
            for bar, val in zip(bars, vals):
                if val > 0:
                    ax.text(bar.get_x() + bar.get_width() / 2,
                            bar.get_height() + max(vals) * 0.01,
                            f'{val:.1f}', ha='center', va='bottom', fontsize=7)

        ax.set_xticks(list(x))
        ax.set_xticklabels(mazes, rotation=15, ha='right', fontsize=9)
        ax.set_ylabel(metric_label)
        ax.legend()
        ax.grid(axis='y', alpha=0.3)

        safe = metric_key.replace('_', '-')
        out = os.path.join(OUT_DIR, f'chart_{safe}.png')
        plt.tight_layout()
        plt.savefig(out, dpi=150, bbox_inches='tight')
        print(f" График сохранён: {out}")
        plt.show()


def print_table(data):
    print(f"\n{'Лабиринт':<20} {'Алгоритм':<6} "
          f"{'Время мс':>10} {'Посещено':>10} {'Путь':>6}")
    print('-' * 56)
    for (maze, strat), vals in sorted(data.items()):
        print(f"{maze:<20} {strat:<6} "
              f"{vals['время_мс']:>10.3f} "
              f"{vals['посещено_клеток']:>10.0f} "
              f"{vals['длина_пути']:>6.0f}")


if __name__ == '__main__':
    if not os.path.exists(CSV_PATH):
        print(f" Файл не найден: {CSV_PATH}")
        print("   Сначала запустите: python benchmark.py")
        exit(1)

    data = load_csv(CSV_PATH)
    print_table(data)

    if HAS_MPL:
        plot_by_metric(data)
    else:
        print("\n Установите matplotlib: pip install matplotlib")
