from django.shortcuts import render
from django.http import JsonResponse
import datetime
#import numpy as np
import time

#from .firmware.run import ITO_class
#from .firmware.endpoints.motor import move_up
#from .Modbus.ito_modbus import ModbusAPI

#Plc_qlo = ModbusAPI()
#ITO = ITO_class()

def calibrate(request):
    M_in = ITO.light_sensors.sense()
    M_in = [x if x>0.25 else 0.25 for x in M_in]
    ITO.corr_fact = np.max(M_in) / M_in
    return JsonResponse({'corr_factors': ITO.corr_fact.tolist()})

def calibrate_lasers(request):
    values = ITO.get_sensors_meas()
    min_value = np.min(np.asarray(values))
    argmin = np.argmin(np.asarray(values))
    return JsonResponse({'min_value': str(min_value), 'argmin': str(argmin)})

def reset_lasers(request):
    ITO.corr_fact = [1, 1, 1]
    return JsonResponse({'corr_fact': ITO.corr_fact})

def current_state(request):
    return JsonResponse({'state':ITO.current_state})

def get_elapsed_time(request):
    if ITO.start_time is None:
        s, m, h, t = 0, 0, 0, 0
    else:
        t = int(time.perf_counter() - ITO.start_time)
        h = int(t // 3600)
        m = int((t % 3600) // 60)
        s = int((t % 3600) % 60)
    return JsonResponse({'s': s, 'm': m, 'h': h, 't': t})

def get_height(request):
    return JsonResponse({'height': ITO.puente.height})

def getLasers(request):
    value = ITO.get_sensors_meas()
    lasers = {
        "laser1": value[0],
        "laser2": value[1],
        "laser3": value[2]
    }
    return JsonResponse(lasers)

def get_status(request):
    # Retorna True si el experimento ya comenzó y False si no.
    return JsonResponse({"status": ITO.current_state})

def get_temp(request):
    temp = ITO.metadata['temperatura'] if 'temperatura' in ITO.metadata.keys() else 0
    return JsonResponse({'temp': temp})

def llenar_probeta(request):
    cantidad = request.GET.get("cantidad")
    ITO.bombas.Activar_bomba(ITO.bombas.id_llenado, int(cantidad))
    return JsonResponse({'cantidad': cantidad})

def detener_llenado(request):
    ITO.bombas.Detener_bomba(ITO.bombas.id_llenado)
    return JsonResponse({})

def vaciar_probeta(request):
    cantidad = request.GET.get("cantidad")
    ITO.bombas.Activar_bomba(ITO.bombas.id_vaciado, cantidad)
    return JsonResponse({'cantidad': cantidad})

def imprimir_config(request):
    cantidad = request.GET.get("cantidad")
    ITO.bombas.Imprimir_configuracion(cantidad=int(cantidad))
    return JsonResponse({})

def detener_vaciado(request):
    ITO.bombas.Detener_bomba(ITO.bombas.id_vaciado)
    return JsonResponse({})

def meas_bulk_single(request):
    n_meas = 550
    M = []
    for _ in range(n_meas):
        M.append(ITO.light_sensors.sense_bulk_single())
    return JsonResponse({   'unfiltered': M,
                            'filtered': '',
                            'times_unfilt': '',
                            'times_filt': ''})

def meas_filt(request):
    n_meas = 50
    M, N, T_meas, T_filt = [], [], [], []
    for _ in range(n_meas):
        m, n, t0, t1 = ITO.light_sensors.sense_bulk()
        M.append(m)
        N.append(n)
        T_meas.append(t0)
        T_filt.append(t1)
    return JsonResponse({   'unfiltered': M,
                            'filtered': N,
                            'times_unfilt': T_meas,
                            'times_filt': T_filt})

def meas_motor_time(request):
    ITO.set_height(0)
    T = []
    l = 0.5
    for _ in range(9):
        t_in = time.perf_counter()
        ITO.set_height(ITO.puente.height + l)
        T.append(time.perf_counter()-t_in)
        l*=2
    return JsonResponse({'time': T})

def meas_single(request):
    M, T = ITO.light_sensors.sense_single()
    tt = np.asarray(T)
    print(np.min(tt), np.average(tt), np.max(tt))
    return JsonResponse({"time": T, "meas": M})

def meas_thru(request):
    ITO.set_height(ITO.max_height)
    laser1, laser2, laser3, H = [], [], [], []
    #reset_lasers(request)
    while (ITO.puente.height > 0):
        #ITO.corr_fact = [1 / ITO.light_sensors.chan0.voltage,
        #                 1 / ITO.light_sensors.chan1.voltage,
        #                 1 / ITO.light_sensors.chan2.voltage]
        x = ITO.get_sensors_meas()
        laser1.append(x[0])
        laser2.append(x[1])
        laser3.append(x[2])
        H.append(ITO.puente.height)
        ITO.set_height(ITO.puente.height - ITO.dh)
        time.sleep(0.05)
    return JsonResponse({'height': H,
            'laser1': laser1,
            'laser2': laser2,
            'laser3': laser3})

def off_laser(request):
    try:
        laserNum = int(request.GET.get("laser"))
    except:#Esto transforma las entradas desde el HTML
        laserNum = int(request.GET.get("laser")[5])
        laserNum -= 1
    if request.GET.get("laser"):
        ITO.lasers[laserNum].turn_laser_off()
    return JsonResponse({'laser': laserNum})

def on_laser(request):
    try:
        laserNum = int(request.GET.get("laser"))
    except:#Esto transforma las entradas desde el HTML
        laserNum = int(request.GET.get("laser")[5])
        laserNum -=1
    if request.GET.get("laser"):
        ITO.lasers[laserNum].turn_laser_on()
    return JsonResponse({'laser': laserNum})

def set_height(request):
    newHeightBridge = request.GET.get("h")
    if request.GET.get("h"):
        ITO.puente.Auto_movimiento(int(newHeightBridge))
    return JsonResponse({})

def set_laser_frequency(request):
    laser = request.GET.get("l")
    freq = request.GET.get("f")
    if request.GET.get("l") and request.GET.get("f"):
        laser = int(laser)
        freq = int(freq)
        if laser in [0, 1, 2]:
            old_freq = ITO.lasers_frequencies[laser]
            ITO.lasers[laser].laser.pin.frequency = freq
            ITO.lasers_frequencies[laser] = freq
        else:
            old_freq = ''
    else:
        old_freq = ''
        freq = ''
    return JsonResponse({   "old_freq": old_freq,
                            "new_freq": freq})

def set_laser_value(request):
    laser = request.GET.get("l")
    value = request.GET.get("v")
    if request.GET.get("l") and request.GET.get("v"):
        laser = int(laser)
        value = float(value)
        if laser in [0, 1, 2]:
            ITO.lasers[laser].laser.value = value
    return JsonResponse({   "laser1.value": ITO.lasers[0].laser.value,
                            "laser2.value": ITO.lasers[1].laser.value,
                            "laser3.value": ITO.lasers[2].laser.value})

def set_umbral(request):
    newUmbral = request.GET.get("umbral")
    ITO.ajustar_umbral(int(newUmbral))
    return JsonResponse({})

def start_exp_api(request):
    metadata = {'operador': 'API',
                'experimento': 'exp_API',
                'alturaInicial': 0,
                'alturaMaxima': 300,
                'temperatura': 0,
                'duracion': datetime.timedelta(0, 0, 0),
                'horas': 0,
                'minutos': 0,
                'segundos': 0,
                'comentarios': '',
                }
    ITO.start_exp(metadata)
    return JsonResponse({})

def start_exp(request):
    metadata = {'operador': request.GET.get('operador'),
                'experimento': request.GET.get('experimento'),
                'alturaInicial': 250,
                'alturaMaxima': 300,
                'temperatura': 0,#request.GET.get('temperatura'),
                'horas': 0,
                'minutos': 0,
                'segundos': 0,
                'comentarios': request.GET.get('comentarios'),
                }
    import requests as rq
    ITO.preparar_medicion(metadata)
    #rq.get("http://localhost/calibrate/")
    ITO.start_exp(metadata)
    return JsonResponse({})

def stop_exp_vito(request):
    ITO.stop_exp('Experimento detenido por usuario.')
    if ITO.current_exp_db is not None:
        return JsonResponse({'id':ITO.current_exp_db.id})
    else:
        return JsonResponse({'id':0})

def stop_exp_genko(request):
    ITO.stop_exp('Experimento detenido por genko.')
    return JsonResponse({})

def parada_emergencia(request):
    ITO.stop_exp('Experimento detenido por parada de emergencia')
    return JsonResponse({})

def support(request):
    return render(request, 'support/support.html')

def Temps(request):
    from Main.firmware.endpoints import hardware
    return JsonResponse(hardware.hardware_get_status(),safe=False)

def estado_modulos(request):
    return JsonResponse(ITO.estado_modulos())