import pandas as pd
from pathlib import Path
from flask import Flask


currentDirectory = Path('P:\\SKR51_Dennis_Sebastian')

# filter = {
#     'Marke': "00-09",
#     'Standort': "00-09",
#     'Kostenstelle': "00-05;10-20;50-99",
#     'Absatzkanal': "00;10-16;20-26;30-36;40-46;50-56;60-66;90-96;99",
#     'Kostentraeger': "00-56;60-68;70-76;80-85"
# }

# matrix = [
#     {
#         'Kontonummer' : '0200',
#         'Kontobezeichnung' : 'Technische Anlagen und Maschinen',
#         'Kostenstelle' : '40-49;50-70;74;75-89',
#         'Absatzkanal' : '',
#         'Kostentraeger' : '70-79;80-99'
#     }
# ]

# buchungssalden = [
#     {
#         'Kontonummer': "0200",
#         'Marke': '01',
#         'Standort': '01',
#         'Kostenstelle' : '50',
#         'Absatzkanal' : '00',
#         'Kostentraeger' : '70',
#         'saldo': 1005.68
#     },
#     {
#         'Kontonummer': "0200",
#         'Marke': '01',
#         'Standort': '01',
#         'Kostenstelle' : '20',
#         'Absatzkanal' : '00',
#         'Kostentraeger' : '70',
#         'saldo': 1005.68
#     },
#     {
#         'Kontonummer': "0201",
#         'Marke': '01',
#         'Standort': '01',
#         'Kostenstelle' : '20',
#         'Absatzkanal' : '00',
#         'Kostentraeger' : '70',
#         'saldo': 1005.68
#     }
# ]


# kst_liste = ["00", "10", "11", "12"... ]

app = Flask(__name__)


@app.route('/cast-translation', methods=['POST', 'GET'])
def cast_translation():
    df = pd.read_csv(str(currentDirectory) + '/' + "Uebersetzung.csv", sep='\t', dtype={0: str, 1: str, 2: str, 3: str, 4: str, 5: str}, decimal=',')
    return df.to_json(indent=2, orient='records')


@app.route('/cast-matrix', methods=['POST', 'GET'])
def cast_matrix():
    df = pd.read_csv(str(currentDirectory) + '/' + "Plausibilitaetsmatrix.csv", sep='\t', dtype={0: str})
    return df.to_json(indent=2, orient='records')


@app.route('/cast-filter', methods=['POST', 'GET'])
def cast_filter():
    df = pd.read_csv(str(currentDirectory) + '/' + "SKR51_Kostenrechnungsmerkmale.csv", sep='\t', quotechar='"')
    return df.to_json(indent=2, orient='records')


def crea_list(liste):
    if liste == "":
        return [str(i).zfill(2) for i in range(0, 100)]

    result_list = []
    for x in liste.split(';'):
        if "-" in x:
            result_list += [str(i).zfill(2) for i in range(int(x.split("-")[0]), int(x.split("-")[1]) + 1)]
        else:
            result_list.append(x)
    return result_list


def check_konto(konto):
    for f in filter_csv.values:
        if konto[f[0]] not in f[2]:
            return False

    try:
        matrix_konto = matrix_csv[matrix_csv['Kontonummer'] == konto['Kontonummer']].to_dict('records')[0]

        for (k, current) in matrix_konto.items():
            if k != "Bezeichnung" and not pd.isna(current) and konto[k] not in crea_list(current):
                return False
    except IndexError:
        pass

    return True


def format_konto(konto):
    return f"{konto['Kontonummer']}-{konto['Marke']}-{konto['Standort']}-{konto['Kostenstelle']}-{konto['Absatzkanal']}-{konto['Kostentraeger']}"


def check_buchungssalden(salden):
    return [format_konto(x) + ": " + str(check_konto(x)) for x in salden]


def format_konto_neu(konto):
    return f"{konto['Kontonummer_neu']}-{konto['Marke_neu']}-{konto['Standort_neu']}-{konto['Kostenstelle_neu']}-{konto['Absatzkanal_neu']}-{konto['Kostentraeger_neu']}"


def check_Kontonummer(konto):
    try:
        matrix_konto = matrix_csv[matrix_csv['Kontonummer'] == konto['Kontonummer']].to_dict('records')[0]

        if not pd.isna(matrix_konto['Kontonummer']) and konto['Kontonummer'] not in crea_list(matrix_konto['Kontonummer']):
            return False
    except IndexError:
        pass

    return True


def check_marke(konto):
    if konto[filter_csv.values[0][0]] not in filter_csv.values[0][2]:
        return False
    return True


def check_Standort(konto):
    if konto[filter_csv.values[1][0]] not in filter_csv.values[1][2]:
        return False
    return True


