# -*- coding:utf-8 -*-

import codecs
import datetime

from django.contrib.auth.models import User
from django.core.management.base import BaseCommand
from django.db.models import Sum

from accounts.models import RealizedLemma, RealizedPhraseology, RealizedPhraseologyBinding, \
    RealizedSemantics
from dictionary.ajax_user_stats import get_used_bindings
from dictionary.models import Lemma


USERNAME = 'ElaH'
FUNCTION = 'Semantyk'
POS = 'noun'
STARTDATE = datetime.datetime(2010, 1, 1, 00, 00)
ENDDATE = (datetime.datetime.now() -
           datetime.timedelta(days=1)).replace(hour=23, minute=59, second=59)


class Command(BaseCommand):
    args = 'none'

    def handle(self, **options):
        get_payments_data(FUNCTION)


def get_payments_data(function):
    start = STARTDATE.strftime('%Y%m%d')
    end = ENDDATE.strftime('%Y%m%d')
    payments_path = 'data/work_%s_%s_%s_%s-%s.csv' % (USERNAME, FUNCTION, POS, start, end)
    payments_file = codecs.open(payments_path, 'wt', 'utf-8')
    user = User.objects.get(username=USERNAME)

    if function == 'Semantyk':
        work_stats = write_semantic_stats(payments_file, user, POS)
    elif function == 'Supersemantyk':
        work_stats = write_supersemantic_stats(payments_file, user, POS)
    elif function == 'Superfrazeolog':
        work_stats = write_superphraseologic_stats(payments_file, user, POS)
    elif function == 'Frazeolog':
        work_stats = write_phraseologic_stats(payments_file, user, POS)
    elif function == 'Leksykograf':
        work_stats = write_lexicographic_stats(payments_file, user, POS)
    elif function == 'Superleksykograf':
        work_stats = write_superlexicographic_stats(payments_file, user, POS)
    total_earned_cash = work_stats['earned_cash']
    if total_earned_cash > 0.0:
        payments_file.write(u'\n%s\t%.2f\n' % (user.username,
                                               total_earned_cash))
    payments_file.close()


def write_superlexicographic_stats(payments_file, user, pos):
    real_lemmas = RealizedLemma.objects.filter(user_stats__user=user,
                                               lemma__entry_obj__pos__tag=pos,
                                               date__gte=STARTDATE,
                                               date__lte=ENDDATE,
                                               status__type__sym_name='checked',
                                               bonus=False)

    earned_cash = real_lemmas.aggregate(Sum('cash'))['cash__sum']
    if earned_cash == None:
        earned_cash = 0.0

    payments_file.write(u'Sprawdzone:\n')
    for done_lemma in real_lemmas.order_by('date'):
        payments_file.write(u'%s\t%.2f\t%s\n' % (done_lemma.lemma.entry_obj.name,
                                                 done_lemma.cash,
                                                 done_lemma.date.strftime('%Y%m%d')))

    lex_work_stats = {'earned_cash': round(earned_cash, 2)}
    return lex_work_stats


def write_semantic_stats(payments_file, user, pos):

    real_semantics = RealizedSemantics.objects.filter(user_stats__user=user,
                                                      date__gte=STARTDATE,
                                                      date__lte=ENDDATE,
                                                      entry__pos__tag=pos)

    earned_cash = real_semantics.filter(user_stats__user=user).aggregate(Sum('cash'))['cash__sum']
    if earned_cash == None:
        earned_cash = 0.0

    bonus_cash = real_semantics.filter(user_stats__user=user,
                                                  bonus=True).aggregate(Sum('cash'))['cash__sum']
    if bonus_cash == None:
        bonus_cash = 0.0
    prop_frames = real_semantics.filter(user_stats__user=user).aggregate(Sum('prop_frames'))[
        'prop_frames__sum']
    if prop_frames == None:
        prop_frames = 0
    part_prop_frames = real_semantics.filter(user_stats__user=user).aggregate(Sum('part_prop_frames'))[
        'part_prop_frames__sum']
    if part_prop_frames == None:
        part_prop_frames = 0
    wrong_frames = real_semantics.filter(user_stats__user=user).aggregate(Sum('wrong_frames'))[
        'wrong_frames__sum']
    if wrong_frames == None:
        wrong_frames = 0
    corr_frames = real_semantics.filter(user_stats__user=user).aggregate(Sum('corr_frames'))[
        'corr_frames__sum']
    if corr_frames == None:
        corr_frames = 0
    part_corr_frames = real_semantics.filter(user_stats__user=user).aggregate(Sum('part_corr_frames'))[
        'part_corr_frames__sum']
    if part_corr_frames == None:
        part_corr_frames = 0
    ncorr_frames = real_semantics.filter(user_stats__user=user).aggregate(Sum('ncorr_frames'))[
        'ncorr_frames__sum']
    if ncorr_frames == None:
        ncorr_frames = 0
    made_frames = real_semantics.filter(user_stats__user=user).aggregate(Sum('made_frames'))[
        'made_frames__sum']
    if made_frames == None:
        made_frames = 0
    added_connections = real_semantics.filter(user_stats__user=user).aggregate(Sum('added_connections'))[
        'added_connections__sum']
    if added_connections == None:
        added_connections = 0
    efficacy = 0.0
    if prop_frames + wrong_frames > 0:
        efficacy = float(prop_frames) / float(prop_frames + wrong_frames) * 100.0

    payments_file.write(u'Wykonane:\n')
    done_semantics = real_semantics.filter(bonus=False).order_by('date')
    for done_sem in done_semantics:
        done_cash = done_sem.cash
        try:
            done_bonus = real_semantics.get(bonus=True, entry=done_sem.entry).cash
            done_cash += done_bonus
        except RealizedSemantics.DoesNotExist:
            pass
        payments_file.write(u'%s\t%.2f\t%s\n' % (done_sem.entry.name,
                                                 done_cash,
                                                 done_sem.date.strftime('%Y%m%d')))

    sem_work_stats = {'earned_cash': round(earned_cash, 2),
                      'bonus_cash': round(bonus_cash, 2),
                      'prop_frames': prop_frames,
                      'part_prop_frames': part_prop_frames,
                      'wrong_frames': wrong_frames,
                      'corr_frames': corr_frames,
                      'part_corr_frames': part_corr_frames,
                      'checked_frames': ncorr_frames + corr_frames + part_corr_frames,
                      'made_frames': made_frames,
                      'efficacy': round(efficacy, 2),
                      'added_connections': added_connections}
    return sem_work_stats


