from django.http import JsonResponse
from django.shortcuts import render
from rest_framework.viewsets import ModelViewSet
from rest_framework.permissions import IsAuthenticated
from rest_framework.response import Response
from rest_framework.views import APIView
from rest_framework.permissions import IsAuthenticated
from rest_framework.decorators import api_view
from django.core import serializers
from django.db.models import Sum

from .serializers import (
    ProductoresSerializer, CultivosSerializer, RecursosHidricosSerializer,
    SueloSerializer, ResiduosSerializer, CertificacionesSerializer,
    ComercializacionSerializer, TrazabilidadSerializer, EnergiaSerializer, TrabajadoresSerializer
)
from .models import (
    Productores, Cultivos, RecursosHidricos, Suelo,
    Residuos, Certificaciones, Comercializacion, Trazabilidad, Energia, Trabajadores
)

# Vista para Productores
class ProductoresView(ModelViewSet):
    serializer_class = ProductoresSerializer
    queryset = Productores.objects.all()
    permission_classes = (IsAuthenticated,)

# Vista para Cultivos
class CultivosView(ModelViewSet):
    serializer_class = CultivosSerializer
    queryset = Cultivos.objects.all()
    permission_classes = (IsAuthenticated,)

# Vista para Recursos Hídricos
class RecursosHidricosView(ModelViewSet):
    serializer_class = RecursosHidricosSerializer
    queryset = RecursosHidricos.objects.all()
    permission_classes = (IsAuthenticated,)

# Vista para Suelo
class SueloView(ModelViewSet):
    serializer_class = SueloSerializer
    queryset = Suelo.objects.all()
    permission_classes = (IsAuthenticated,)

# Vista para Residuos
class ResiduosView(ModelViewSet):
    serializer_class = ResiduosSerializer
    queryset = Residuos.objects.all()
    permission_classes = (IsAuthenticated,)

# Vista para Certificaciones
class CertificacionesView(ModelViewSet):
    serializer_class = CertificacionesSerializer
    queryset = Certificaciones.objects.all()
    permission_classes = (IsAuthenticated,)

# Vista para Comercialización
class ComercializacionView(ModelViewSet):
    serializer_class = ComercializacionSerializer
    queryset = Comercializacion.objects.all()
    permission_classes = (IsAuthenticated,)

# Vista para Trazabilidad
class TrazabilidadView(ModelViewSet):
    serializer_class = TrazabilidadSerializer
    queryset = Trazabilidad.objects.all()
    permission_classes = (IsAuthenticated,)

# Vista para Energía
class EnergiaView(ModelViewSet):
    serializer_class = EnergiaSerializer
    queryset = Energia.objects.all()
    permission_classes = (IsAuthenticated,)

#Vista para Trabajadores    
class TrabajadoresView(ModelViewSet):
    serializer_class = TrabajadoresSerializer
    queryset = Trabajadores.objects.all()
    permission_classes = (IsAuthenticated,)
    

# Using function-based view
@api_view(['GET'])
def custom_endpoint(request):
    # Your custom logic here
    SomeModel_json = serializers.serialize("json", Productores.objects.all())
    data = {
        'productores': SomeModel_json,
        'message': 'Hello, this is a custom endpoint!',
        'user': request.user.username  # Example: access user data
    }
    return Response(data)

# Using class-based view
class CustomEndpointView(APIView):

    def get(self, request):
        # Your custom logic here
        data = {
            'message': 'Hello from the class-based custom endpoint!',
            'user': request.user.username  # Example: access user data
        }
        return Response(data)
    
# Using function-based view
@api_view(['GET'])
def get_by_prod_id(request, prod_id):

    try:
        # item = Productores.objects.get(id=prod_id)
        # Trabajadores.objects.filter(productor=prod_id).count()

        response = {
            'panels': {
                'productor_por_tipo': {
                    'juridica': Productores.objects.filter(tipo_empresa='juridica').count(),
                    'natural': Productores.objects.filter(tipo_empresa='natural').count()
                },
                'productores_por_sexo': {
                    'total': Trabajadores.objects.filter(productor=prod_id).aggregate(total=Sum('total_trabajadores'))['total'],
                    'mujeres': Trabajadores.objects.filter(productor=prod_id).aggregate(total=Sum('mujeres_trabajadoras'))['total']
                }
            }
        }
        return JsonResponse(response) # Returns a single JSON object
    except Productores.DoesNotExist:
        return Response({'error': 'Item not found'}, status=404)
    # OOOOJO QUE ESTA CONSULTA FUNCIONA