def check_Kostenstelle(konto):
    if konto[filter_csv.values[2][0]] not in filter_csv.values[2][2]:
        return False

    try:
        matrix_konto = matrix_csv[matrix_csv['Kontonummer'] == konto['Kontonummer']].to_dict('records')[0]

        if not pd.isna(matrix_konto['Kostenstelle']) and konto['Kostenstelle'] not in crea_list(matrix_konto['Kostenstelle']):
            return False
    except IndexError:
        pass

    return True


def check_Absatzkanal(konto):
    if konto[filter_csv.values[3][0]] not in filter_csv.values[3][2]:
        return False

    try:
        matrix_konto = matrix_csv[matrix_csv['Kontonummer'] == konto['Kontonummer']].to_dict('records')[0]

        if not pd.isna(matrix_konto['Absatzkanal']) and konto['Absatzkanal'] not in crea_list(matrix_konto['Absatzkanal']):
            return False
    except IndexError:
        pass

    return True


def check_Kostentraeger(konto):
    if konto[filter_csv.values[4][0]] not in filter_csv.values[4][2]:
        return False

    try:
        matrix_konto = matrix_csv[matrix_csv['Kontonummer'] == konto['Kontonummer']].to_dict('records')[0]

        if not pd.isna(matrix_konto['Kostentraeger']) and konto['Kostentraeger'] not in crea_list(matrix_konto['Kostentraeger']):
            return False
    except IndexError:
        pass

    return True


def add_validation(salden):
    kontonummer_valid = []
    marke_valid = []
    standort_valid = []
    kostenstelle_valid = []
    absatzkanal_valid = []
    kostentraeger_valid = []
    konto_name = []
    konto_valid = []
    for x in salden:
        kontonummer_valid.append(check_Kontonummer(x))
        marke_valid.append(check_marke(x))
        standort_valid.append(check_Standort(x))
        kostenstelle_valid.append(check_Kostenstelle(x))
        absatzkanal_valid.append(check_Absatzkanal(x))
        kostentraeger_valid.append(check_Kostentraeger(x))
        konto_name.append(format_konto(x))
        konto_valid.append(str(check_konto(x)))
    df = pd.DataFrame(salden)
    df.insert(1, 'Kontonummer_valid', kontonummer_valid, True)
    df.insert(3, 'Marke_valid', marke_valid, True)
    df.insert(5, 'Standort_valid', standort_valid, True)
    df.insert(7, 'Kostenstelle_valid', kostenstelle_valid, True)
    df.insert(9, 'Absatzkanal_valid', absatzkanal_valid, True)
    df.insert(11, 'Kostentraeger_valid', kostentraeger_valid, True)
    df.insert(12, 'Konto', konto_name, True)
    df.insert(13, 'Konto_valid', konto_valid, True)
    return df


