#!/usr/bin/env python3.7

import codecs
import csv
import logging.config
import os
import shutil
import time

from ftplib import FTP


def setup_logging(log_path):
    # Set up logging
    log_file = os.path.join(log_path,
                            '{}.log'.format(time.strftime("%Y%m%d-%H%M%S")))

    logging.config.dictConfig({
        'version': 1,
        'disable_existing_loggers': False,
        'formatters': {
            'standard': {
                'format': '%(asctime)s [%(levelname)s] %(name)s: %(message)s'
            },
        },
        'handlers': {
            'default': {
                'level': 'NOTSET',
                'class': 'logging.StreamHandler',
                'formatter': 'standard'
            },
            'logfile': {
                'filename': log_file,
                'class': 'logging.FileHandler',
                'formatter': 'standard'
            }
        },
        'loggers': {
            '': {
                'handlers': ['default', 'logfile'],
                'level': 'NOTSET',
                'propagate': True
            }
        }
    })


def get_files_from_ftp(in_path):
    filenames = ["ean.csv"]

    try:
        logging.debug("Retrieving files from Jako...")
        ftp = FTP(host="91.103.115.171", user="12260", passwd="CT12260")

        ftp.cwd("_KUNDE/12260/katalogdaten")

        for filename in filenames:
            full_path = os.path.join(in_path, filename)
            with open(full_path, "wb") as f:
                ftp.retrbinary('RETR ' + filename, f.write, 1024)

        ftp.quit()
    except Exception as ex:
        logging.error(ex)


def parse_currency(value):
    value_numeric = 0.0

    if value:
        try:
            value_us_fmt = value.replace(".", "").replace(",", ".")
            value_numeric = float(value_us_fmt)
        except ValueError as ve:
            logging.error(ve)
            logging.error("could not convert " + value)

    return value_numeric


def convert_jako_inv(in_file, out_file):
    header_read = False
    avail_qty_index = -1
    avail_index = -1
    next_del_index = -1
    price_debitors_index = -1
    price_retail_index = -1
    item_no_index = -1 
    color_code_index = -1

    with codecs.open(in_file, "r", encoding='iso-8859-1') as f, codecs.open(
            out_file, "w", encoding='utf-8') as of:
        reader = csv.reader(f, delimiter=';')
        writer = csv.writer(of, delimiter=';')

        for row in reader:
            if header_read:
                item_no = row[item_no_index]
                color_code = row[color_code_index]
                if len(row[price_debitors_index].strip()) == 0:
                    row[price_debitors_index] = "0,00"
                    price_raw = 0
                else:
                    price_raw = row[price_debitors_index]

                price_retail_raw = row[price_retail_index]

                qty = 0 if not row[avail_qty_index] else int(
                    row[avail_qty_index])

                if qty == 0:
                    continue
                row.append(str(qty))

                row.append("Jako")
                row.append("2")
                row.append("0")
                row.append("1,70")
                row.append("2,45")

                disc_factor = 1.0
                row.append(
                    str(round(parse_currency(price_raw) * disc_factor,
                              2)).replace(".", ","))
                retail_parsed = parse_currency(price_retail_raw)
                if retail_parsed < 0.01:
                    row.append("200,00")
                else:
                    row.append(
                        str(round(retail_parsed + 2.92, 2)).replace(".", ","))
                new_item_no = "JA{}_{}".format(item_no,color_code)
                row.append(new_item_no)
            else:
                header_read = True

                # EAN;Availability General;Availability Quantity;
                # Next Delivery Date;HEK;Price Individual;UVP;
                # UVP Current;Item No.;Item Description1;Item Description2;
                # Variant Code;Color Code;Color Description;Size Code;
                # Size Description;Jako;O;P;Q;Net Weight;Path;Image;Fedas;
                if "Availability Quantity" in row:  # Column I
                    avail_qty_index = row.index("Availability Quantity")

                if "Availability General" in row:  # Column N
                    avail_index = row.index("Availability General")

                if "Next Delivery Date" in row:  # Column M
                    next_del_index = row.index("Next Delivery Date")

                if "Price Individual" in row:  # Column K
                    price_debitors_index = row.index("Price Individual")

                if "UVP" in row:  # Column L
                    price_retail_index = row.index("UVP")

                if "Item No." in row:
                    item_no_index = row.index("Item No.")

                if "Color Code" in row:
                    color_code_index = row.index("Color Code")

                if avail_qty_index < 0 or avail_index < 0 or next_del_index < 0  \
                        or price_debitors_index < 0 or price_retail_index < 0:
                    raise Exception("Could not find needed columns")

                row.append("Bestand_Neu")
                row.append("SSW_1")
                row.append("SSW_2")
                row.append("SSW_3")
                row.append("SSW_4")
                row.append("SSW_5")
                row.append("EK_Sonderpreis")
                row.append("Preis Endkunden_2")
                row.append("ItemNo")

            writer.writerow(row)


def process(data_root):
    path_in = os.path.join(data_root, "in")
    path_out = os.path.join(data_root, "out")
    path_proc = os.path.join(data_root, "processed")
    path_err = os.path.join(data_root, "error")
    path_log = os.path.join(data_root, "log")

    setup_logging(path_log)

    get_files_from_ftp(path_in)

    files = os.listdir(path_in)
    num_files = len(files)

    logging.debug("Found {0} files...".format(num_files))

    if num_files == 0:
        return

    for f in files:
        in_file = os.path.join(path_in, f)
        out_file_name = 'jako_HK.csv'
        out_file = os.path.join(path_out, out_file_name)
        proc_file = os.path.join(path_proc, f)
        err_file = os.path.join(path_err, f)

        logging.debug("Calculating inventory for {0}...".format(in_file))

        if os.path.isfile(in_file):
            try:
                logging.debug("Converting {0} to {1}...".format(
                    in_file, out_file))
                convert_jako_inv(in_file, out_file)
                shutil.move(in_file, proc_file)
            except Exception as e:
                logging.error(e)

                try:
                    shutil.move(in_file, err_file)
                    os.remove(out_file)
                except Exception as e:
                    logging.error(e)


def main():
    if os.path.exists(r"/ftproot/"):
        data_root = r"/ftproot/"
    elif os.path.exists(r"/home/holger/git/bitbucket/thelen/data/"):
        data_root = r"/home/holger/git/bitbucket/thelen/data/"
    else:
        print(
            "Unknown environment. Please set data_root to data folder location. Aborting."
        )
        return

    project_data_root = os.path.join(data_root, "Matching_Jako_Bestand")

    process(project_data_root)

    print("Done.")


if __name__ == "__main__":
    main()
