from django.shortcuts import render
from django.utils import timezone
from rest_framework import viewsets, status
from rest_framework.decorators import action
from rest_framework.response import Response
from rest_framework.pagination import PageNumberPagination
# Cambia la importación de modelos locales por los globales
from Models.oportunidad_de_venta_model import OportunidadDeVenta
from Models.Empresa import Empresa
from Models.Provincia import Provincia
from Models.Localidad import Localidad
from Models.Estado_Empresa import EstadoEmpresa
from Models.origen import Origen
from .serializers import EmpresaSerializer, EmpresaUpdateSerializer, EmpresaDeleteSerializer, EstadoEmpresaSerializer, EmpresaListSerializer
from drf_yasg.utils import swagger_auto_schema
from drf_yasg import openapi
from django.db import transaction
from Models.contacto_model import Contacto

# Create your views here.

class StandardResultsSetPagination(PageNumberPagination):
    page_size = 50
    page_size_query_param = 'limit'  # Use 'limit' to match existing frontend parameter logic if compatible, or just page_size
    max_page_size = 1000

class EmpresaViewSet(viewsets.ViewSet):
    serializer_class = EmpresaSerializer

    @action(detail=False, methods=['get'], url_path='list_company')
    def list_company(self, request):
        empresas = Empresa.objects.filter(deleted_at__isnull=True)\
        .prefetch_related('provincia', 'localidad')\
        .select_related('estado_empresa', 'tipo_empresa', 'usuario_responsable')\
        .order_by('-fecha_creacion')
        
        # Filtro por id específico
        empresa_id = request.query_params.get('id')
        if empresa_id:
            empresas = empresas.filter(id=empresa_id)
        
        tipo_empresa = request.query_params.get('tipo_empresa')
        if tipo_empresa:
            empresas = empresas.filter(tipo_empresa_id=tipo_empresa)
            
        # Filter by status (estado)
        estado = request.query_params.get('estado')
        if estado:
            empresas = empresas.filter(estado_empresa__nombre_estado=estado)

        # Search functionality
        search = request.query_params.get('search')
        if search:
            from django.db.models import Q
            empresas = empresas.filter(
                Q(nombre__icontains=search) | 
                Q(nombre_comercial__icontains=search) | # New field
                Q(cuit__icontains=search) |
                Q(direccion__icontains=search) |
                Q(localidad__nombre__icontains=search) |
                Q(provincia__nombre__icontains=search)
            )
        
        # We handle pagination manually
        paginator = StandardResultsSetPagination()
        
        # User Requirement: If 'limit' is NOT sent, return ALL records.
        # Only paginate if 'limit' is explicitly provided.
        limit_param = request.query_params.get('limit')
        
        if limit_param:
            page = paginator.paginate_queryset(empresas, request)
            if page is not None:
                # Optimization: Fetch all origins once to avoid N+1 in serializer
                origenes_map = {o.id: o.nombre for o in Origen.objects.all()}
                serializer = EmpresaListSerializer(page, many=True, context={'origenes_map': origenes_map})
                return paginator.get_paginated_response(serializer.data)
        
        origenes_map = {o.id: o.nombre for o in Origen.objects.all()}
        serializer = EmpresaListSerializer(empresas, many=True, context={'origenes_map': origenes_map})
        return Response(serializer.data)

    @swagger_auto_schema(
        operation_description="Crea una nueva empresa.",
        request_body=openapi.Schema(
            type=openapi.TYPE_OBJECT,
            required=['nombre', 'provincia', 'localidad'],
            properties={
                'nombre': openapi.Schema(type=openapi.TYPE_STRING, description='Nombre de la empresa'),
                'cuit': openapi.Schema(type=openapi.TYPE_STRING, description='CUIT de la empresa'),
                'estado_empresa': openapi.Schema(type=openapi.TYPE_INTEGER, description='ID del estado de empresa (opcional)'),
                'provincia': openapi.Schema(type=openapi.TYPE_INTEGER, description='ID de la provincia'),
                'localidad': openapi.Schema(type=openapi.TYPE_INTEGER, description='ID de la localidad'),
                'direccion': openapi.Schema(type=openapi.TYPE_STRING, description='Dirección (opcional)'),
                'tipo_empresa': openapi.Schema(type=openapi.TYPE_INTEGER, description='ID del tipo de empresa (opcional, default 1)'),
                'origen_id': openapi.Schema(type=openapi.TYPE_INTEGER, description='ID del origen '),
                'contactos': openapi.Schema(
                    type=openapi.TYPE_ARRAY,
                    items=openapi.Schema(
                        type=openapi.TYPE_OBJECT,
                        properties={
                            'nombre': openapi.Schema(type=openapi.TYPE_STRING),
                            'apellido': openapi.Schema(type=openapi.TYPE_STRING),
                            'email': openapi.Schema(type=openapi.TYPE_STRING),
                            'telefono': openapi.Schema(type=openapi.TYPE_STRING),
                            'cargo': openapi.Schema(type=openapi.TYPE_STRING),
                        }
                    ),
                    description="Lista de contactos a crear junto con la empresa"
                )
            }
        ),
        responses={
            201: openapi.Response('Empresa creada', EmpresaSerializer),
            400: 'Solicitud incorrecta'
        }
    )
    @action(detail=False, methods=['post'], url_path='create_company')
    @transaction.atomic
    def create_company(self, request):
        serializer = EmpresaSerializer(data=request.data)
        if serializer.is_valid():
            # Validar que no exista un CUIT duplicado
            cuit = request.data.get('cuit', '').strip()
            if cuit:
                empresa_existente = Empresa.objects.filter(
                    cuit=cuit,
                    deleted_at__isnull=True
                ).first()
                if empresa_existente:
                    return Response(
                        {"error": f"Ya existe una empresa con el CUIT {cuit}"},
                        status=status.HTTP_400_BAD_REQUEST
                    )
            
            # Guardar la empresa usando el serializer
            empresa = serializer.save()

            # Manejar creación de contactos si se proporcionan
            contactos_data = request.data.get('contactos', [])
            if contactos_data:
                for contact_data in contactos_data:
                    try:
                        nombre = contact_data.get('nombre', '')
                        apellido = contact_data.get('apellido', '')
                        full_name = f"{nombre} {apellido}".strip()
                        
                        Contacto.objects.create(
                            nombre=full_name if full_name else 'Sin Nombre',
                            email=contact_data.get('email', ''),
                            telefono=contact_data.get('telefono', ''),
                            cargo=contact_data.get('cargo', None),
                            empresa=empresa,
                            fecha_creacion=timezone.now()
                        )
                    except Exception as e:
                        print(f"Error creating contact for company {empresa.id}: {e}")
                        # Opcional: decidir si revertir todo o continuar

            # Preparar response
            data = serializer.data
            data['provincia'] = empresa.provincia_id
            data['localidad'] = empresa.localidad_id
            data['direccion'] = empresa.direccion
            data['origen_id'] = getattr(empresa, 'origen_id', None)
            # Incluir tipo_empresa como id
            data['tipo_empresa'] = getattr(empresa, 'tipo_empresa_id', 1)
            data['codigo_postal'] = empresa.codigo_postal
            data['nombre_comercial'] = empresa.nombre_comercial # Ensure output has it

            return Response(data, status=status.HTTP_201_CREATED)

        return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)

    @swagger_auto_schema(
        operation_description="Modifica una empresa existente por ID.",
        request_body=openapi.Schema(
            type=openapi.TYPE_OBJECT,
            required=['id'],
            properties={
                'id': openapi.Schema(type=openapi.TYPE_INTEGER, description='ID de la empresa a modificar'),
                'nombre': openapi.Schema(type=openapi.TYPE_STRING, description='Nombre de la empresa'),
                'cuit': openapi.Schema(type=openapi.TYPE_STRING, description='CUIT de la empresa'),
                'estado_empresa': openapi.Schema(type=openapi.TYPE_INTEGER, description='ID del estado de empresa'),
                'provincia': openapi.Schema(type=openapi.TYPE_INTEGER, description='ID de la provincia'),
                'localidad': openapi.Schema(type=openapi.TYPE_INTEGER, description='ID de la localidad'),
                'direccion': openapi.Schema(type=openapi.TYPE_STRING, description='Dirección'),
                'tipo_empresa': openapi.Schema(type=openapi.TYPE_INTEGER, description='ID del tipo de empresa'),
                'origen_id': openapi.Schema(type=openapi.TYPE_INTEGER, description='ID del origen (opcional)'),
            }
        ),
        responses={
            200: openapi.Response('Empresa actualizada', EmpresaSerializer),
            400: 'Solicitud incorrecta',
            404: 'Empresa no encontrada'
        }
    )
    @action(detail=False, methods=['patch'], url_path='update_company')
    def update_company(self, request):
        empresa_id = request.data.get('id')
        if not empresa_id:
            return Response({"error": "Se requiere el id de la empresa"}, status=status.HTTP_400_BAD_REQUEST)
        try:
            empresa = Empresa.objects.get(id=empresa_id)
        except Empresa.DoesNotExist:
            return Response({"error": "Empresa no encontrada"}, status=status.HTTP_404_NOT_FOUND)

        update_fields = {}
        for field in ['nombre', 'name_comercial', 'cuit', 'estado_empresa_id', 'provincia', 'localidad', 'direccion', 'tipo_empresa', 'tipo_empresa_id', 'origen_id', 'codigo_postal', 'usuario_responsable_id', 'provincia_id', 'localidad_id']:
            if field in request.data:
                # Mapear los campos _id a sus versiones sin _id para provincia y localidad
                if field == 'provincia_id' and 'provincia' not in request.data:
                    update_fields['provincia'] = request.data[field]
                elif field == 'localidad_id' and 'localidad' not in request.data:
                    update_fields['localidad'] = request.data[field]
                else:
                    update_fields[field] = request.data[field]

        if not update_fields:
            return Response({"error": "No se enviaron campos para modificar"}, status=status.HTTP_400_BAD_REQUEST)

        # FORCE UPDATE of usuario_responsable_id manually to ensure it is saved
        if 'usuario_responsable_id' in request.data:
            try:
                uid = request.data['usuario_responsable_id']
                if uid:
                    empresa.usuario_responsable_id = int(uid)
                else:
                    empresa.usuario_responsable_id = None
                empresa.save()
                print(f"DEBUG update_company: Manual update of usuario_responsable_id to {empresa.usuario_responsable_id}")
            except Exception as e:
                print(f"DEBUG update_company: Error updating usuario_responsable_id manually: {e}")

        print(f"DEBUG update_company: update_fields={update_fields}")

        serializer = EmpresaUpdateSerializer(empresa, data=update_fields, partial=True)
        if serializer.is_valid():
            empresa = serializer.save()
            empresa.refresh_from_db() # Asegurar tener datos frescos
            data = serializer.data
            data['provincia'] = empresa.provincia_id
            data['localidad'] = empresa.localidad_id
            data['direccion'] = empresa.direccion
            data['origen_id'] = getattr(empresa, 'origen_id', None)
            data['tipo_empresa'] = getattr(empresa, 'tipo_empresa_id', 1)
            data['codigo_postal'] = empresa.codigo_postal
            data['nombre_comercial'] = empresa.nombre_comercial # Ensure output has it
            data['usuario_responsable_id'] = empresa.usuario_responsable_id
            print(f"DEBUG update_company: empresa updated. usuario_responsable_id={empresa.usuario_responsable_id}")
            return Response({"mensaje": "Empresa actualizada", "empresa": data})
        
        print(f"DEBUG update_company: errors={serializer.errors}")
        return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)

    @swagger_auto_schema(
        operation_description="Elimina (soft delete) una empresa por ID. Actualiza el campo deleted_at.",
        request_body=EmpresaDeleteSerializer,
        responses={
            200: openapi.Response('Empresa eliminada'),
            400: 'Solicitud incorrecta',
            404: 'Empresa no encontrada'
        }
    )
    @action(detail=False, methods=['post'], url_path='delete_company')
    def delete_company(self, request):
        empresa_id = request.data.get('id')
        if not empresa_id:
            return Response({"error": "Se requiere el id de la empresa"}, status=status.HTTP_400_BAD_REQUEST)
        try:
            empresa = Empresa.objects.get(id=empresa_id)
        except Empresa.DoesNotExist:
            return Response({"error": "Empresa no encontrada"}, status=status.HTTP_404_NOT_FOUND)

        empresa.deleted_at = timezone.now()
        empresa.save()
        return Response({"mensaje": "Empresa eliminada correctamente", "id": empresa_id}, status=status.HTTP_200_OK)


    @action(detail=False, methods=['get'], url_path='get_statuses')
    def get_statuses(self, request):
        estados = EstadoEmpresa.objects.all()
        serializer = EstadoEmpresaSerializer(estados, many=True)
        return Response(serializer.data)

    @swagger_auto_schema(
        operation_description="Devuelve los contactos asociados a una empresa por su ID.",
        request_body=openapi.Schema(
            type=openapi.TYPE_OBJECT,
            properties={
                'empresa_id': openapi.Schema(type=openapi.TYPE_INTEGER, description='ID de la empresa')
            },
            required=['empresa_id']
        ),
        responses={
            200: openapi.Response('Contactos de la empresa'),
            400: 'Solicitud incorrecta'
        }
    )
    @action(detail=False, methods=['get'], url_path='get_clients')
    def get_clients(self, request):
        empresa_id = request.query_params.get('empresa_id')
        if not empresa_id:
            return Response({"error": "Se requiere el id de la empresa"}, status=status.HTTP_400_BAD_REQUEST)
        contactos = Contacto.objects.filter(empresa_id=empresa_id, deleted_at__isnull=True).values('id', 'nombre', 'email')
        return Response(list(contactos), status=status.HTTP_200_OK)

    @action(detail=False, methods=['get'], url_path='oportunity_clients')
    def oportunity_clients(self, request):
        id_client = request.query_params.get('id_client')
        if not id_client:
            return Response({"error": "Se requiere el parámetro id_client"}, status=status.HTTP_400_BAD_REQUEST)
        oportunidades = OportunidadDeVenta.objects.filter(
            empresa_id=id_client, deleted_at__isnull=True
        ).select_related('estado_oportunidad')

        data = []
        for o in oportunidades:
            data.append({
                'id': o.id,
                'nombre': o.nombre,
                'fecha_creacion': o.fecha_creacion,
                'estado_oportunidad': o.estado_oportunidad.nombre_estado if o.estado_oportunidad else None
            })
        return Response({"data": data}, status=status.HTTP_200_OK)
    
    
    # client_contacts
    @action(detail=False, methods=['get'], url_path='client_contacts')
    def client_contacts(self, request):
        id_client = request.query_params.get('id_client')
        print(f"DEBUG: client_contacts endpoint called with id_client={id_client}")
        if not id_client:
            return Response({"error": "Se requiere el id del cliente"}, status=status.HTTP_400_BAD_REQUEST)
        
        contactos = Contacto.objects.filter(empresa_id=id_client, deleted_at__isnull=True).values('id', 'nombre', 'email', 'telefono', 'cargo')
        print(f"DEBUG: Found {contactos.count()} contacts for client {id_client}")
        return Response(list(contactos), status=status.HTTP_200_OK)