def uebersetzung(salden):
    Kontonummer_neu = []
    Marke_neu = []
    Standort_neu = []
    Kostenstelle_neu = []
    Absatzkanal_neu = []
    Kostentraeger_neu = []
    Konto_neu = []
    valid_salden = add_validation(salden)
    for index, row in valid_salden.iterrows():
        if not row['Marke_valid']:
            for i, r in uebersetzung_csv.iterrows():
                if r['Kontonummer'] == row['Kontonummer'] and row['Marke'] in crea_list(r['Marke']):
                    Marke_neu.append(r['Marke_neu'])
        if len(Marke_neu) == index:
            Marke_neu.append('')
        if not row['Standort_valid']:
            for i, r in uebersetzung_csv.iterrows():
                if r['Kontonummer'] == row['Kontonummer'] and row['Standort'] in crea_list(r['Standort']):
                    Standort_neu.append(r['Standort_neu'])
        if len(Standort_neu) == index:
            Standort_neu.append('')
        if not row['Kostenstelle_valid']:
            for i, r in uebersetzung_csv.iterrows():
                if r['Kontonummer'] == row['Kontonummer'] and row['Kostenstelle'] in crea_list(r['Kostenstelle']):
                    Kostenstelle_neu.append(r['Kostenstelle_neu'])
        if len(Kostenstelle_neu) == index:
            Kostenstelle_neu.append('')
        if not row['Absatzkanal_valid']:
            for i, r in uebersetzung_csv.iterrows():
                if r['Kontonummer'] == row['Kontonummer'] and row['Absatzkanal'] in crea_list(r['Absatzkanal']):
                    Absatzkanal_neu.append(r['Absatzkanal_neu'])
        if len(Absatzkanal_neu) == index:
            Absatzkanal_neu.append('')
        if not row['Kostentraeger_valid']:
            for i, r in uebersetzung_csv.iterrows():
                if r['Kontonummer'] == row['Kontonummer'] and row['Kostentraeger'] in crea_list(r['Kostentraeger']):
                    Kostentraeger_neu.append(r['Kostentraeger_neu'])
        if len(Kostentraeger_neu) == index:
            Kostentraeger_neu.append('')
        Kontonummer_neu.append(row['Kontonummer'])
        if not row['Konto_valid']:
            new = f"{Kontonummer_neu[index]}"
            if not row['Marke_valid']:
                new += f"-{Marke_neu[index]}"
            else:
                new += f"-{row['Marke']}"
            if not row['Standort_valid']:
                new += f"-{Standort_neu[index]}"
            else:
                new += f"-{row['Standort']}"
            if not row['Kostenstelle_valid']:
                new += f"-{Kostenstelle_neu[index]}"
            else:
                new += f"-{row['Kostenstelle']}"
            if not row['Absatzkanal_valid']:
                new += f"-{Absatzkanal_neu[index]}"
            else:
                new += f"-{row['Absatzkanal']}"
            if not row['Kostentraeger_valid']:
                new += f"-{Kostentraeger_neu[index]}"
            else:
                new += f"-{row['Kostentraeger']}"
            Konto_neu.append(new)
            # Konto_neu.append(f"{Kontonummer_neu[index]}-{Marke_neu[index]}-{Standort_neu[index]}-{Kostenstelle_neu[index]}-{Absatzkanal_neu[index]}-{Kostentraeger_neu[index]}")

        else:
            Konto_neu.append(row['Konto'])
        # if row['Kontonummer_valid'] == 'true' and row['Marke_valid'] == 'true' and row['Standort_valid'] == 'true' and row['Kostenstelle_valid'] == 'true' and row['Absatzkanal_valid'] == 'true' and row['Kostentraeger_valid'] == 'true' and row['Kostentraeger_valid'] == 'true':
        #    row['Konto_valid'] = 'true'
    valid_salden.insert(2, 'Kontonummer_neu', Kontonummer_neu, True)
    valid_salden.insert(5, 'Marke_neu', Marke_neu, True)
    valid_salden.insert(8, 'Standort_neu', Standort_neu, True)
    valid_salden.insert(11, 'Kostenstelle_neu', Kostenstelle_neu, True)
    valid_salden.insert(14, 'Absatzkanal_neu', Absatzkanal_neu, True)
    valid_salden.insert(17, 'Kostentraeger_neu', Kostentraeger_neu, True)
    valid_salden.insert(20, 'Konto_neu', Konto_neu, True)
    return valid_salden


def konto_alt_neu(salden):
    dat = uebersetzung(salden)
    konto_alt = dat['Konto']
    konto_neu = dat['Konto_neu']
    d = {'Konto': konto_alt, 'Konto_neu': konto_neu}
    df = pd.DataFrame(data=d)
    return df

# filter_liste = [(k, crea_list(v)) for (k, v) in filter.items()]


# print(filter_liste)

filter_csv = pd.read_csv(str(currentDirectory) + '/' + "SKR51_Kostenrechnungsmerkmale.csv", sep='\t', quotechar='"')
filter_csv['Filter_Liste'] = filter_csv['Filter'].apply(crea_list)
print(filter_csv)
# print(filter_csv.values[0][0])

matrix_csv = pd.read_csv(str(currentDirectory) + '/' + "Plausibilitaetsmatrix.csv", sep='\t', dtype={0: str})
# print(matrix_csv.head())

export_csv = pd.read_csv(str(currentDirectory) + '/' + "SKR51_Export.csv", sep=';', dtype={0: str, 1: str, 2: str, 3: str, 4: str, 5: str}, decimal=',')
print(export_csv.head())

uebersetzung_csv = pd.read_csv(str(currentDirectory) + '/' + "Uebersetzung.csv", sep='\t', dtype={0: str, 1: str, 2: str, 3: str, 4: str, 5: str}, decimal=',')
print(uebersetzung_csv.head())

print(uebersetzung(export_csv.to_dict('records')[:5]))
print(konto_alt_neu(export_csv.to_dict('records')[:5]))


@app.route('/skr51_export', methods=['POST', 'GET'])
def skr51_export():
    df = uebersetzung(export_csv.to_dict('records')[:5])
    return df.to_json(indent=2, orient='records')


@app.route('/konto_update', methods=['POST', 'GET'])
def Konto_Update():
    df = konto_alt_neu(export_csv.to_dict('records')[:5])
    return df.to_json(indent=2, orient='records')

# print(dict_list)
# print(check_konto(buchungssalden[0]))

# print(check_buchungssalden(export_csv.to_dict('records')[:5]))
# print(add_validation(export_csv.to_dict('records')[:5]))
