from rest_framework import serializers
from Models import oportunidad_de_venta_model
from Models.oportunidad_de_venta_model import ColumnWorkflow, OportunidadDeVenta
from Models.Empresa import Empresa
from Models.contacto_model import Contacto
from api_login.models import Usuario
from Models.estado_oportunidad_venta import EstadoOportunidadVenta
from Models.origen import Origen
from producto.serializers import OportunidadProductoSerializer

class OportunidadDeVentaSerializer(serializers.ModelSerializer):
    workflow_nombre = serializers.SerializerMethodField()
    workflow_id = serializers.IntegerField(source='column_workflow.workflow_id', read_only=True)
    column_workflow = serializers.CharField(source='column_workflow.nombre', read_only=True)
    empresa_nombre = serializers.CharField(source='empresa.nombre', read_only=True)
    nombre_comercial = serializers.CharField(source='empresa.nombre_comercial', read_only=True)
    contacto_nombre = serializers.CharField(source='contacto.nombre', read_only=True)
    estado_oportunidad_nombre = serializers.CharField(source='estado_oportunidad.nombre_estado', read_only=True)
    
    # Agregar el campo origen_nombre
    origen_nombre = serializers.SerializerMethodField()
    usuario_responsable_nombre = serializers.SerializerMethodField()
    nombre_workflow = serializers.SerializerMethodField()

    # Expose column_workflow_id explicitly
    column_workflow_id = serializers.IntegerField(source='column_workflow.id', read_only=True)

    productos = OportunidadProductoSerializer(many=True, read_only=True)

    class Meta:
        model = OportunidadDeVenta
        fields = [
            'id',
            'nombre',
            'empresa_id',
            'empresa_nombre',
            'nombre_comercial',
            'contacto_id',
            'contacto_nombre',
            'usuario_responsable_id',
            'usuario_responsable_nombre',
            'estado_oportunidad_id',
            'estado_oportunidad_nombre',
            'valor_estimado',
            'fecha_estimada_cierre',
            'origen',
            'origen_nombre',
            'fecha_creacion',
            'fecha_ultima_actualizacion',
            'deleted_at',
            'workflow_nombre',
            'nombre_workflow',
            'workflow_id',
            'column_workflow', # Exponemos el ID de la columna para el frontend
            'column_workflow_id', # Explicit ID for frontend mapping
            'productos',
        ]
    def get_usuario_responsable_nombre(self, obj):
        if obj.usuario_responsable:
            if hasattr(obj.usuario_responsable, 'nombre') and hasattr(obj.usuario_responsable, 'apellido'):
                return f"{obj.usuario_responsable.nombre} {obj.usuario_responsable.apellido}".strip()
            elif hasattr(obj.usuario_responsable, 'first_name') and hasattr(obj.usuario_responsable, 'last_name'):
                return f"{obj.usuario_responsable.first_name} {obj.usuario_responsable.last_name}".strip()
            elif hasattr(obj.usuario_responsable, 'nombre'):
                return obj.usuario_responsable.nombre
            else:
                return obj.usuario_responsable.username
        return None

    def get_workflow_nombre(self, obj):
        if not obj.column_workflow:
            return None
    
        columna_orden1 = ColumnWorkflow.objects.filter(
            workflow_id=obj.column_workflow.workflow_id,
            orden=1,
            deleted_at__isnull=True
        ).first()
    
        return columna_orden1.nombre if columna_orden1 else None

    def get_nombre_workflow(self, obj):
        if not obj.column_workflow:
            return None
        from Models.workflow import Workflow
        try:
            wf = Workflow.objects.get(id=obj.column_workflow.workflow_id)
            return wf.nombre
        except Workflow.DoesNotExist:
            return None

    def get_origen_nombre(self, obj):
        # 1. Intentar obtener el origen directamente de la oportunidad
        if obj.origen:
            try:
                # Si es un número (ID), intentar buscar en la tabla Origen
                if str(obj.origen).isdigit():
                    origen_obj = Origen.objects.get(id=obj.origen)
                    return origen_obj.nombre
                # Si no es un número, devolver el texto original
                return obj.origen
            except (Origen.DoesNotExist, ValueError, TypeError):
                # En caso de error, devolver el texto original
                return str(obj.origen)

        # 2. Si no tiene origen directo, buscar a través del contacto -> empresa -> origen
        # El usuario indica que "si tiene es por medio del contacto_id"
        if obj.contacto_id:
            try:
                if obj.contacto and obj.contacto.empresa:
                     if obj.contacto.empresa.origen_id:
                        origen_obj = Origen.objects.get(id=obj.contacto.empresa.origen_id)
                        return origen_obj.nombre
            except (Origen.DoesNotExist, AttributeError, ValueError, Exception):
                # Catch generic Exception to handle RelatedObjectDoesNotExist or other DB integrity issues
                pass
        
        return None

