import math

from ressources.acced.production.acced_production_service import _get_config, CONTRAT_DOSE_STACK, \
    CONTRAT_CADENCE_DOSE_STACK, CONTRAT_CADENCE_STACK, State


def get_stack_mean(counter_values):
    dose = sum(filter(lambda s: s > 0,
                      map(lambda d: d['stack_dose_num'], counter_values)))
    stack = sum(filter(lambda s: s > 0,
                       map(lambda d: d['stack_num'], counter_values)))

    picking_stack_time = sum(filter(lambda s: s > 0,
                                    map(lambda d: d['picking_stack_time'], counter_values)))

    threshold_dose = _get_config(property=CONTRAT_DOSE_STACK)
    threshold_cadence_dose = _get_config(property=CONTRAT_CADENCE_DOSE_STACK)
    threshold_cadence = _get_config(property=CONTRAT_CADENCE_STACK)

    mean = round(dose / stack, 2) if stack > 0 else 0
    cadence_dose_mean = round(dose / picking_stack_time, 2) if picking_stack_time > 0 else None
    cadence_mean = round(stack / picking_stack_time, 2) if picking_stack_time > 0 else 0
    state = State.UNKNOW.value if cadence_dose_mean is None or math.isnan(cadence_mean) else State.KO.value

    if state is not State.UNKNOW.value:
        if (mean > threshold_dose and cadence_dose_mean >= threshold_cadence_dose) or \
           (mean <= threshold_dose and cadence_mean >= threshold_cadence):
            state = State.OK.value
        elif ((mean > threshold_dose and cadence_dose_mean >= (0.9 * threshold_cadence_dose)) or
              (mean <= threshold_dose and cadence_mean >= (0.9 * threshold_cadence))):
            state = State.WARNING.value

    return {
        'unit': 'unit.dose.h' if mean > threshold_dose else 'unit.stack.h',
        'mean': cadence_dose_mean if mean > threshold_dose else cadence_mean,
        'cadence_doses': mean,  # dose per pillbox
        'cadence_hour': cadence_mean,  # pillbox per hour
        'dose_hour': cadence_dose_mean,  # dose per hour
        'state': state,
        'threshold': {
            'min': threshold_cadence_dose if mean > threshold_dose else threshold_cadence,
            'unit': 'unit.dose.h' if mean > threshold_dose else 'unit.stack.h',
        }
    } if state != State.UNKNOW.value else None
