import matplotlib.pyplot as plt
import pandas as pd
import matplotlib
import time
import os

W = 10
H = 5
FONTSIZE = 18
FONTSIZE_LABELS = 14
INSTANCE_SUBSET = ['20', '30', '40', '50', '60', '70', '80', '90', '100', '150', '200', '250']
X_LABEL = 'Instance size'
Y_LABEL = 'GAP (%)'
STYLE = 'o--'

# Set font types
matplotlib.rcParams['pdf.fonttype'] = 42
matplotlib.rcParams['ps.fonttype'] = 42

# Set plot style
plt.style.use('tableau-colorblind10')

if not os.path.exists('plots'):
    os.makedirs('plots')



def main():
    start_time = time.perf_counter()
    data = pd.read_csv('results/data.csv')
    print(f'Data has {len(data)} rows and {len(data.columns)} columns')
    data = data.drop_duplicates()
    print(f'After removing duplicates, data has {len(data)} rows and {len(data.columns)} columns')
    BP = pd.read_csv('results/bp.csv') 

    static_size = data[(data['algorithm']== "static") & (data['decreasing'] == ' False')]
    dinamic_size = data[(data['algorithm']== "static") & (data['decreasing'] == ' True')]

    static_size_5 = static_size[static_size['destruction_size'] == 5]
    static_size_10 = static_size[static_size['destruction_size'] == 10]
    static_size_15 = static_size[static_size['destruction_size'] == 15]
    static_size_20 = static_size[static_size['destruction_size'] == 20]

    dinamic_size_5 = dinamic_size[dinamic_size['max_iterations_without_improvement'] == 5]
    dinamic_size_10 = dinamic_size[dinamic_size['max_iterations_without_improvement'] == 10]
    dinamic_size_15 = dinamic_size[dinamic_size['max_iterations_without_improvement'] == 15]
    dinamic_size_20 = dinamic_size[dinamic_size['max_iterations_without_improvement'] == 20]
    dinamic_size_30 = dinamic_size[dinamic_size['max_iterations_without_improvement'] == 30]
    dinamic_size_50 = dinamic_size[
        (dinamic_size['destroyers'] == "['EmployeeWeighted_EmployeeUniform_TourRemover']") 
        & (dinamic_size['max_iterations_without_improvement'] == 50)
        & (dinamic_size['date'] < '2023/07/21')
        ]


    TR = dinamic_size[dinamic_size['destroyers'] == "['TourRemover']"]
    EU = dinamic_size[dinamic_size['destroyers'] == "['EmployeeUniform']"]
    EW = dinamic_size[dinamic_size['destroyers'] == "['EmployeeWeighted']"]
    EW_TR = dinamic_size[dinamic_size['destroyers'] == "['EmployeeWeighted_TourRemover']"]
    EU_TR = dinamic_size[dinamic_size['destroyers'] == "['EmployeeUniform_TourRemover']"]
    EU_EW = dinamic_size[dinamic_size['destroyers'] == "['EmployeeUniform_EmployeeWeighted']"]
    ALL = dinamic_size[
        (dinamic_size['destroyers'] == "['EmployeeWeighted_EmployeeUniform_TourRemover']")
        & (dinamic_size['max_iterations_without_improvement'] == 50)
        & (dinamic_size['date'] >= '2023/07/21')
        ]


    ALNS = data[data['algorithm'] != 'static']
    ALNS_small = ALNS[ALNS["algorithm"] == 'adaptive_small']
    ALNS_medium = ALNS[ALNS["algorithm"] == 'adaptive_avg']
    ALNS_large = ALNS[ALNS["algorithm"] == 'adaptive_large']


    # check if each dataset contains 5*12=60 instances
    print(f'Static size 5 has {len(static_size_5)} runs')
    print(f'Static size 10 has {len(static_size_10)} runs')
    print(f'Static size 15 has {len(static_size_15)} runs')
    print(f'Static size 20 has {len(static_size_20)} runs')
    print(f'Dinamic size 5 has {len(dinamic_size_5)} runs')
    print(f'Dinamic size 10 has {len(dinamic_size_10)} runs')
    print(f'Dinamic size 15 has {len(dinamic_size_15)} runs')
    print(f'Dinamic size 20 has {len(dinamic_size_20)} runs')
    print(f'Dinamic size 30 has {len(dinamic_size_30)} runs')
    print(f'Dinamic size 50 has {len(dinamic_size_50)} runs')
    print(f'TR has {len(TR)} runs')
    print(f'EU has {len(EU)} runs')
    print(f'EW has {len(EW)} runs')
    print(f'EW_TR has {len(EW_TR)} runs')
    print(f'EU_TR has {len(EU_TR)} runs')
    print(f'EU_EW has {len(EU_EW)} runs')
    print(f'ALL has {len(ALL)} runs')
    print(f'ALNS_small has {len(ALNS_small)} runs')
    print(f'ALNS_medium has {len(ALNS_medium)} runs')
    print(f'ALNS_large has {len(ALNS_large)} runs')