class CreateOportunidadSerializer(serializers.ModelSerializer):
    nombre = serializers.CharField(required=True, help_text="Descripcion  de venta")
    empresa_id = serializers.IntegerField(required=True, help_text="ID de la empresa relacionada con esta oportunidad")
    contacto_id = serializers.IntegerField(required=False, allow_null=True, help_text="ID del contacto relacionado con esta oportunidad")
    usuario_responsable_id = serializers.IntegerField(required=True, help_text="ID del usuario responsable de esta oportunidad")
    estado_oportunidad_id = serializers.IntegerField(required=True, help_text="ID del estado de la oportunidad")
    valor_estimado = serializers.DecimalField(max_digits=12, decimal_places=2, required=False, allow_null=True, help_text="Valor estimado de la oportunidad (ej: 15000.00)")
    fecha_estimada_cierre = serializers.DateField(required=True, help_text="Fecha estimada de cierre (formato: YYYY-MM-DD)")
    origen = serializers.CharField(max_length=100, required=False, help_text="Origen de la oportunidad (ej: Referido, Web, Llamada, etc)")
    column_workflow_id = serializers.PrimaryKeyRelatedField(
        queryset=ColumnWorkflow.objects.all(),
        source='column_workflow',
        required=False,
        allow_null=True,
        help_text="ID del workflow asignado a la oportunidad (opcional)"
    )
    productos = serializers.ListField(
        child=serializers.DictField(), 
        required=False,
        help_text="Lista de productos [{'producto_id': 1, 'cantidad': 2, 'precio_unitario': 10.0}]"
    )
    
    class Meta:
        model = oportunidad_de_venta_model.OportunidadDeVenta
        fields = [
            'nombre',
            'empresa_id',
            'contacto_id',
            'usuario_responsable_id',
            'estado_oportunidad_id',
            'valor_estimado',
            'fecha_estimada_cierre',
            'origen',
            'column_workflow_id',
            'productos',
        ]
        
    def validate_empresa_id(self, value):
        try:
            Empresa.objects.get(id=value, deleted_at__isnull=True)
        except Empresa.DoesNotExist:
            raise serializers.ValidationError("La empresa especificada no existe")
        return value
        
    def validate_usuario_responsable_id(self, value):
        try:
            Usuario.objects.get(id=value, deleted_at__isnull=True)
        except Usuario.DoesNotExist:
            raise serializers.ValidationError("El usuario responsable especificado no existe")
        return value
        
    def validate_estado_oportunidad_id(self, value):
        try:
            estado = EstadoOportunidadVenta.objects.get(id=value)
            return value
        except EstadoOportunidadVenta.DoesNotExist:
            estados_disponibles = EstadoOportunidadVenta.objects.all()
            estados_info = [f"ID: {e.id}, Nombre: {e.nombre_estado}" for e in estados_disponibles[:5]]
            mensaje = f"El estado de oportunidad con ID {value} no existe en la base de datos. "
            if estados_disponibles:
                mensaje += f"Estados disponibles: {', '.join(estados_info)}"
            raise serializers.ValidationError(mensaje)
        except Exception as e:
            raise serializers.ValidationError(f"Error al validar el estado de oportunidad: {str(e)}")