# @api_view(['GET'])
# def obtener_datos_productor(request, prod_id):
#     try:
#         # Realiza la consulta al productor específico usando `prod_id`
#         productor = Productores.objects.prefetch_related(
#             'trabajadores_set',
#             'cultivos',
#             'cultivos__recursoshidricos_set',    # Prefetch recursos hídricos a través de cultivos
#             'cultivos__suelo_set',               # Prefetch suelo a través de cultivos
#             'cultivos__residuos_set',            # Prefetch residuos a través de cultivos
#             'cultivos__certificaciones_set',     # Prefetch certificaciones a través de cultivos
#             'cultivos__comercializacion_set',    # Prefetch comercialización a través de cultivos
#             'cultivos__trazabilidad_set',        # Prefetch trazabilidad a través de cultivos
#             'energia_set'                        # Prefetch energía (directamente relacionado)
#         ).get(id=prod_id)

#         # Datos generales del productor
#         datos_productor = {
#             'tipo_empresa': productor.tipo_empresa,
#             'tamano_empresa': productor.tamano_empresa,
#             'region': productor.region,
#             'comuna': productor.comuna,
#             'ubicacion_predio': productor.ubicacion_predio,
#         }

#         # Datos de trabajadores
#         datos_trabajadores = {
#             'total': productor.trabajadores_set.aggregate(total=Sum('total_trabajadores'))['total'],
#             'mujeres': productor.trabajadores_set.aggregate(total=Sum('mujeres_trabajadoras'))['total'],
#             'postgrado': productor.trabajadores_set.aggregate(total=Sum('trabajadores_postgrado'))['total'],
#             'pregrado': productor.trabajadores_set.aggregate(total=Sum('trabajadores_pregrado'))['total'],
#             'tecnico': productor.trabajadores_set.aggregate(total=Sum('trabajadores_tecnico'))['total'],
#             'media': productor.trabajadores_set.aggregate(total=Sum('trabajadores_educacion_media'))['total'],
#             'basica': productor.trabajadores_set.aggregate(total=Sum('trabajadores_educacion_basica'))['total'],
#         }

#         # Datos de cultivos y sus relaciones
#         datos_cultivos = []
#         for cultivo in productor.cultivos.all():  # Usa el `related_name` adecuado para la relación con `Cultivos`
#             datos_cultivo = {
#                 'producto': cultivo.producto,
#                 'produccion_anual': cultivo.produccion_anual,
#                 'recursos_hidricos': [
#                     {
#                         'fuente_agua': recurso.fuente_agua,
#                         'consumo_anual_agua': recurso.consumo_anual_agua
#                     } for recurso in cultivo.recursoshidricos_set.all()
#                 ],
#                 'suelo': [
#                     {
#                         'superficie_cultivada': suelo.superficie_cultivada,
#                         'cantidad_arboles': suelo.cantidad_arboles
#                     } for suelo in cultivo.suelo_set.all()
#                 ],
#                 'residuos': [
#                     {
#                         'cantidad_residuos_organicos_anual': residuo.cantidad_residuos_organicos_anual,
#                         'realiza_gestion_residuos_organicos': residuo.realiza_gestion_residuos_organicos
#                     } for residuo in cultivo.residuos_set.all()
#                 ],
#                 'certificaciones': [
#                     {
#                         'cert_act_sellos_reportes_producciones': certificacion.cert_act_sellos_reportes_producciones
#                     } for certificacion in cultivo.certificaciones_set.all()
#                 ],
#                 'comercializacion': [
#                     {
#                         'participacion_de_emp_en_sector_agricola': comercializacion.participacion_de_emp_en_sector_agricola
#                     } for comercializacion in cultivo.comercializacion_set.all()
#                 ],
#                 'trazabilidad': [
#                     {
#                         'realiza_trazabilidad': trazabilidad.realiza_trazabilidad
#                     } for trazabilidad in cultivo.trazabilidad_set.all()
#                 ]
#             }
#             datos_cultivos.append(datos_cultivo)

