
from rest_framework import viewsets
# from rest_framework.response import Response
from rest_framework.decorators import action, api_view
from django_filters.rest_framework import DjangoFilterBackend
from django.db import connection
from .. import models, serializers
from django.http import JsonResponse, HttpResponse
from django.forms.models import model_to_dict
from os import getenv
import redis
import json
import logging


class LineaViewSet(viewsets.ModelViewSet):
    queryset = models.Linea.objects.all()
    serializer_class = serializers.LineaSerializer
    filter_backends = [DjangoFilterBackend]
    filterset_fields = ['id_operador', 'route_short_name', 'route_long_name', 'vigente', 'rollinea__id_rol']

    def list(self, request, pk=None, *args, **kwargs):
        login = request.jwt_info['login']
        usuario = models.Usuario.objects.filter(login=login).first()

        if usuario.superuser != True:
            self.request.GET.rollinea__id_rol = usuario.id_rol.id_rol
            request.GET.rollinea__id_rol = usuario.id_rol.id_rol
            # request.GET.setdefault('rollinea__id_rol',usuario.id_rol)

        return super().list(request, pk, *args, **kwargs)

    @action(detail=False, methods=['get'])
    def proto(self, request, pk=None):
        id_paradero = request.GET['id_paradero']

        query = "SELECT json_data \
                from gtfs_posiciones_json \
                where stop_id = %s"

        with connection.cursor() as cursor:
            cursor.execute(query, [ id_paradero ])
            row = cursor.fetchone()

        return JsonResponse(row[0], safe=False)


    @action(detail=False, methods=['get'])
    def paraderos(self, request, pk=None):
        pk = request.GET['id_linea']

        paraderos = models.Paradero.objects \
            .filter(vigente=True, lineaparadero__id_linea=pk) \
            .values('id_paradero','stop_lat','stop_lon','stop_name') \
            .all()
        return JsonResponse(list(paraderos), safe=False)


    @action(detail=False, methods=['get'])
    def buses(self, request, pk=None):
        pk = request.GET['id_linea']

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

        paraderos = models.Paradero.objects \
            .filter(vigente=True, lineaparadero__id_linea=pk) \
            .values('id_paradero') \
            .all()

        fileproto = r.get('fileproto')
        obj_buses = {}
        array_buses = []
        for p in paraderos:
            key = f'stop_id:{p["id_paradero"]}'
            data = r.get(key)

            if data != None:
                array_trayectos = json.loads(data)
                for trayecto in array_trayectos:
                    key_route = f'{trayecto["route_id"]}-{trayecto["direction_id"]}'
                    if key_route == pk:
                        patente = trayecto["vehicle_license_plate"]
                        if patente not in obj_buses:
                            obj_buses[patente] = {
                                'Patente_vehiculo': trayecto["vehicle_license_plate"],
                                'latitude': trayecto["latitude"],
                                'longitude': trayecto["longitude"],
                                'speed': trayecto["speed"]
                            }
        
        for patente in obj_buses:
            array_buses.append(obj_buses[patente])
        
        return JsonResponse({
            'fileproto': fileproto,
            'buses': array_buses
        }, safe=False)


    @action(detail=False, methods=['get'])
    def buses_proto(self, request, pk=None):
        pk = request.GET['id_linea']

        linea = models.Linea.objects \
            .filter(id_linea=pk) \
            .first()

        logging.error(linea)

        detalle_buses = []
        paraderos = models.Paradero.objects \
            .filter(vigente=True, lineaparadero__id_linea=pk) \
            .values('id_paradero') \
            .all()

        query = "SELECT json_data \
                from gtfs_posiciones_json \
                where stop_id = %s"

        for p in paraderos:
            id_paradero = p['id_paradero']

            with connection.cursor() as cursor:
                cursor.execute(query, [ id_paradero ])
                datajson = cursor.fetchone()

            if datajson != None:
                buses = list(filter(lambda rowjson: rowjson['Descripcion'] == linea.route_short_name, datajson[0]))
                for bus in buses:
                    for llegada in bus['Llegadas']:
                        data_bus = {
                            'patente': llegada['patente'],
                            'estimada_gps': llegada['EstimadaGPS'],
                            'distancia_gps': llegada['DistanciaGPS'],
                        }
                        detalle_buses.append(data_bus)

        return JsonResponse(detalle_buses, safe=False)


    @action(detail=False, methods=['get'])
    def count(self, request, pk=None):

        queryset = models.Linea.objects.all()

        if 'vigente' in request.GET and request.GET['vigente'] == '1':
            queryset = queryset.filter(vigente=True)

        if 'vigente' in request.GET and request.GET['vigente'] == '0':
            queryset = queryset.filter(vigente=False)
        
        return JsonResponse({ 'count': queryset.count() })


    @action(detail=False, methods=['get'])
    def count_buses(self, request, pk=None):

        query = "SELECT \
            l.route_short_name, \
            (select count(distinct vehicle_license_plate) \
                from gtfs_posiciones as gp \
                where (trim(gp.route_id)||'-'||trim(gp.direction_id::varchar)) = l.id_linea \
            ) as count \
            from linea l \
            where \
            (select count(distinct vehicle_license_plate) from gtfs_posiciones as gp where \
            (trim(gp.route_id)||'-'||trim(gp.direction_id::varchar)) = l.id_linea)>0"

        with connection.cursor() as cursor:
            cursor.execute(query)
            result = cursor.fetchall()

        data = []
        for row in result:
            data.append({
                'route_short_name': row[0],
                'count': row[1]
            })
        
        return JsonResponse(data, safe=False)


    @action(detail=False, methods=['get'])
    def count_buses_recorridos(self, request, pk=None):
        query = "select count(distinct vehicle_license_plate) from gtfs_posiciones"

        with connection.cursor() as cursor:
            cursor.execute(query)
            result = cursor.fetchone()

        return JsonResponse({ 'count': result[0] })

