from __future__ import annotations
import csv
from collections import defaultdict
from pathlib import Path
import matplotlib.pyplot as plt
from typing import List, Dict, Any

# Карта соответствия заголовков CSV для удобства поддержки
_CSV_KEYS = {
    "STRUCTURE": "Структура",
    "MODE": "Режим",
    "OP": "Операция",
    "MEASURE": "Замер",
    "TIME": "Время (сек)"
}

def load_average_results(csv_file: str) -> List[Dict[str, Any]]:
    """Загружает только строки со средними значениями из CSV."""
    with open(csv_file, "r", encoding="utf-8") as fh:
        return [
            {
                "structure": row[_CSV_KEYS["STRUCTURE"]],
                "mode": row[_CSV_KEYS["MODE"]],
                "operation": row[_CSV_KEYS["OP"]],
                "time": float(row[_CSV_KEYS["TIME"]])
            }
            for row in csv.DictReader(fh)
            if row[_CSV_KEYS["MEASURE"]] == "среднее"
        ]

def _render_chart(operation: str, data: List[Dict[str, Any]], save_path: Path) -> None:
    """Вспомогательная функция для отрисовки одного столбчатого графика."""
    fig, ax = plt.subplots(figsize=(10, 5))
    labels = [f"{rec['structure']}\n{rec['mode']}" for rec in data]
    values = [rec["time"] for rec in data]

    ax.bar(labels, values, color="cornflowerblue", edgecolor="navy")
    ax.set_title(f"{operation.capitalize()} Performance Comparison")
    ax.set_xlabel("Data Structure & Input Order")
    ax.set_ylabel("Execution Time (seconds)")
    ax.tick_params(axis="x", rotation=15)
    fig.tight_layout()
    fig.savefig(save_path, dpi=150)
    plt.close(fig)
    print(f"Saved chart: {save_path}")

def build_graphs(results: List[Dict[str, Any]], output_dir: str = "docs/data") -> None:
    """Группирует результаты по операциям и сохраняет графики."""
    out_path = Path(output_dir)
    out_path.mkdir(parents=True, exist_ok=True)

    grouped = defaultdict(list)
    for record in results:
        grouped[record["operation"]].append(record)

    for op_name in ("insert", "find", "delete"):
        if op_name in grouped:
            target_file = out_path / f"{op_name}.png"
            _render_chart(op_name, grouped[op_name], target_file)

def main():
    avg_data = load_average_results("results.csv")
    build_graphs(avg_data)

if __name__ == "__main__":
    main()