import openpyxl

def excel_row_to_string(file_path):
    # Öffne die Excel-Datei
    workbook = openpyxl.load_workbook(file_path)

    # Wähle das Arbeitsblatt aus
    sheet = workbook['Sheet1']

    # Erhalte die angegebene Zeile als Liste von Zellen
    row_values = [cell.value for cell in sheet[2]]

    # Ergebnisse werden ab Spalte 5 eingetragen
    selected_columns = list(range(4, len(row_values)))

    # Wähle nur die gewünschten Spalten aus
    selected_values = [row_values[col] for col in selected_columns]

    # Schließe die Excel-Datei
    workbook.close()

    # Konvertiere die Liste von Zellen in einen String
    row_string = ', '.join(str(value) for value in selected_values)

    return row_string

def write_subdivided_string_to_excel(file_path, input_string):
    # Öffne die Excel-Datei
    workbook = openpyxl.load_workbook(file_path)

    # Wähle das Arbeitsblatt aus
    sheet = workbook['Sheet1']

    # Teile den String nach jedem Komma auf
    parts = input_string.split(',')

    # Trage jeden Teil des Strings in eine neue Zeile ein
    for i, part in enumerate(parts, 1):

        #Spalte 17 kann sich je nach Tabellenstruktur ändern!
        sheet.cell(row=2 + i - 1, column=17, value=part.strip())  # strip entfernt mögliche Leerzeichen

    # Speichere die Änderungen
    workbook.save(file_path)

    # Schließe die Excel-Datei
    workbook.close()

def read_columns(file_path):
    # Öffne die Excel-Datei
    workbook = openpyxl.load_workbook(file_path)

    # Wähle das Arbeitsblatt aus
    sheet = workbook['Sheet1']

    # Lese die Werte der beiden Spalten aus
    values_column1 = [cell.value for cell in sheet['O']][1:]
    values_column2 = [cell.value for cell in sheet['Q']][1:]

    # Schließe die Excel-Datei
    workbook.close()

    return values_column1, values_column2

def calculate_deviation(liste1, liste2):
    # Überprüfe, ob die Listen die gleiche Länge haben
    if len(liste1) != len(liste2):
        raise ValueError("Die Listen müssen die gleiche Länge haben")

    # Berechne die prozentuale Abweichung zwischen den Werten
    deviations = [((abs(float(b) - float(a)) / float(a)) * 100) if float(a) != 0 else None for a, b in zip(liste1, liste2)]

    return deviations

def write_string_to_excel(file_path, input_string, column):
    # Öffne die Excel-Datei
    workbook = openpyxl.load_workbook(file_path)

    # Wähle das Arbeitsblatt aus
    sheet = workbook['Sheet1']

    # Trage jeden Buchstaben des Strings in eine eigene Zeile ein
    for i, char in enumerate(input_string, 1):
        sheet.cell(row=2 + i - 1, column=column, value=char)

    # Speichere die Änderungen
    workbook.save(file_path)

    # Schließe die Excel-Datei
    workbook.close()

def copy_header(input_sheet, output_sheet):
    # Kopiere den Header manuell in das Ausgabe-Arbeitsblatt
    for row in input_sheet.iter_rows(min_row=1, max_row=1, values_only=True):
        output_sheet.append(row)

def sort_excel(input_file_path, output_file_path, ):
    # Öffne die Eingabe-Excel-Datei
    input_workbook = openpyxl.load_workbook(input_file_path)
    input_sheet = input_workbook['Sheet1']

    # Erstelle eine neue Excel-Tabelle für die sortierten Zeilen
    output_workbook = openpyxl.Workbook()
    output_sheet = output_workbook.active

    # Kopiere den Header ins Ausgabe-Arbeitsblatt
    copy_header(input_sheet, output_sheet)

    # Lese die Daten-Zeilen aus der Tabelle
    data_rows = list(input_sheet.iter_rows(min_row=2, values_only=True))

    # Sortiere die Daten-Zeilen nach dem Wert der angegebenen Spalte
    sorted_data_rows = sorted(data_rows, key=lambda x: x[18 - 1])  # -1, da Listenindizes bei 0 beginnen

    # Schreibe die sortierten Daten-Zeilen in die neue Tabelle
    for row in sorted_data_rows:
        output_sheet.append(row)

    # Speichere die Änderungen in der neuen Excel-Datei
    output_workbook.save(output_file_path)

    # Schließe die Excel-Dateien
    input_workbook.close()
    output_workbook.close()


#Sollten mehrere Testruns ausgewertet werden wollen, müssen die enthaltenen Funktionen umstrukturiert werden
#Aktuell wird nur der Testrun in Zeile 1 ausgewertet
#Eine Weitere Funktion, die zwei Tabellenzeilen tauscht, wäre der einfachste workaround
def evaluation(testcases, testruns):
    
    #liest die Ergebnisse des Testruns aus
    #bei mehreren Testruns muss diese Funktion angepasst werden!
    input_string = excel_row_to_string(testruns)

    #schreibt die Berechneten Ergebnisse in die Testcases-Tabelle
    write_subdivided_string_to_excel(testcases, input_string)

    #liest die gemessenen und die errechneten Werte aus den Testcases
    values_col1, values_col2 = read_columns(testcases)

    #berechnet aus diesen Werten die prozentuale Abweichung
    deviations = calculate_deviation(values_col1, values_col2)

    #Trägt die prozentualen Abweichungen in die Testcases-Tabelle
    #je nach Tabellenstruktur kann sich die 18 ändern!
    write_string_to_excel(testcases, deviations, 18)

    #Gibt die eine Kopie der Testcases-Tabelle sortiert nach Genauigkeit aus
    sort_excel(testcases, 'Testcases_nach_Genauigkeit.xlsx')