def write_supersemantic_stats(payments_file, user, pos):

    real_semantics = RealizedSemantics.objects.filter(user_stats__user=user,
                                                      date__gte=STARTDATE,
                                                      date__lte=ENDDATE,
                                                      entry__pos__tag=pos,
                                                      status__type__sym_name='checked_s')

    payments_file.write(u'Wykonane:\n')
    done_semantics = real_semantics.filter(bonus=False).order_by('date')
    for done_sem in done_semantics:
        payments_file.write(u'%s\t%.2f\t%s\n' % (done_sem.entry.name,
                                                 0.0,
                                                 done_sem.date.strftime('%Y%m%d')))

    sem_work_stats = {'earned_cash': 0.0}
    return sem_work_stats


def write_superphraseologic_stats(payments_file, user, pos):
    added_bindings = RealizedPhraseologyBinding.objects.filter(user_stats__user=user,
                                                               date__gte=STARTDATE,
                                                               date__lte=ENDDATE)
    used_bindings = get_used_bindings(added_bindings)

    checked_phraseology = RealizedPhraseology.objects.filter(user_stats__user=user,
                                                             date__gte=STARTDATE,
                                                             date__lte=ENDDATE,
                                                             bonus=False,
                                                             status__type__sym_name='checked_f',
                                                             lemma__entry_obj__pos__tag=pos)

    earned_cash_frames = checked_phraseology.aggregate(Sum('cash'))['cash__sum']
    if earned_cash_frames == None:
        earned_cash_frames = 0.0
    earned_cash_bindings = used_bindings.aggregate(Sum('cash'))['cash__sum']
    if earned_cash_bindings == None:
        earned_cash_bindings = 0.0
    earned_cash = earned_cash_frames + earned_cash_bindings

    phraseologic_empty_frame_value = 1.0
    empty_value = 0.0

    payments_file.write(u'Sprawdzone:\n')
    checked_phraseology = checked_phraseology.order_by('date')
    for checked_phr in checked_phraseology:
        cash = checked_phr.cash
        if cash == 0.0:
            cash = phraseologic_empty_frame_value
            empty_value += phraseologic_empty_frame_value
        payments_file.write(u'%s\t%.2f\t%s\n' % (checked_phr.lemma.entry_obj.name,
                                                 cash,
                                                 checked_phr.date.strftime('%Y%m%d')))
    earned_cash += empty_value

    payments_file.write(u'\n\nDodane powiazania frazeologiczne:\n')
    for binding in used_bindings.order_by('date'):
        payments_file.write(u'%s\t%.2f\t%s\n' % (binding.binded_entry.name,
                                                 binding.cash,
                                                 binding.date.strftime('%Y%m%d')))


    phraseology_work_stats = {'earned_cash': round(earned_cash, 2),
                              'added_bindings': added_bindings.count(),
                              'used_bindings': used_bindings.count()}
    return phraseology_work_stats