#         # Datos de energía
#         datos_energia = [
#             {
#                 'registro_consumo_energia': energia.registro_consumo_energia,
#                 'consumo_anual_energia_kw': energia.consumo_anual_energia_kw
#             } for energia in productor.energia_set.all()
#         ]

#         response_data = {
#             'productor': datos_productor,
#             'trabajadores': datos_trabajadores,
#             'cultivos': datos_cultivos,
#             'energia': datos_energia
#         }

#         return JsonResponse(response_data)
#     except Productores.DoesNotExist:
#         return JsonResponse({'error': 'Productor no encontrado'}, status=404)
################

from django.db.models import Sum, Max
from django.http import JsonResponse
from rest_framework.decorators import api_view

from django.http import JsonResponse
from django.shortcuts import render
from rest_framework.viewsets import ModelViewSet
from rest_framework.permissions import IsAuthenticated
from rest_framework.response import Response
from rest_framework.views import APIView
from rest_framework.permissions import IsAuthenticated
from rest_framework.decorators import api_view
from django.core import serializers
from django.db.models import Sum

from .serializers import (
    ProductoresSerializer, CultivosSerializer, RecursosHidricosSerializer,
    SueloSerializer, ResiduosSerializer, CertificacionesSerializer,
    ComercializacionSerializer, TrazabilidadSerializer, EnergiaSerializer, TrabajadoresSerializer
)
from .models import (
    Productores, Cultivos, RecursosHidricos, Suelo,
    Residuos, Certificaciones, Comercializacion, Trazabilidad, Energia, Trabajadores
)

# Vista para Productores
class ProductoresView(ModelViewSet):
    serializer_class = ProductoresSerializer
    queryset = Productores.objects.all()
    permission_classes = (IsAuthenticated,)

# Vista para Cultivos
class CultivosView(ModelViewSet):
    serializer_class = CultivosSerializer
    queryset = Cultivos.objects.all()
    permission_classes = (IsAuthenticated,)

# Vista para Recursos Hídricos
class RecursosHidricosView(ModelViewSet):
    serializer_class = RecursosHidricosSerializer
    queryset = RecursosHidricos.objects.all()
    permission_classes = (IsAuthenticated,)

# Vista para Suelo
class SueloView(ModelViewSet):
    serializer_class = SueloSerializer
    queryset = Suelo.objects.all()
    permission_classes = (IsAuthenticated,)

# Vista para Residuos
class ResiduosView(ModelViewSet):
    serializer_class = ResiduosSerializer
    queryset = Residuos.objects.all()
    permission_classes = (IsAuthenticated,)

# Vista para Certificaciones
class CertificacionesView(ModelViewSet):
    serializer_class = CertificacionesSerializer
    queryset = Certificaciones.objects.all()
    permission_classes = (IsAuthenticated,)

# Vista para Comercialización
class ComercializacionView(ModelViewSet):
    serializer_class = ComercializacionSerializer
    queryset = Comercializacion.objects.all()
    permission_classes = (IsAuthenticated,)

# Vista para Trazabilidad
class TrazabilidadView(ModelViewSet):
    serializer_class = TrazabilidadSerializer
    queryset = Trazabilidad.objects.all()
    permission_classes = (IsAuthenticated,)

# Vista para Energía
class EnergiaView(ModelViewSet):
    serializer_class = EnergiaSerializer
    queryset = Energia.objects.all()
    permission_classes = (IsAuthenticated,)

#Vista para Trabajadores    
class TrabajadoresView(ModelViewSet):
    serializer_class = TrabajadoresSerializer
    queryset = Trabajadores.objects.all()
    permission_classes = (IsAuthenticated,)
    

# Using function-based view
@api_view(['GET'])
def custom_endpoint(request):
    # Your custom logic here
    SomeModel_json = serializers.serialize("json", Productores.objects.all())
    data = {
        'productores': SomeModel_json,
        'message': 'Hello, this is a custom endpoint!',
        'user': request.user.username  # Example: access user data
    }
    return Response(data)

