import os
import csv
import matplotlib.pyplot as plt
import numpy as np
from itertools import zip_longest

# --- 1. Première fonction (inchangée) ---
def csv_to_list(chemin, nom_fichier):
    valeurs = []
    with open(os.path.join(chemin, nom_fichier), mode='r', encoding='utf-8') as fichier:
        lecteur_csv = csv.reader(fichier)
        next(lecteur_csv, None) 
        for ligne in lecteur_csv:
            if len(ligne) >= 2:
                valeurs.append(float(ligne[1]))
    return valeurs


# --- 2. Seconde fonction adaptée ---
def graph_trois_ratios(fichier_LP, fichier_spyros, fichier_w_haut, chemin):
    """
    Lit trois fichiers CSV, trace leurs ratios sur un même graphe avec 
    indicateurs de Consistance et Robustesse, et sauvegarde une synthèse CSV.
    """
    # --- 0. Extraction des données via la première fonction ---
    print("Lecture des fichiers CSV...")
    ratio_LP = csv_to_list(chemin, fichier_LP)
    ratio_spyros = csv_to_list(chemin, fichier_spyros)
    ratio_w_haut = csv_to_list(chemin, fichier_w_haut)

    # --- 1. Export des données dans un fichier CSV de synthèse ---
    csv_filename = os.path.join(chemin, "ratios_export.csv")
    with open(csv_filename, mode='w', newline='', encoding='utf-8') as file:
        writer = csv.writer(file)
        writer.writerow(['k', 'ratio_LP', 'ratio_spyros', 'ratio_w_haut'])
        
        # zip_longest permet de gérer le cas où les listes n'auraient pas la même taille
        for i, (r_lp, r_sp, r_wh) in enumerate(zip_longest(ratio_LP, ratio_spyros, ratio_w_haut, fillvalue='')):
            writer.writerow([i + 1, r_lp, r_sp, r_wh])
            
    print(f"Données fusionnées et sauvegardées avec succès dans : {csv_filename}")

    # --- 2. Préparation du graphe ---
    plt.figure(figsize=(14, 8))
    
    # Configuration des 3 séries (Nom, Données, Couleur)
    series = [
        {"data": ratio_LP, "name": "Linear Programming (LP)", "short_name": "LP", "color": "#d62728"},
        {"data": ratio_spyros, "name": "Linear Uniform (LU)", "short_name": "LU", "color": "#1f77b4"},
        {"data": ratio_w_haut, "name": "Linear Uniform Continuous (LUC)", "short_name": "LUC", "color": "#2ca02c"}
    ]
    
    y_min_global = float('inf')
    y_max_global = float('-inf')

    # --- 3. Tracé et calculs pour chaque ratio ---
    for idx, serie in enumerate(series):
        ratios = serie["data"]
        if not ratios: # Sécurité si une liste est vide
            print(f"Attention: La série {serie['name']} est vide.")
            continue
            
        nom = serie["name"]
        nom_court = serie["short_name"]
        couleur = serie["color"]
        n_total = len(ratios)
        k_values = list(np.arange(1, n_total + 1))
        
        # Maj des limites pour un affichage propre à la fin
        y_min_global = min(y_min_global, min(ratios))
        y_max_global = max(y_max_global, max(ratios))

        # --- Calcul des métriques ---
        robustness = max(ratios)
        # Sécurité au cas où le fichier a moins de 2500 lignes
        index_consistence = min(2499, n_total - 1) 
        consistence = ratios[index_consistence]
        
        k_cons = index_consistence + 1
        k_rob = ratios.index(robustness) + 1

        # --- Tracé de la courbe principale ---
        plt.scatter(k_values, ratios, color=couleur, alpha=0.38, s=10, label=nom)

        # Décalages dynamiques pour éviter que les annotations de texte se superposent
        if nom_court in {"LP", "LU", "LUC"}:
            offset_y_cons = 0
        if nom_court == "LUC":
            offset_x_rob = 0
            offset_x_cons = 36
            offset_y_rob = -63
        if nom_court == "LU":
            offset_x_rob = 0
            offset_x_cons = 36
            offset_y_rob = 10 + (idx * 15)
        if nom_court == "LP":
            offset_x_rob = 20
            offset_x_cons = 36
            offset_y_rob = 10 + (idx * 15)




        # Annotations Robustesse (Max)
        plt.scatter(k_rob, robustness, color=couleur, s=24, linewidths=0, zorder=4)
        plt.annotate(f'R_{nom_court}: {robustness:.3f}',
                     xy=(k_rob, robustness), xytext=(offset_x_rob, offset_y_rob),
                     textcoords='offset points', arrowprops=dict(arrowstyle='->', color=couleur),
                     fontsize=9, fontweight='bold', color=couleur,
                     ha='center' if offset_x_rob == 0 else ('left' if offset_x_rob > 0 else 'right'))

        # Annotations Consistance (Fixée à l'index k_cons)
        plt.scatter(k_cons, consistence, color=couleur, s=24, linewidths=0, zorder=4)
        plt.annotate(f'C_{nom_court}: {consistence:.3f}',
                     xy=(k_cons, consistence), xytext=(offset_x_cons, offset_y_cons),
                     textcoords='offset points', arrowprops=dict(arrowstyle='->', color=couleur),
                     fontsize=9, fontweight='bold', color=couleur,
                     ha='left')

    # --- 4. Mise en page du graphique ---
    plt.xlabel("k facilities", fontsize=13, labelpad=28)
    plt.ylabel(r"Ratio $\frac{alg_k}{\tilde{opt}_k}$", fontsize=13, rotation=0, labelpad=55)
    plt.axvline(x=2500, color='black', linestyle='--', linewidth=1.0, alpha=0.7)
    plt.annotate("prediction = 2500",
                 xy=(2500, 0), xycoords=('data', 'axes fraction'),
                 xytext=(0, -22), textcoords='offset points',
                 ha='center', va='top', fontsize=10)

    plt.grid(True, which='both', linestyle='--', alpha=0.3)
    legend = plt.legend(loc='upper right', frameon=True, shadow=True, markerscale=1.8)
    for handle in legend.legend_handles:
        handle.set_alpha(0.9)

    # Ajustement des limites pour bien voir les annotations extrêmes
    if y_min_global != float('inf'):
        plt.ylim(y_min_global - 0.05, y_max_global + 0.15)

    # plt.savefig(os.path.join(chemin, "graphe_ratios.pdf")) # Optionnel : sauvegarde en PDF
    plt.show()

def load_graph(chemin):
    """
    Charge les données des ratios depuis un fichier CSV et affiche le graphe.
    """
    csv_filename = os.path.join(chemin, "ratios_export.csv")
    
    if not os.path.exists(csv_filename):
        print(f"Erreur : Le fichier {csv_filename} n'existe pas.")
        return
    
    ratio_LP, ratio_spyros, ratio_w_haut = [], [], []
    
    with open(csv_filename, mode='r') as file:
        reader = csv.DictReader(file)
        for row in reader:
            ratio_LP.append(float(row['ratio_LP']) if row['ratio_LP'] else None)
            ratio_spyros.append(float(row['ratio_spyros']) if row['ratio_spyros'] else None)
            ratio_w_haut.append(float(row['ratio_w_haut']) if row['ratio_w_haut'] else None)

    graph_trois_ratios(ratio_LP, ratio_spyros, ratio_w_haut, chemin)


if __name__ == "__main__":
    racine = "/Users/imrane/Desktop/Online bidding/online-bidding/application_new/ratios"

    graph_trois_ratios(
    fichier_LP="ratio_LP.csv", 
    fichier_spyros="ratio_spyros.csv", 
    fichier_w_haut="ratio_w_haut_R=4.csv", 
    chemin=racine
)