def write_phraseologic_stats(payments_file, user, pos):
    added_bindings = RealizedPhraseologyBinding.objects.filter(user_stats__user=user,
                                                               date__gte=STARTDATE,
                                                               date__lte=ENDDATE)
    used_bindings = get_used_bindings(added_bindings)

    checked_and_done_phraseology = RealizedPhraseology.objects.filter(user_stats__user=user,
                                                                      date__gte=STARTDATE,
                                                                      date__lte=ENDDATE,
                                                                      lemma__entry_obj__pos__tag=pos)

    done_phraseology = checked_and_done_phraseology.filter(status__type__sym_name='ready_f',
                                                           bonus=False)

    earned_cash_frames = done_phraseology.aggregate(Sum('cash'))['cash__sum']
    if earned_cash_frames == None:
        earned_cash_frames = 0.0
    earned_cash_bindings = used_bindings.aggregate(Sum('cash'))['cash__sum']
    if earned_cash_bindings == None:
        earned_cash_bindings = 0.0
    earned_cash = earned_cash_frames + earned_cash_bindings

    bonus_cash = checked_and_done_phraseology.filter(bonus=True).aggregate(Sum('cash'))['cash__sum']
    if bonus_cash == None:
        bonus_cash = 0.0
    earned_cash += bonus_cash

    phraseologic_empty_frame_value = 1.0
    empty_value = 0.0

    payments_file.write(u'Wykonane:\n')
    for done_phr in done_phraseology.order_by('date'):
        cash = done_phr.cash
        if cash == 0.0:
            cash = phraseologic_empty_frame_value
            empty_value += phraseologic_empty_frame_value
        try:
            done_bonus = checked_and_done_phraseology.get(bonus=True, lemma__entry_obj=done_phr.lemma.entry_obj).cash
            cash += done_bonus
        except RealizedPhraseology.DoesNotExist:
            pass
        payments_file.write(u'%s\t%.2f\t%s\n' % (done_phr.lemma.entry_obj.name,
                                                 cash,
                                                 done_phr.date.strftime('%Y%m%d')))

    payments_file.write(u'\n\nDodane powiazania frazeologiczne:\n')
    for binding in used_bindings.order_by('date'):
        payments_file.write(u'%s\t%.2f\t%s\n' % (binding.binded_entry.name,
                                                 binding.cash,
                                                 binding.date.strftime('%Y%m%d')))

    earned_cash += empty_value

    phraseology_work_stats = {'earned_cash': round(earned_cash, 2),
                              'added_bindings': added_bindings.count(),
                              'used_bindings': used_bindings.count(),}
    return phraseology_work_stats


def write_lexicographic_stats(payments_file, user, pos):

    real_lemmas = RealizedLemma.objects.filter(user_stats__user=user,
                                               lemma__entry_obj__pos__tag=pos,
                                               date__gte=STARTDATE,
                                               date__lte=ENDDATE)

    earned_cash = real_lemmas.filter(status__type__sym_name='ready').aggregate(Sum('cash'))['cash__sum']
    if earned_cash == None:
        earned_cash = 0.0

    lemmas_to_erase_cash = 0.0
    lemmas_marked_to_erase = Lemma.objects.filter(owner=user,
                                                  old=False,
                                                  status__type__sym_name='erase',
                                                  entry_obj__pos__tag=pos)

    payments_file.write(u'Zaznaczone do usunięcia:\n')
    for lemma in lemmas_marked_to_erase:
        erase_date = lemma.status_history.order_by('-date')[0].date
        if erase_date >= STARTDATE and erase_date <= ENDDATE:
            payments_file.write(u'%s\t%.2f\t%s\n' % (lemma.entry_obj.name,
                                                     1.0,
                                                     erase_date.strftime('%Y%m%d')))
            lemmas_to_erase_cash += 1.0
    earned_cash += lemmas_to_erase_cash

    bonus_cash = real_lemmas.filter(bonus=True).aggregate(Sum('cash'))['cash__sum']
    if bonus_cash == None:
        bonus_cash = 0.0
    earned_cash += bonus_cash

    payments_file.write(u'\n\nWykonane:\n')
    done_lemmas = real_lemmas.filter(bonus=False,
                                     status__type__sym_name='ready').order_by('date')
    for done_lemma in done_lemmas:
        cash = done_lemma.cash
        try:
            bonus = real_lemmas.get(bonus=True, lemma__entry_obj=done_lemma.lemma.entry_obj).cash
            cash += bonus
        except RealizedLemma.DoesNotExist:
            pass
        payments_file.write(u'%s\t%.2f\t%s\n' % (done_lemma.lemma.entry_obj.name,
                                                 cash,
                                                 done_lemma.date.strftime('%Y%m%d')))

    lex_work_stats = {'earned_cash': round(earned_cash, 2),
                      'bonus_cash': round(bonus_cash, 2),
                      'lemmas_to_erase_cash': round(lemmas_to_erase_cash, 2)}
    return lex_work_stats
