import pandas as pd
import matplotlib.pyplot as plt
from pathlib import Path

BASE_DIR = Path(__file__).resolve().parent.parent
DATA_PATH = BASE_DIR / "results.csv"
ATTACHMENTS_DIR = BASE_DIR / "attachments"


def shuffled_sorted_plots(structures, df):
    for mode in ['shuffled', 'sorted']:
        mode_title = 'перемешанные данные' if mode == 'shuffled' else 'отсортированные данные'
        fig, axes = plt.subplots(1, 3, figsize=(15, 6))
        fig.suptitle(f'Производительность — {mode_title}')
    
        for ax, op in zip(axes, ['insert', 'find', 'delete']):
            subset = df[(df['mode'] == mode) & (df['operation'] == op)]
            structures_average = subset.groupby('structure')['time_sec'].mean()
            means = [structures_average[s] for s in structures]
            
            bars = ax.bar(structures, means, color=['#4C72B0', '#55A868', '#C44E52'])
            ax.set_title(op)
            ax.set_ylabel('t (с)')
            ax.set_yscale('log')
            ax.grid(True, axis='y', alpha=0.3)
    
            for bar, val in zip(bars, means):
                label = f'{val:.5f}' if val > 0.0001 else f'{val:.1e}'
                ax.text(bar.get_x() + bar.get_width() / 2, bar.get_height(),
                        label, ha='center', va='bottom', fontsize=9)
    
        plt.tight_layout()
        save_path = ATTACHMENTS_DIR / f'plot_{mode}.png'
        plt.savefig(save_path, dpi=300)
        plt.close()
        print(f'Saved: {save_path.name}')


def bst_shuffled_vs_sorted(df):
    fig, ax = plt.subplots(figsize=(7, 5))
    fig.suptitle('Производительность bst_insert(): перемешанные и упорядоченные данные')
    
    bst_insert = df[(df['structure'] == 'BST') & (df['operation'] == 'insert')]
    modes_average = bst_insert.groupby('mode')['time_sec'].mean()
    modes = ['shuffled', 'sorted']
    means = [modes_average[m] for m in modes]
    
    bars = ax.bar(modes, means, color=['#4C72B0', '#C44E52'])
    ax.set_ylabel('t (c)')
    ax.set_yscale('log')
    ax.grid(True, axis='y', alpha=0.3)
    
    for bar, val in zip(bars, means):
        label = f'{val:.5f}' if val > 0.0001 else f'{val:.1e}'
        ax.text(bar.get_x() + bar.get_width() / 2, bar.get_height(),
                label, ha='center', va='bottom', fontsize=10)
    
    plt.tight_layout()
    save_path = ATTACHMENTS_DIR / 'plot_bst_comparison.png'
    plt.savefig(save_path, dpi=300)
    plt.close()
    print(f'Saved: {save_path.name}')


def build_plots():
    ATTACHMENTS_DIR.mkdir(exist_ok=True)
    
    if not DATA_PATH.exists():
            raise ValueError(f"File not found: {DATA_PATH}")
    
    df = pd.read_csv(DATA_PATH)
    
    STRUCTURES = ['LinkedList', 'HashTable', 'BST']
    
    shuffled_sorted_plots(STRUCTURES, df)
    bst_shuffled_vs_sorted(df)


if __name__ == "__main__":
    build_plots()