# Using class-based view
class CustomEndpointView(APIView):

    def get(self, request):
        # Your custom logic here
        data = {
            'message': 'Hello from the class-based custom endpoint!',
            'user': request.user.username  # Example: access user data
        }
        return Response(data)
    
# Using function-based view
@api_view(['GET'])
def get_by_prod_id(request, prod_id):

    try:
        # item = Productores.objects.get(id=prod_id)
        # Trabajadores.objects.filter(productor=prod_id).count()

        response = {
            'panels': {
                'productor_por_tipo': {
                    'juridica': Productores.objects.filter(tipo_empresa='juridica').count(),
                    'natural': Productores.objects.filter(tipo_empresa='natural').count()
                },
                'productores_por_sexo': {
                    'total': Trabajadores.objects.filter(productor=prod_id).aggregate(total=Sum('total_trabajadores'))['total'],
                    'mujeres': Trabajadores.objects.filter(productor=prod_id).aggregate(total=Sum('mujeres_trabajadoras'))['total']
                }
            }
        }
        return JsonResponse(response) # Returns a single JSON object
    except Productores.DoesNotExist:
        return Response({'error': 'Item not found'}, status=404)
    # OOOOJO QUE ESTA CONSULTA FUNCIONA
# @api_view(['GET'])
# def obtener_datos_productor(request, prod_id):
#     try:
#         # Realiza la consulta al productor específico usando `prod_id`
#         productor = Productores.objects.prefetch_related(
#             'trabajadores_set',
#             'cultivos',
#             'cultivos__recursoshidricos_set',    # Prefetch recursos hídricos a través de cultivos
#             'cultivos__suelo_set',               # Prefetch suelo a través de cultivos
#             'cultivos__residuos_set',            # Prefetch residuos a través de cultivos
#             'cultivos__certificaciones_set',     # Prefetch certificaciones a través de cultivos
#             'cultivos__comercializacion_set',    # Prefetch comercialización a través de cultivos
#             'cultivos__trazabilidad_set',        # Prefetch trazabilidad a través de cultivos
#             'energia_set'                        # Prefetch energía (directamente relacionado)
#         ).get(id=prod_id)

#         # Datos generales del productor
#         datos_productor = {
#             'tipo_empresa': productor.tipo_empresa,
#             'tamano_empresa': productor.tamano_empresa,
#             'region': productor.region,
#             'comuna': productor.comuna,
#             'ubicacion_predio': productor.ubicacion_predio,
#         }

#         # Datos de trabajadores
#         datos_trabajadores = {
#             'total': productor.trabajadores_set.aggregate(total=Sum('total_trabajadores'))['total'],
#             'mujeres': productor.trabajadores_set.aggregate(total=Sum('mujeres_trabajadoras'))['total'],
#             'postgrado': productor.trabajadores_set.aggregate(total=Sum('trabajadores_postgrado'))['total'],
#             'pregrado': productor.trabajadores_set.aggregate(total=Sum('trabajadores_pregrado'))['total'],
#             'tecnico': productor.trabajadores_set.aggregate(total=Sum('trabajadores_tecnico'))['total'],
#             'media': productor.trabajadores_set.aggregate(total=Sum('trabajadores_educacion_media'))['total'],
#             'basica': productor.trabajadores_set.aggregate(total=Sum('trabajadores_educacion_basica'))['total'],
#         }