class EditOportunidadSerializer(serializers.ModelSerializer):
    workflow_id = serializers.IntegerField(required=False, help_text="ID del workflow asociado")
    id = serializers.IntegerField(required=True, help_text="ID de la oportunidad de venta a editar")
    productos = serializers.ListField(
        child=serializers.DictField(), 
        required=False
    )
    
    def validate_id(self, value):
        try:
            oportunidad = OportunidadDeVenta.objects.get(id=value, deleted_at__isnull=True)
            return value
        except OportunidadDeVenta.DoesNotExist:
            raise serializers.ValidationError(f"La oportunidad de venta con ID {value} no existe o ya fue eliminada")
            
    nombre = serializers.CharField(required=False, help_text="Descripcion  de venta")
    empresa_id = serializers.IntegerField(required=False, help_text="ID de la empresa relacionada con esta oportunidad")
    usuario_responsable_id = serializers.IntegerField(required=False, help_text="ID del usuario responsable de esta oportunidad")
    estado_oportunidad_id = serializers.IntegerField(required=False, help_text="ID del estado de la oportunidad")
    valor_estimado = serializers.DecimalField(max_digits=12, decimal_places=2, required=False, allow_null=True, help_text="Valor estimado de la oportunidad (ej: 15000.00)")
    fecha_estimada_cierre = serializers.DateField(required=False, help_text="Fecha estimada de cierre (formato: YYYY-MM-DD)")
    origen = serializers.CharField(max_length=100, required=False, help_text="Origen de la oportunidad (ej: Referido, Web, Llamada, etc)")
    column_workflow_id = serializers.IntegerField(required=False, help_text="ID del workflow asociado a la oportunidad")

    class Meta:
        model = oportunidad_de_venta_model.OportunidadDeVenta
        fields = [
            'id',
            'nombre',
            'empresa_id',
            'contacto_id',
            'usuario_responsable_id',
            'estado_oportunidad_id',
            'valor_estimado',
            'fecha_estimada_cierre',
            'origen',
            'workflow_id',
            'column_workflow_id',
            'productos',
        ]
        
    def validate_empresa_id(self, value):
        try:
            Empresa.objects.get(id=value, deleted_at__isnull=True)
            return value
        except Empresa.DoesNotExist:
            raise serializers.ValidationError("La empresa especificada no existe")
            
    def validate_usuario_responsable_id(self, value):
        try:
            Usuario.objects.get(id=value, deleted_at__isnull=True)
            return value
        except Usuario.DoesNotExist:
            raise serializers.ValidationError("El usuario responsable especificado no existe")
            
    def validate_estado_oportunidad_id(self, value):
        try:
            estado = EstadoOportunidadVenta.objects.get(id=value)
            return value
        except EstadoOportunidadVenta.DoesNotExist:
             raise serializers.ValidationError("Estado no existe")
        except Exception as e:
            raise serializers.ValidationError(f"Error al validar el estado de oportunidad: {str(e)}")

    def validate_workflow_id(self, value):
        try:
            ColumnWorkflow.objects.get(id=value)
            return value
        except ColumnWorkflow.DoesNotExist:
            raise serializers.ValidationError("El workflow especificado no existe")



from Models.incidencia_model import Incidencia

class IncidenciaSerializer(serializers.ModelSerializer):
    usuario_nombre = serializers.SerializerMethodField()
    tipo_nombre = serializers.ReadOnlyField(source='tipo_incidencia.nombre_tipo')
    estado_nombre = serializers.ReadOnlyField(source='estado_incidencia.nombre_estado')

    class Meta:
        model = Incidencia
        fields = [
            'id', 'titulo', 'descripcion', 'empresa', 'contacto', 'usuario', 'usuario_nombre',
            'tipo_incidencia', 'tipo_nombre', 'estado_incidencia', 'estado_nombre',
            'oportunidad',
            'fecha_creacion', 'fecha_ultima_actualizacion'
        ]
        read_only_fields = ['id', 'fecha_creacion', 'fecha_ultima_actualizacion', 'usuario']

    def get_usuario_nombre(self, obj):
        if obj.usuario:
             return obj.usuario.nombre or obj.usuario.email or "Usuario"
        return "Desconocido"

class DeleteOportunidadSerializer(serializers.Serializer):
    id = serializers.IntegerField(
        required=True, 
        help_text="ID de la oportunidad de venta a eliminar"
    )