#   Group each of them by instance
    static_size_5 = static_size_5.groupby('instance')
    static_size_10 = static_size_10.groupby('instance')
    static_size_15 = static_size_15.groupby('instance')
    static_size_20 = static_size_20.groupby('instance')
    dinamic_size_5 = dinamic_size_5.groupby('instance')
    dinamic_size_10 = dinamic_size_10.groupby('instance')
    dinamic_size_15 = dinamic_size_15.groupby('instance')
    dinamic_size_20 = dinamic_size_20.groupby('instance')
    dinamic_size_30 = dinamic_size_30.groupby('instance')
    dinamic_size_50 = dinamic_size_50.groupby('instance')
    BP = BP.groupby('instance')
    TR = TR.groupby('instance')
    EU = EU.groupby('instance')
    EW = EW.groupby('instance')
    EW_TR = EW_TR.groupby('instance')
    EU_TR = EU_TR.groupby('instance')
    EU_EW = EU_EW.groupby('instance')
    ALL = ALL.groupby('instance')
    ALNS_small = ALNS_small.groupby('instance')
    ALNS_medium = ALNS_medium.groupby('instance')
    ALNS_large = ALNS_large.groupby('instance')


    print('Start plotting...')

    fig, ax = plt.subplots()
    fig.set_size_inches(W, H)
    ax.set_xlabel(X_LABEL, fontsize=FONTSIZE)
    ax.set_ylabel(Y_LABEL, fontsize=FONTSIZE)
    plt.yticks(fontsize=FONTSIZE_LABELS)
    plt.xticks(fontsize=FONTSIZE_LABELS)
    plt.plot(INSTANCE_SUBSET, static_size_5['best_gap_bks'].mean(), STYLE, label='5')
    plt.plot(INSTANCE_SUBSET, static_size_10['best_gap_bks'].mean(), STYLE, label='10')
    plt.plot(INSTANCE_SUBSET, static_size_15['best_gap_bks'].mean(), STYLE, label='15')
    plt.plot(INSTANCE_SUBSET, static_size_20['best_gap_bks'].mean(), STYLE, label='20')
    plt.axhline(y=0, color='black', linestyle='-', linewidth=1)
    plt.legend(fontsize=FONTSIZE, title='$k_0$', title_fontsize=FONTSIZE)
    plt.grid(True)
    plt.tight_layout()
    plt.savefig('plots/staticSize-GAP_mean.pdf')
    print('Plotted staticSize-GAP_mean.pdf')


    fig, ax = plt.subplots()
    fig.set_size_inches(W, H)
    ax.set_xlabel(X_LABEL, fontsize=FONTSIZE)
    ax.set_ylabel(Y_LABEL, fontsize=FONTSIZE)
    plt.yticks(fontsize=FONTSIZE_LABELS)
    plt.xticks(fontsize=FONTSIZE_LABELS)
    plt.plot(INSTANCE_SUBSET, dinamic_size_5['best_gap_bks'].mean(), STYLE, label='5')
    plt.plot(INSTANCE_SUBSET, dinamic_size_10['best_gap_bks'].mean(), STYLE, label='10')
    # plt.plot(INSTANCE_SUBSET, dinamic_size_15['best_gap_bks'].mean(), STYLE, label='15')
    plt.plot(INSTANCE_SUBSET, dinamic_size_20['best_gap_bks'].mean(), STYLE, label='20')
    plt.plot(INSTANCE_SUBSET, dinamic_size_30['best_gap_bks'].mean(), STYLE, label='30')
    plt.plot(INSTANCE_SUBSET, dinamic_size_50['best_gap_bks'].mean(), STYLE, label='50')
    plt.axhline(y=0, color='black', linestyle='-', linewidth=1)
    plt.legend(fontsize=FONTSIZE, title='$n_{max}$', title_fontsize=FONTSIZE)
    plt.grid(True)
    plt.tight_layout()
    plt.savefig('plots/dinamicSize-GAP_mean.pdf')
    print('Plotted dinamicSize-GAP_mean.pdf')


    fig, ax = plt.subplots()
    fig.set_size_inches(W, H)
    ax.set_xlabel(X_LABEL, fontsize=FONTSIZE)
    ax.set_ylabel(Y_LABEL,fontsize=FONTSIZE)
    plt.yticks(fontsize=FONTSIZE_LABELS)
    plt.xticks(fontsize=FONTSIZE_LABELS)
    plt.plot(INSTANCE_SUBSET, TR['best_gap_bks'].mean(), STYLE, label='TR')
    plt.plot(INSTANCE_SUBSET, EU['best_gap_bks'].mean(), STYLE, label='EU')
    plt.plot(INSTANCE_SUBSET, EW['best_gap_bks'].mean(), STYLE, label='EW')
    plt.plot(INSTANCE_SUBSET, EW_TR['best_gap_bks'].mean(), STYLE, label='EW+TR')
    plt.plot(INSTANCE_SUBSET, EU_TR['best_gap_bks'].mean(), STYLE, label='EU+TR')
    # plt.plot(INSTANCE_SUBSET, EU_EW['best_gap_bks'].mean(), STYLE, label='EU_EW')
    plt.plot(INSTANCE_SUBSET, ALL['best_gap_bks'].mean(), STYLE, label='ALL')
    plt.axhline(y=0, color='black', linestyle='-', linewidth=1)
    plt.legend(fontsize=FONTSIZE)
    plt.grid(True)
    plt.tight_layout()
    plt.savefig('plots/destroyers-GAP_avg.pdf')
    print('Plotted destroyers-GAP_avg.pdf')


    fig, ax = plt.subplots()
    fig.set_size_inches(W, H)
    ax.set_xlabel(X_LABEL, fontsize=FONTSIZE)
    ax.set_ylabel('#successes/#calls', fontsize=FONTSIZE)
    plt.yticks(fontsize=FONTSIZE_LABELS)
    plt.xticks(fontsize=FONTSIZE_LABELS)
    plt.plot(INSTANCE_SUBSET, TR['incumbent_changes'].mean()/TR['CG_calls'].mean(), STYLE, label='TR')
    plt.plot(INSTANCE_SUBSET, EU['incumbent_changes'].mean()/EU['CG_calls'].mean(), STYLE, label='EU')
    plt.plot(INSTANCE_SUBSET, EW['incumbent_changes'].mean()/EW['CG_calls'].mean(), STYLE, label='EW')
    plt.plot(INSTANCE_SUBSET, EW_TR['incumbent_changes'].mean()/EW_TR['CG_calls'].mean(), STYLE, label='EW+TR')
    plt.plot(INSTANCE_SUBSET, EU_TR['incumbent_changes'].mean()/EU_TR['CG_calls'].mean(), STYLE, label='EU+TR')
    plt.plot(INSTANCE_SUBSET, ALL['incumbent_changes'].mean()/ALL['CG_calls'].mean(), STYLE, label='ALL')
    plt.legend(fontsize=FONTSIZE)

    plt.grid(True)
    plt.tight_layout()
    plt.savefig(f'plots/destroyers-performance_ratio.pdf')
    print('Plotted destroyers-performance_ratio.pdf')




    # now all together
    fig, ax = plt.subplots()
    fig.set_size_inches(W, H)
    ax.set_xlabel(X_LABEL, fontsize=FONTSIZE)
    ax.set_ylabel(Y_LABEL,fontsize=FONTSIZE)
    plt.yticks(fontsize=FONTSIZE_LABELS)
    plt.xticks(fontsize=FONTSIZE_LABELS)
    plt.plot(INSTANCE_SUBSET, BP['avg_time'].mean(), STYLE, label='BP avg')
    plt.plot(INSTANCE_SUBSET, ALL['avg_time'].mean(), STYLE, label='CG avg')
    plt.plot(INSTANCE_SUBSET, BP['max_time'].mean(), STYLE, label='BP max')
    plt.plot(INSTANCE_SUBSET, ALL['max_time'].mean(), STYLE, label='CG max')
    plt.legend(fontsize=FONTSIZE_LABELS)
    plt.grid(True)
    plt.tight_layout()
    plt.savefig('plots/BPvsCG_time.pdf')
    print('Plotted BPvsCG_time.pdf')


    # now all together
    fig, ax = plt.subplots()
    fig.set_size_inches(W, H)
    ax.set_xlabel(X_LABEL, fontsize=FONTSIZE)
    ax.set_ylabel(Y_LABEL,fontsize=FONTSIZE)
    plt.yticks(fontsize=FONTSIZE_LABELS)
    plt.xticks(fontsize=FONTSIZE_LABELS)
    plt.plot(INSTANCE_SUBSET, BP['best_gap_bks'].mean(), STYLE, label='BP')
    plt.plot(INSTANCE_SUBSET, ALL['best_gap_bks'].mean(), STYLE, label='CG')
    plt.legend(fontsize=FONTSIZE)
    plt.axhline(y=0, color='black', linestyle='-', linewidth=1)
    plt.grid(True)
    plt.tight_layout()
    plt.savefig('plots/BPvsCG_GAP_avg.pdf')
    print('Plotted BPvsCG_GAP_avg.pdf')


    fig, ax = plt.subplots()
    fig.set_size_inches(W, H)
    ax.set_xlabel(X_LABEL, fontsize=FONTSIZE)
    ax.set_ylabel('Number of iterations',fontsize=FONTSIZE)
    plt.plot(INSTANCE_SUBSET, TR['iterations'].mean(), STYLE, label='Static')
    plt.plot(INSTANCE_SUBSET, dinamic_size_5['iterations'].mean(), STYLE, label='Dynamic ($n_{max}=5$)')
    plt.plot(INSTANCE_SUBSET, dinamic_size_15['iterations'].mean(), STYLE, label='Dynamic ($n_{max}=15$)')
    plt.plot(INSTANCE_SUBSET, dinamic_size_50['iterations'].mean(), STYLE, label='Dynamic ($n_{max}=50$)')
    plt.legend(fontsize=FONTSIZE_LABELS)
    plt.grid(True)
    plt.tight_layout()
    plt.savefig('plots/iterations.pdf')
    print('Plotted iterations.pdf')


    fig, ax = plt.subplots()
    fig.set_size_inches(W, H)
    ax.set_xlabel(X_LABEL, fontsize=FONTSIZE)
    ax.set_ylabel(Y_LABEL,fontsize=FONTSIZE)
    plt.yticks(fontsize=FONTSIZE_LABELS)
    plt.xticks(fontsize=FONTSIZE_LABELS)
    plt.plot(INSTANCE_SUBSET, ALNS_small['best_gap_bks'].mean(), STYLE, label='ALNS ($\lambda = 1/3$)')
    plt.plot(INSTANCE_SUBSET, ALNS_medium['best_gap_bks'].mean(), STYLE, label='ALNS ($\lambda = 0.5$)')
    plt.plot(INSTANCE_SUBSET, ALNS_large['best_gap_bks'].mean(), STYLE, label='ALNS ($\lambda =2/3$)')
    plt.plot(INSTANCE_SUBSET, TR['best_gap_bks'].mean(), STYLE, label='LNS (only TR)')

    plt.legend(fontsize=FONTSIZE)
    plt.axhline(y=0, color='black', linestyle='-', linewidth=1)
    plt.grid(True)
    plt.tight_layout()
    plt.savefig('plots/ALNSvsLNS_avg.pdf')
    print('Plotted ALNSvsLNS_avg.pdf')

    # final results with all the instances
    final = pd.read_csv('results/final.csv')
    
    fig, ax = plt.subplots()
    fig.set_size_inches(W, H)
    ax.set_xlabel('Instance', fontsize=FONTSIZE)
    ax.set_ylabel(Y_LABEL, fontsize=FONTSIZE)
    plt.plot(final['LNS_GAP'], STYLE, label='LNS')
    plt.plot(final['CMSA_GAP'], STYLE, label='CMSA')
    plt.plot(final['BP_GAP'], '*--', label='BP')
    plt.axhline(y=0, color='black', linestyle='-', linewidth=1)
    plt.legend(fontsize=FONTSIZE)
    plt.grid(True)
    plt.tight_layout()
    plt.savefig('plots/final.pdf')
    print('Plotted final.pdf')



    print(f'Completely finished after {round(time.perf_counter() - start_time, 2)} seconds.')



if __name__ == '__main__':
    main()