#         # Datos de cultivos y sus relaciones
#         datos_cultivos = []
#         for cultivo in productor.cultivos.all():  # Usa el `related_name` adecuado para la relación con `Cultivos`
#             datos_cultivo = {
#                 'producto': cultivo.producto,
#                 'produccion_anual': cultivo.produccion_anual,
#                 'recursos_hidricos': [
#                     {
#                         'fuente_agua': recurso.fuente_agua,
#                         'consumo_anual_agua': recurso.consumo_anual_agua
#                     } for recurso in cultivo.recursoshidricos_set.all()
#                 ],
#                 'suelo': [
#                     {
#                         'superficie_cultivada': suelo.superficie_cultivada,
#                         'cantidad_arboles': suelo.cantidad_arboles
#                     } for suelo in cultivo.suelo_set.all()
#                 ],
#                 'residuos': [
#                     {
#                         'cantidad_residuos_organicos_anual': residuo.cantidad_residuos_organicos_anual,
#                         'realiza_gestion_residuos_organicos': residuo.realiza_gestion_residuos_organicos
#                     } for residuo in cultivo.residuos_set.all()
#                 ],
#                 'certificaciones': [
#                     {
#                         'cert_act_sellos_reportes_producciones': certificacion.cert_act_sellos_reportes_producciones
#                     } for certificacion in cultivo.certificaciones_set.all()
#                 ],
#                 'comercializacion': [
#                     {
#                         'participacion_de_emp_en_sector_agricola': comercializacion.participacion_de_emp_en_sector_agricola
#                     } for comercializacion in cultivo.comercializacion_set.all()
#                 ],
#                 'trazabilidad': [
#                     {
#                         'realiza_trazabilidad': trazabilidad.realiza_trazabilidad
#                     } for trazabilidad in cultivo.trazabilidad_set.all()
#                 ]
#             }
#             datos_cultivos.append(datos_cultivo)

#         # Datos de energía
#         datos_energia = [
#             {
#                 'registro_consumo_energia': energia.registro_consumo_energia,
#                 'consumo_anual_energia_kw': energia.consumo_anual_energia_kw
#             } for energia in productor.energia_set.all()
#         ]

#         response_data = {
#             'productor': datos_productor,
#             'trabajadores': datos_trabajadores,
#             'cultivos': datos_cultivos,
#             'energia': datos_energia
#         }

#         return JsonResponse(response_data)
#     except Productores.DoesNotExist:
#         return JsonResponse({'error': 'Productor no encontrado'}, status=404)
################

from django.db.models import Sum, Max
from django.http import JsonResponse
from rest_framework.decorators import api_view

