#!/usr/bin/python3

# TODO format output

import pandas as pd
import argparse
from datetime import datetime, timedelta

# setup CLI parsing
parser = argparse.ArgumentParser(
    prog='xmpp-expenses-report',
    description='Generate a report from a CSV file generated by the XMPP expense bot.',
    epilog='')

parser.add_argument('-f', '--filename')
parser.add_argument('-n', '--nexp')
parser.add_argument('-l', '--lang')
parser.add_argument('-d', '--days')
args = parser.parse_args()

# localize

sentences = { 'it':
                [f'Ciao, ecco le ultime {args.nexp} spese dal',
                 f'Bilancio',
                 f'Bilancio per ogni utente',
                 f'Uscite',
                 f'Uscite per ogni utente',
                 f'Entrate',
                 f'Entrate per ogni utente',
                 f'Mi dispiace, non ho trovato nessuna spesa per il periodo richiesto'
                 ],
              'en':
                [f'Hi, here\'s the latest {args.nexp} expenses since',
                 f'Total balance',
                 f'Balance for every user',
                 f'Sum of expenses',
                 f'Sum of expenses for every user',
                 f'Sum of incoming',
                 f'Sum of incoming for every user',
                 f'Sorry, I could not find any expense for the given period'
                 ]}


def whole_report(df):
    startDate = df.dt.iloc[-1].date()

    # latest N expenses
    print('{0} {1}:\n'.format(
        sentences[args.lang][0],
        startDate))

    print(
        df[['ID', 'Time', 'Value', 'User', 'Notes']]
        .head(int(args.nexp))   # only print latest args.nexp expenses
        .to_string(index=False))

    # balance
    ntot = df.FloatValue.sum()

    print('\n{0}:\n{1:.2f} euro'.format(
        sentences[args.lang][1],
        ntot))

    usertot = pd.DataFrame(df[['User','FloatValue']].groupby('User', group_keys=True).sum())

    print('\n{0}:'.format(sentences[args.lang][2]))

    for user,value in usertot.iterrows():
        print('{0}: {1:.2f} euro'.format(user,abs(value.values[0])))

    # outgoing
    outgoing = df.loc[df['FloatValue'] < 0].FloatValue.sum()
    userOut = pd.DataFrame(df[['User','FloatValue']].loc[df['FloatValue'] < 0].groupby('User', group_keys=True).sum())

    print('\n{0}:\n{1:.2f} euro'.format(
        sentences[args.lang][3],
        abs(outgoing)))

    if not userOut.empty:
        print('\n{0}:'.format(sentences[args.lang][4]))

        for user,value in userOut.iterrows():
            print('{0}: {1:.2f} euro'.format(user,abs(value.values[0])))

    # incoming
    incoming = df.loc[df['FloatValue'] >= 0].FloatValue.sum()
    userIn = pd.DataFrame(df[['User','FloatValue']].loc[df['FloatValue'] >= 0].groupby('User', group_keys=True).sum())

    print('\n{0}:\n{1:.2f} euro'.format(
        sentences[args.lang][5],
        abs(incoming)))

    if not userIn.empty:
        print('\n{0}:'.format(sentences[args.lang][6]))

        for user,value in userIn.iterrows():
            print('{0}: {1:.2f} euro'.format(user,abs(value.values[0])))

def timestamp_report(df, days):
    startDate = datetime.today() - timedelta(days = days)
    try:
        whole_report(df.loc[(df.dt >= startDate)])
    except IndexError:
        print(sentences[args.lang][-1])

if __name__ == '__main__':
    # load CSV
    input = pd.read_csv(args.filename)
    input['dt'] = pd.to_datetime(input['Time'])
    input['FloatValue'] = input[['Value']].astype(float)

    df = input.sort_values(by='dt', ascending=False)


    if args.days is None:
        whole_report(df)
    else:
        timestamp_report(df, int(args.days))
