import matplotlib
matplotlib.use('TkAgg')
import matplotlib.pyplot as plt
import math
import seaborn as sns
import pandas as pd

def filter_dataframe1(df):
    df = pd.DataFrame(df, columns=[
                               "MATERIAL_NAME_TULUS","THICKNESS_TULUS [mm]",
                               "NOZZLE_TYPE", "CONTOUR_SPEED [mm/min]",
                                "LASER_POWER [W]",
                               "CONTOUR_GAS_PRESSURE [bar]", "CONTOUR_NOZZLE_DISTANCE [mm]", "CONTOUR_FOCAL [mm]",
                               "QUALITY_CUT", "DEFECT_TYPE"])
    return df

def filter_dataframe2(df):
    df = pd.DataFrame(df, columns=
                               ['MATERIAL_NAME_TULUS','THICKNESS_TULUS [mm]', 'NOZZLE_TYPE', 'CONTOUR_SPEED [mm/min]',
       'LASER_POWER [W]', 'CONTOUR_GAS_PRESSURE [bar]',
       'CONTOUR_NOZZLE_DISTANCE [mm]', 'CONTOUR_FOCAL [mm]', 'QUALITY_CUT',
       'DEFECT_TYPE', 'TECHNOLOGY_GAS', 'CONTOUR_LASER_MODE', 'LASER_TYPE'])
    return df


def plot_matrix_grid(df, cols_per_row=3, fig_width=15, row_height=4,speed_is_dense=False,pressure_is_dense=False,focal_is_dense=False,title=None):
    columns = df.keys()
    total_cols = len(columns)

    # Calcola il numero di righe necessarie
    rows = math.ceil(total_cols/cols_per_row)

    # Crea la griglia di subplot
    fig, axs = plt.subplots(rows, cols_per_row,
                           figsize=(fig_width, row_height * rows),
                           squeeze=False)
    fig.subplots_adjust(hspace=0.5, wspace=0.3)

    for idx, col in enumerate(columns):
        row =  idx // cols_per_row
        col_pos = idx % cols_per_row

        ax = axs[row, col_pos]


        if col == "CONTOUR_SPEED [mm/min]" and speed_is_dense:
             # Crea l'istogramma
            n_bins = 40
            counts, bin_edges, patches = ax.hist(df[col].dropna(), bins=n_bins, color='steelblue', alpha=0.7,edgecolor='black')

            # Regola i tick sull'asse X
            # Bin edges sono i bordi degli intervalli
            ax.set_xticks(bin_edges)  # Imposta i tick sull'asse X basati sui bin edges

            # regolazione intervallo ticks
            ax.set_xticklabels([f'{x:.2f}' for x in bin_edges], rotation=45)
            

        elif col == "CONTOUR_FOCAL [mm]" and focal_is_dense:
           # Crea l'istogramma
            n_bins = 30
            counts, bin_edges, patches = ax.hist(df[col].dropna(), bins=n_bins, color='steelblue', alpha=0.7,edgecolor='black')

            # Regola i tick sull'asse X
            # Bin edges sono i bordi degli intervalli
            ax.set_xticks(bin_edges)  # Imposta i tick sull'asse X basati sui bin edges

            # regolazione intervallo ticks
            ax.set_xticklabels([f'{x:.2f}' for x in bin_edges], rotation=45)
             
        elif col == "CONTOUR_GAS_PRESSURE [bar]" and pressure_is_dense:
           # Crea l'istogramma
            n_bins = 40
            counts, bin_edges, patches = ax.hist(df[col].dropna(), bins=n_bins, color='steelblue', alpha=0.7,edgecolor='black')

            # Regola i tick sull'asse X
            # Bin edges sono i bordi degli intervalli
            ax.set_xticks(bin_edges)  # Imposta i tick sull'asse X basati sui bin edges

            # regolazione intervallo ticks
            ax.set_xticklabels([f'{x:.2f}' for x in bin_edges], rotation=45)

        else:
             if pd.api.types.is_numeric_dtype(df[col]):
                rounded_col = df[col].round(2)  # Arrotonda a 2 cifre decimali
                counts = rounded_col.value_counts().sort_index()
             else:
                counts = df[col].value_counts().sort_index()
             counts.plot(kind='bar', ax=ax, width=0.8, color='steelblue')
            # Rinomina i tick dell'asse X con valori arrotondati (se numerici)
             try:
                rounded_labels = [f"{float(label):.2f}" for label in counts.index]
                ax.set_xticklabels(rounded_labels, rotation=45)
             except ValueError:
                # Se le label non sono numeri (es. stringhe), lascia così
                pass
                       
        # Personalizzazione griglia
        ax.yaxis.grid(True, linestyle='--', alpha=0.6)
        ax.xaxis.grid(False)
        ax.set_axisbelow(True)

        # Formattazione
        ax.set_title(col, fontsize=10, pad=5)
        ax.tick_params(axis='both', which='major', labelsize=8)
        ax.tick_params(axis='x', rotation=45)

        # Rimuozione bordi
        for spine in ['top', 'right']:
            ax.spines[spine].set_visible(False)

        # Aggiungi valori sulle barre
        for p in ax.patches:
            ax.annotate(f"{p.get_height():.0f}",
                       (p.get_x() + p.get_width() / 2., p.get_height()),
                       ha='center', va='center',
                       xytext=(0, 5),
                       textcoords='offset points',
                       fontsize=7)

    # Nascondi gli assi vuoti
    for idx in range(len(columns), rows * cols_per_row):
        row = idx // cols_per_row
        col_pos = idx % cols_per_row
        axs[row, col_pos].axis('off')

    plt.tight_layout()
    if title != None:
        plt.savefig(f"{title}.png")
    else:
        plt.show()
    plt.close()