@api_view(['GET'])
def obtener_datos_productor(request, prod_id):
    try:
        # Prefetch related data for optimization
        productor = Productores.objects.prefetch_related(
            'trabajadores_set',
            'cultivos',
            'cultivos__certificaciones_set',
            'cultivos__comercializacion_set',
            'cultivos__recursoshidricos_set',
            'cultivos__residuos_set',
            'cultivos__trazabilidad_set'
        ).get(id=prod_id)

        # Find the crop with the highest annual production
        cultivo_mayor_produccion = productor.cultivos.aggregate(
            max_produccion=Max('produccion_anual')
        )
        cultivo_mayor = productor.cultivos.filter(
            produccion_anual=cultivo_mayor_produccion['max_produccion']
        ).first()

        if not cultivo_mayor:
            return JsonResponse({'error': 'No se encontraron cultivos para el productor.'}, status=404)

        # Aggregations for commercialization related to the crop with the highest production
        comercializacion = cultivo_mayor.comercializacion_set.aggregate(
            porc_internacional=Sum('porc_produccion_internacional'),
            porc_nacional=Sum('porc_produccion_nacional'),
            porc_regional=Sum('porc_produccion_regional'),
            nivel_produccion=Max('decl_nivel_produccion')
        )

        # Aggregations for workers
        trabajadores = productor.trabajadores_set.aggregate(
            total_trabajadores=Sum('total_trabajadores'),
            total_pregrado=Sum('trabajadores_pregrado'),
            total_postgrado=Sum('trabajadores_postgrado'),
            total_tecnica=Sum('trabajadores_tecnico'),
            total_media=Sum('trabajadores_educacion_media'),
            total_basica=Sum('trabajadores_educacion_basica'),
        )
        frecuencia_capacitacion = productor.trabajadores_set.values('frecuencia_capacitacion_bpa').distinct()
        frecuencia_capacitacion_seguridad = productor.trabajadores_set.values('frecuencia_capacitacion_seguridad').distinct()

        # Total annual production of all crops
        total_produccion_anual = productor.cultivos.aggregate(
            total_produccion=Sum('produccion_anual')
        )['total_produccion'] or 0

        # List of certifications
        certificaciones_lista = productor.cultivos.prefetch_related('certificaciones_set').values_list(
            'certificaciones__cert_act_sellos_reportes_producciones', flat=True
        ).distinct()

        # List of crops associated with the producer, including certifications and commercialization data
        lista_cultivos = [
            {
                'producto': cultivo.producto,
                'produccion_anual': cultivo.produccion_anual,
                'frecuencia_cosecha_anual': cultivo.frecuencia_cosecha_anual,
                'practica_agricola': cultivo.practica_agricola,
                'declaracion_practica_agricola': cultivo.declaracion_practica_agricola,
                'grado_satisfaccion_cultivo': cultivo.grado_satisfaccion_cultivo,
                'grado_pertinencia_cultivo': cultivo.grado_pertinencia_cultivo,
                'evolucion_prod_ult_cinco_anios': cultivo.comercializacion_set.values_list(
                    'evolucion_prod_ult_cinco_anios', flat=True
                ).first(),  # First commercialization data for this crop
                'sello': cultivo.certificaciones_set.values_list(
                    'cert_act_sellos_reportes_producciones', flat=True
                ).first() or "No especificado"  # Include the first sello or a default value
            }
            for cultivo in productor.cultivos.all()
        ]

        # Aggregations for waste management
        gestion_residuos = cultivo_mayor.residuos_set.aggregate(
            gestion_residuos_organicos=Sum('decl_gestion_residuos_organicos'),
            gestion_residuos_no_organicos=Sum('decl_residuos_no_organicos')
        )

        # Aggregations for traceability, including the `realiza_trazabilidad` field
        trazabilidad = cultivo_mayor.trazabilidad_set.aggregate(
            decl_forma_registro=Max('decl_form_registro_produccion'),
            frec_registro=Max('decla_frec_registro_produccion')
        )
        realiza_trazabilidad_valor = cultivo_mayor.trazabilidad_set.values_list('realiza_trazabilidad', flat=True).first()

        # Total annual water consumption
        total_consumo_agua = Cultivos.objects.filter(
            productor_id=productor.id
        ).aggregate(
            total_consumo_agua=Sum('recursoshidricos__consumo_anual_agua')
        )['total_consumo_agua'] or 0

        # Structured JSON response
        response_data = {
            'productor': {
                'tipo_empresa': productor.tipo_empresa,
                'tamano_empresa': productor.tamano_empresa,
                'region': productor.region,
                'comuna': productor.comuna,
                'ubicacion_predio': productor.ubicacion_predio,
                'ranking_bpsa': productor.ranking_bpsa,
                'percepcion': productor.percepcion,
            },
            'trabajadores': {
                'total': trabajadores['total_trabajadores'] or 0,
                'pregrado': trabajadores['total_pregrado'] or 0,
                'postgrado': trabajadores['total_postgrado'] or 0,
                'tecnica': trabajadores['total_tecnica'] or 0,
                'media': trabajadores['total_media'] or 0,
                'basica': trabajadores['total_basica'] or 0,
                'frecuencia_capacitacion': list(frecuencia_capacitacion),
                'frecuencia_capacitacion_seguridad': list(frecuencia_capacitacion_seguridad),
            },
            'cultivos': {
                'total_produccion_anual': total_produccion_anual,
                'producto_mayor_produccion': cultivo_mayor.producto,
                'porcentaje_internacional': comercializacion['porc_internacional'] or 0,
                'porcentaje_nacional': comercializacion['porc_nacional'] or 0,
                'porcentaje_regional': comercializacion['porc_regional'] or 0,
                'evolucion_produccion': comercializacion['nivel_produccion'] or 0,
                'lista_cultivos': lista_cultivos,
                'consumo_anual_agua': total_consumo_agua
            },
            'certificaciones': list(certificaciones_lista),  # New key for certifications
            'residuos': {
                'gestion_organicos': gestion_residuos['gestion_residuos_organicos'] or 0,
                'gestion_no_organicos': gestion_residuos['gestion_residuos_no_organicos'] or 0,
            },
            'trazabilidad': {
                'realiza_trazabilidad': realiza_trazabilidad_valor or "No especificado",
                'forma_registro': trazabilidad['decl_forma_registro'] or 0,
                'frecuencia_registro': trazabilidad['frec_registro'] or 0,
            }
        }

        return JsonResponse(response_data)

    except Productores.DoesNotExist:
        return JsonResponse({'error': 'Productor no encontrado'}, status=404)
