from django.views.generic import TemplateView
from users.access_checks import LoginRequiredMixin
from django.utils.translation import ugettext as _
from math import fabs


# like with the panelist history, this central location assesses lab performance
# values. it expects a dictionary with r and A keys and inserts A_ok and r_ok boolean
# key/value pairs
def check_lab_values(lab_perf_dict):
    try:
        r = lab_perf_dict['r']
        A = lab_perf_dict['A']
        lab_perf_dict['A_ok'] = A <= 0.217
        lab_perf_dict['r_ok'] = r <= 0.477
        return lab_perf_dict
    except KeyError:
        return lab_perf_dict  # NOP


# stripped down version to query just for the latest value
def get_current_lab_value():
    from panelhistory.models import LabHistory

    qset = LabHistory.objects.all().order_by('-timestamp').first()  # None if there is no entry at all

    if qset is None or qset.sigma is None or qset.y_ite is None:
        return {}
    else:
        from .models import LABHIST_STUDENT_20, LABHIST_AW_20, LABHIST_MU, SQR2

        r_val = LABHIST_STUDENT_20 * SQR2 * qset.sigma
        dw = qset.y_ite - LABHIST_MU
        a = fabs(dw) + LABHIST_AW_20 * r_val
        lab_perf = {'A': a, 'r': r_val}
        return check_lab_values(lab_perf)


def prepare_lab_history(time_span_key=None):
    from panelhistory.models import LabHistory

    lab_query = LabHistory.objects.all().select_related('team_ite', 'team_ite__sample__cylinder') \
        .order_by('-timestamp')

    if time_span_key == 'r':
        lab_query = list(lab_query)[:20]
    elif time_span_key == 'y':  # last year
        from datetime import timedelta, datetime

        td = timedelta(weeks=52)
        filter_date = datetime.now() - td
        lab_query = lab_query.filter(timestamp__gte=filter_date)

    history_data = list()

    # start at the top of the list...
    for result in lab_query:
        history_data.append(dict())
        # fill the stuff which does not depend on the other values in
        # this calculation window
        history_data[-1]['date'] = result.team_ite.finished_at.date()
        history_data[-1]['ite'] = result.team_ite.result  # team ite of this measurement
        history_data[-1]['measurement'] = result.team_ite.pk  # provide link to measurement

        # link to cylinder
        history_data[-1]['cylinder_pk'] = result.team_ite.sample.cylinder.pk  # ['sample__cylinder__id']
        # show ppm concentration of cylinder
        history_data[-1]['concentration'] = result.team_ite.sample.cylinder.concentration
        history_data[-1]['ppm'] = result.ppm

        # now, from the 20th value and onwards, calculate r and A
        # note that only the 20th and onwards will have sigma/mean
        if result.sigma is not None and result.y_ite is not None:
            history_data[-1]['y_ite'] = result.y_ite
            history_data[-1]['site'] = result.sigma
            history_data[-1]['r'] = result.r_value
            history_data[-1]['dw'] = result.dw_value
            history_data[-1]['A'] = result.a_value
            check_lab_values(history_data[-1])

    return history_data


class LabHistoryView(LoginRequiredMixin, TemplateView):
    # template_name = 'panel_history/lab_history.html'

    def bread(self):
        return [{'url': '#',
                 'label': _('lab performance')}]

    def get_context_data(self, **kwargs):
        ctx = super(LabHistoryView, self).get_context_data(**kwargs)

        from .models import LABHIST_MU, LABHIST_AW_20, LABHIST_STUDENT_20

        glob = {'t_20': LABHIST_STUDENT_20,
                'Aw_20': LABHIST_AW_20,
                'MU': LABHIST_MU}

        ctx.update(glob)

        timespan = self.request.GET.get('timespan', None)

        history_data = prepare_lab_history(timespan)

        ctx['history_data'] = history_data
        return ctx

