import csv
import datetime
from io import StringIO
from pyramid.view import view_config
import transaction
from brewman.models import DBSession
from brewman.models.master import Employee
from brewman.models.validation_exception import TryCatchFunction
from brewman.models.voucher import Fingerprint

__author__ = 'tanshu'

@view_config(request_method='POST', route_name='api_fingerprint', renderer='json', permission='Authenticated')
@TryCatchFunction
def show_list(request):
    filename = request.POST['uploadedFile'].filename
    input_file = request.POST['uploadedFile'].file
    reader = csv.reader(read_file(input_file), delimiter=";")
    for row in reader:
        add_fingerprint(row)
    transaction.commit()
    return filename


def read_file(input_file):
    input_file.seek(0)
    output = ""
    while 1:
        data = input_file.read(2 << 16)
        if not data:
            break
        output += data.decode('utf-8')
    return StringIO(output)


def add_fingerprint(row):
    try:
        employee_code = int(row[0])
        date = datetime.datetime.strptime(row[3] + ' ' + row[4], '%m/%d/%Y %H:%M')
    except ValueError:
        return
    employee_id = Employee.by_code(employee_code).id
    Fingerprint(employee_id=employee_id, date=date).create()


def get_prints(employee_id, date):
    start_fp = date + datetime.timedelta(hours=7)
    finish_fp = date + datetime.timedelta(hours=7, days=1)
    prints = DBSession.query(Fingerprint).filter(Fingerprint.employee_id == employee_id)\
    .filter(Fingerprint.date >= start_fp).filter(Fingerprint.date < finish_fp).order_by(Fingerprint.date).all()

    last = None
    for i in range(len(prints), 0, -1):
        item = prints[i - 1].date
        if last is not None and last - item < datetime.timedelta(minutes=10):
            prints.remove(prints[i - 1])
        else:
            last = item

    if len(prints) == 0:
        hours = '', ''
    elif len(prints) == 2:
        hours = prints[1].date - prints[0].date
        hours = working_hours(hours)
    elif len(prints) == 4:
        hours = (prints[1].date - prints[0].date) + (prints[3].date - prints[2].date)
        hours = working_hours(hours)
    else:
        hours = 'Error', 'Error'
    return ', '.join([x.date.strftime('%H:%M') for x in prints]) + ' ', hours[0], hours[1]


def working_hours(delta):
    minutes = (delta.seconds // 60) % 60
    minutes = int(5 * round(float(minutes) / 5))
    hours = delta.seconds // 3600
    worked = str(hours).zfill(2) + ':' + str(minutes).zfill(2)
    return worked, delta.seconds >= 60 * 60 * 9 # 9hrs