import csv
import datetime
import logging
import luigi
import numpy as np
import pandas as pd
import sys

import src.etl.luigi.uade_lib as lib


class Fetch(luigi.Task):
    # - Pedidos
    #     - Id. de pedido
    #     - Cliente
    #     - Fecha de pedido
    logger = logging.getLogger('luigi-interface')

    def run(self):
        # Doesn't work on mac
        # connection = lib.NeptunoDB.connection()
        self.logger.info('==> Reading original csv''s')
        shippings_df = pd.read_csv(
            'input/pedidos.csv')[['Id. de pedido', 'Cliente', 'Fecha de envío']]

        self.logger.info('==> Renaming columns')
        shippings_df = shippings_df.rename(index=str, columns={
                                         'Id. de pedido': 'id',
                                         'Cliente': 'client',
                                         'Fecha de envío': 'date'})

        self.logger.info('==> Writting')
        with self.output().open('w') as out_file:
            shippings_df.to_csv(out_file, index=False)

    def output(self):
        return luigi.LocalTarget('output/luigi/out_shippings.csv')


class Clean(luigi.Task):
    logger = logging.getLogger('luigi-interface')

    def requires(self):
        return Fetch()

    def output(self):
        return luigi.LocalTarget('output/luigi/out_shippings_cleaned.csv')

    def run(self):
        self.logger.info('==> Reading: {}'.format(self.input().path))
        shippings_df = pd.read_csv(self.input().path)

        self.logger.info('==> Build date column')
        shippings_df['date'] = shippings_df['date'].apply(
            lambda orig_date: lib.TransforHelper.date_to_id(orig_date) )

        # Filter null values
        shippings_df['date'].replace('', np.nan, inplace=True)
        shippings_df.dropna(subset=['date'], inplace=True)

        self.logger.info('==> Build clients dictionary')
        clients_dic = {}
        clients = lib.DBRead.get('dim_clients')
        for id, company_name, name, last_name, id_address in clients:
            clients_dic[company_name] = id

        self.logger.info('==> Replacing clients name with id')
        shippings_df['client'] = shippings_df['client'].apply(
            lambda client_name: (
                clients_dic[client_name] if client_name in clients_dic else clients_dic['others']
            ))
        shippings_df = shippings_df.rename(index=str, columns={'client': 'id_client'})

        with self.output().open('w') as out_file:
            shippings_df.to_csv(out_file, index=False)

    def output(self):
        return luigi.LocalTarget('output/luigi/out_shippings_cleaned.csv')


class Insert(luigi.Task):
    table = 'fact_shippings'
    columns = ['id', 'id_client', 'id_date']

    def requires(self):
        return Clean()

    def run(self):
        lib.PgInsert.exec(self.table, self.columns, self.input().path)
        with self.output().open('w') as out_file:
            out_file.write('ok')

    def output(self):
        return luigi.LocalTarget('output/luigi/out_shippings_done_{}.txt'.format(datetime.datetime.now().isoformat()))
