
from rest_framework import viewsets
from rest_framework.decorators import action
from django.http import JsonResponse
from django.db.models import F
from django.db import connection
from django_filters.rest_framework import DjangoFilterBackend
from api import models, serializers
from os import getenv
import redis
import json
import logging

# funcion para registrar en mongo
from logger.views import save_log_dispositivo

class DispositivoViewSet(viewsets.ModelViewSet):
    queryset = models.Dispositivo.objects.all()
    serializer_class = serializers.DispositivoSerializer
    filter_backends = [DjangoFilterBackend]
    filterset_fields = ['id_dispositivo', 'id_paradero', 'id_tipo_dispositivo']


    @action(detail=False, methods=['post'])
    def whoami(self, request, pk=None):
        input = json.loads(request.body)
        whoami = input['whoami']

        record = models.Paradero.objects \
            .filter(dispositivo__id_dispositivo=whoami['idDispositivo']) \
            .annotate(nro_paradero=F('id_paradero'), nombre_paradero=F('stop_name')) \
            .first()

        if (record):
            save_log_dispositivo(id_dispositivo=whoami['idDispositivo'], accion_url='whoami')

            return JsonResponse({
                "WhoamiResponse": {
                    "NroParadero": record.nro_paradero,
                    "NombreParadero": record.nombre_paradero,
                    "Status": "OK"
                }
            })

        # retorna json de no existente
        return JsonResponse({
            "WhoamiResponse": {
                "Status": "NOK",
                "errorString": "Dispositivo no identificado"
            }
        })


    @action(detail=False, methods=['post','get'])
    def getInfoDevice(self, request, pk=None):
        input = json.loads(request.body)
        getInfoDevice = input['GetInfoDevice']

        cursor = connection.cursor()
        paradero = models.Paradero.objects \
            .filter(dispositivo__id_dispositivo=getInfoDevice['idDispositivo']) \
            .annotate(nro_paradero=F('id_paradero'), nombre_paradero=F('stop_name')) \
            .first()

        db_host = getenv('DB_REDIS_HOST')
        db_port = getenv('DB_REDIS_PORT')
        r = redis.Redis(host=db_host, port=db_port, decode_responses=True)

        key = f'stop_id:{paradero.nro_paradero}'
        json_trayectos = r.get(key)
        trayectos = []
        if json_trayectos != None:
            trayectos = json.loads(json_trayectos)

        key = f'stop_id:none'
        json_trayectos = r.get(key)
        trayectos_none = []
        if json_trayectos != None:
            trayectos_none = json.loads(json_trayectos)

        # agregar al listado los trayecto en donde no se registro el paradero
        """ 
        json_trayectos = r.get('stop_id:none')
        trayectos_none = []
        if json_trayectos != None:
            trayectos_none = json.loads(json_trayectos)
        
        for trayecto in trayectos_none:
            trayecto['stop_id'] = 'none'
            trayecto['hora_llegada'] = None
            trayectos.append(trayecto)

 """
        lineas = models.Linea.objects.filter(lineaparadero__id_paradero = paradero.id_paradero).order_by('route_short_name')
        detalle_lineas = []
        for linea in lineas:
            llegadas = []

            for trayecto in trayectos:
                id_linea = f"{trayecto['route_id']}-{trayecto['direction_id']}"
                stop_id = trayecto['stop_id']
                patente = trayecto['vehicle_license_plate']
                trayecto['stop_id_alterno'] = None

                if id_linea == linea.id_linea:
                    hora_llegada = trayecto['hora_llegada']
                    distancia_km = None
                    texto_llegada= None

                    # si no trae latitud ni longitud: buscar en trayectos_none por patente
                    # y sobreescribir latitud y longitud
                    if trayecto['latitude'] == 0 and trayecto['longitude'] == 0:
                        for trayecto_none in trayectos_none:
                            if patente == trayecto_none['vehicle_license_plate']:
                                trayecto['longitude'] = trayecto_none['longitude']
                                trayecto['latitude'] = trayecto_none['latitude']
                                trayecto['stop_id_alterno'] = 'none'
                                break

                    if trayecto['latitude'] != 0 and trayecto['longitude'] != 0:
                        trip_id = trayecto['trip_id']
                        velocidad_promedio = 80
                        p_lon = trayecto['longitude']
                        p_lat = trayecto['latitude']

                        sql = "select hora_llegada, distancia_km, texto_llegada from fn_gtfs_calcula_distancia_tiempo_llegada(%s,%s,%s,%s,%s)"
                        cursor.execute(sql, [trip_id, stop_id, velocidad_promedio, p_lon, p_lat])
                        row = cursor.fetchone()

                        """ if patente == 'FDCB32':
                            print(f'SQL: {sql}', flush=True)
                            print(f'params: {[trip_id, stop_id, velocidad_promedio, p_lon, p_lat]}', flush=True)
                            print(f'row: {row}', flush=True) """

                        if row != None:
                            hora_llegada = row[0].strftime('%H:%M:%S')
                            distancia_km = row[1]
                            texto_llegada= row[2]

                    llegadas.append({
                        'patente': trayecto['vehicle_license_plate'],
                        'Planificada': trayecto['hora_llegada'],
                        'Latitud': trayecto['latitude'],
                        'Longitud': trayecto['longitude'],
                        'stop_id_alterno': trayecto['stop_id_alterno'],
                        'EstimadaGPS': hora_llegada,
                        'DistanciaGPS': distancia_km,
                        'textoLlegada' : texto_llegada, 
                        'Mensajelinea': None,
                    })

            llegadas_ordendas = sorted(llegadas, key=lambda x: x['DistanciaGPS'])

            item = {
                'Linea': linea.route_long_name,
                'Descripcion': linea.route_short_name,
                'TipoLocomocion': linea.route_type.descripcion,
                'colorFondo': linea.route_color,
                'colorTexto': linea.route_text_color,
                'Llegadas': llegadas_ordendas
            }
            detalle_lineas.append(item)

        # lineas = {}
        # lineas_agrupadas = {}
        # for t in trayectos:

        #     pk_linea = f'{t["route_id"]}-{t["direction_id"]}'
        #     if pk_linea not in lineas:
        #         lineas[pk_linea] = models.Linea.objects.filter(id_linea=pk_linea).first()

        #     linea = lineas[pk_linea]

        #     if linea == None:
        #         print(pk_linea, flush=True)

        #     if linea != None:
        #         if pk_linea not in lineas_agrupadas:
        #             lineas_agrupadas[pk_linea] = {
        #                 'Linea': linea.route_long_name,
        #                 'Descripcion': linea.route_short_name,
        #                 'TipoLocomocion': linea.route_type.descripcion,
        #                 'colorFondo': linea.route_color,
        #                 'colorTexto': linea.route_text_color,
        #                 'Llegadas': []
        #             }

        #         sql = "select hora_llegada, distancia_km from fn_gtfs_calcula_distancia_tiempo_llegada(%s,%s,%s,%s,%s)"

        #         trip_id = t['trip_id']
        #         paradero_id = t['stop_id']
        #         velocidad_promedio = 30
        #         p_lon = t['longitude']
        #         p_lat = t['latitude']

        #         cursor.execute(sql, [trip_id, paradero_id, velocidad_promedio, p_lon, p_lat])
        #         row = cursor.fetchone()
        #         hora_llegada = None
        #         distancia_km = None
        #         if row != None:
        #             hora_llegada = row[0].strftime('%H:%M:%S')
        #             distancia_km = row[1]

        #         lineas_agrupadas[pk_linea]['Llegadas'].append({
        #             'patente': t['vehicle_license_plate'],
        #             'Planificada': t['hora_llegada'],
        #             'EstimadaGPS': hora_llegada,
        #             'DistanciaGPS': distancia_km,
        #             'Mensajelinea': None,
        #         })


        # detalle_lineas = []
        # for pk_linea in lineas_agrupadas:
        #     detalle_lineas.append(lineas_agrupadas[pk_linea])


        save_log_dispositivo(id_dispositivo=getInfoDevice['idDispositivo'], accion_url='getInfoDevice')
        cursor.close()
        return JsonResponse({
            "GetInfoDeviceResponse": {
                "DetalleLineas": detalle_lineas,
                "MensajeParadero": "No considerar, uso futuro",
                "NroParadero": paradero.nro_paradero,
                "NombreParadero": paradero.nombre_paradero,
                "proto": trayectos,
            }
        })
