from rest_framework import status, viewsets
from rest_framework.decorators import action
from rest_framework.response import Response
from drf_yasg.utils import swagger_auto_schema
from drf_yasg import openapi
from django.utils import timezone
from Models import workflow
from Models.oportunidad_de_venta_model import ColumnWorkflow, OportunidadDeVenta
from .serializers import WorkflowSerializer, CreateWorkflowSerializer, EditWorkflowSerializer, WorkflowWithColumnsSerializer,ColumnWorkflowSerializer

class WorkflowViewSet(viewsets.ViewSet):

    @swagger_auto_schema(
        operation_description="Lista todos los workflows activos con sus columnas y la primera columna",
        responses={200: 'Lista de workflows con columnas'}
    )
    @action(detail=False, methods=['get'], url_path='list_workflow')
    def listar(self, request):
        workflows = workflow.Workflow.objects.filter(deleted_at__isnull=True)
        serializer = WorkflowWithColumnsSerializer(workflows, many=True)
        return Response(serializer.data)


    @swagger_auto_schema(
        operation_description="Crea un nuevo workflow con columnas",
        request_body=CreateWorkflowSerializer,
        responses={
            201: openapi.Response(
                description="Workflow creado correctamente",
                schema=openapi.Schema(
                    type=openapi.TYPE_OBJECT,
                    properties={
                        'mensaje': openapi.Schema(type=openapi.TYPE_STRING),
                        'id': openapi.Schema(type=openapi.TYPE_INTEGER),
                        'datos': openapi.Schema(type=openapi.TYPE_OBJECT)
                    }
                )
            ),
            400: openapi.Response(
                description="Error en los datos proporcionados",
                schema=openapi.Schema(
                    type=openapi.TYPE_OBJECT,
                    properties={
                        'error': openapi.Schema(type=openapi.TYPE_STRING),
                        'detalles': openapi.Schema(type=openapi.TYPE_OBJECT)
                    }
                )
            )
        }
    )
    @action(detail=False, methods=['post'], url_path='create_workflow')
    def crear(self, request):
        serializer = CreateWorkflowSerializer(data=request.data)
        if not serializer.is_valid():
            return Response(
                {"error": "Datos inválidos", "detalles": serializer.errors}, 
                status=status.HTTP_400_BAD_REQUEST
            )

        # Crear workflow
        nuevo_workflow = workflow.Workflow.objects.create(
            nombre=serializer.validated_data['nombre'],
            created_at=timezone.now(),
            updated_at=timezone.now()
        )

        columnas = serializer.validated_data.get('columnas', [])
        inicio_columna = serializer.validated_data.get('inicioColumna', None)

        orden = 1

        # Crear columna inicial primero si existe
        if inicio_columna:
            ColumnWorkflow.objects.create(
                workflow_id=nuevo_workflow.id,
                nombre=inicio_columna,
                orden=orden,
                created_at=timezone.now()
            )
            orden += 1

        # Crear el resto de columnas, evitando duplicar inicio_columna
        for col_name in columnas:
            if col_name != inicio_columna:
                ColumnWorkflow.objects.create(
                    workflow_id=nuevo_workflow.id,
                    nombre=col_name,
                    orden=orden,
                    created_at=timezone.now()
                )
                orden += 1

        # Serializar el workflow incluyendo columnas
        workflow_data = WorkflowSerializer(nuevo_workflow).data
        # Ordenar columnas por orden antes de devolverlas
        workflow_data['columnas'] = ColumnWorkflowSerializer(
            ColumnWorkflow.objects.filter(workflow_id=nuevo_workflow.id).order_by('orden'), 
            many=True
        ).data
        workflow_data['inicioColumna'] = inicio_columna

        return Response({
            "mensaje": "Workflow creado correctamente",
            "id": nuevo_workflow.id,
            "datos": workflow_data
        }, status=status.HTTP_201_CREATED)

    @swagger_auto_schema(
        operation_description="Edita un workflow existente mediante método POST. Solo es necesario incluir el ID y los campos que se desean modificar.",
        request_body=EditWorkflowSerializer,
        responses={
            200: openapi.Response(
                description="Workflow actualizado correctamente",
                schema=openapi.Schema(
                    type=openapi.TYPE_OBJECT,
                    properties={
                        'mensaje': openapi.Schema(type=openapi.TYPE_STRING, description='Mensaje de éxito'),
                        'id': openapi.Schema(type=openapi.TYPE_INTEGER, description='ID del workflow actualizado'),
                        'datos': openapi.Schema(type=openapi.TYPE_OBJECT, description='Datos actualizados del workflow')
                    }
                )
            ),
            400: openapi.Response(
                description="Error en los datos proporcionados",
                schema=openapi.Schema(
                    type=openapi.TYPE_OBJECT,
                    properties={
                        'error': openapi.Schema(type=openapi.TYPE_STRING),
                        'detalles': openapi.Schema(type=openapi.TYPE_OBJECT)
                    }
                )
            ),
            404: openapi.Response(
                description="Workflow no encontrado",
                schema=openapi.Schema(
                    type=openapi.TYPE_OBJECT,
                    properties={
                        'error': openapi.Schema(type=openapi.TYPE_STRING)
                    }
                )
            )
        }
    )
    @action(detail=False, methods=['post'], url_path='edit_workflow')
    def editar(self, request):
        serializer = EditWorkflowSerializer(data=request.data)
        
        if not serializer.is_valid():
            return Response({"error": "Datos inválidos", "detalles": serializer.errors}, status=status.HTTP_400_BAD_REQUEST)
            
        workflow_id = serializer.validated_data['id']
        try:
            workflow_obj = workflow.Workflow.objects.get(id=workflow_id, deleted_at__isnull=True)
        except workflow.Workflow.DoesNotExist:
            return Response({"error": f"Workflow con ID {workflow_id} no encontrado"}, status=status.HTTP_404_NOT_FOUND)
            
        # Actualizar campos
        if 'nombre' in serializer.validated_data:
            workflow_obj.nombre = serializer.validated_data['nombre']
            
        workflow_obj.updated_at = timezone.now()
        workflow_obj.save()

        # Actualizar columnas si se proporcionan
        if 'columnas' in serializer.validated_data:
            columnas_names = serializer.validated_data['columnas']
            inicio_columna_name = serializer.validated_data.get('inicioColumna')
            
            # Obtener columnas actuales
            current_columns = list(ColumnWorkflow.objects.filter(workflow_id=workflow_obj.id, deleted_at__isnull=True))
            
            # Determinar el orden final
            final_order_names = []
            
            # Si hay columna inicial, va primero
            if inicio_columna_name:
                final_order_names.append(inicio_columna_name)
            
            # Agregar el resto de columnas que no sean la inicial
            for name in columnas_names:
                if name != inicio_columna_name:
                    final_order_names.append(name)
            
            # Procesar columnas según el orden nuevo
            for index, name in enumerate(final_order_names, start=1):
                # Buscar si ya existe una columna activa con ese nombre
                found_col = None
                for col in current_columns:
                    if col.nombre == name:
                        found_col = col
                        break
                
                if found_col:
                    # Actualizar orden si es necesario
                    if found_col.orden != index:
                        found_col.orden = index
                        found_col.updated_at = timezone.now()
                        found_col.save()
                    # Remover de la lista de pendientes por procesar
                    current_columns.remove(found_col)
                else:
                    # Crear nueva columna
                    ColumnWorkflow.objects.create(
                        workflow_id=workflow_obj.id,
                        nombre=name,
                        orden=index,
                        created_at=timezone.now(),
                        updated_at=timezone.now()
                    )
            
            # Las columnas que quedaron en current_columns ya no están en la lista nueva -> eliminar (soft delete)
            for col in current_columns:
                col.deleted_at = timezone.now()
                col.save()
        
        return Response({
            "mensaje": "Workflow actualizado correctamente",
            "id": workflow_obj.id,
            "datos": WorkflowWithColumnsSerializer(workflow_obj).data
        })

    @swagger_auto_schema(
        operation_description="Elimina un workflow (soft delete). Solo requiere el ID.",
        request_body=openapi.Schema(
            type=openapi.TYPE_OBJECT,
            required=['id'],
            properties={
                'id': openapi.Schema(type=openapi.TYPE_INTEGER, description='ID del workflow a eliminar'),
            }
        ),
        responses={
            200: openapi.Response(
                description="Workflow eliminado correctamente",
                schema=openapi.Schema(
                    type=openapi.TYPE_OBJECT,
                    properties={
                        'mensaje': openapi.Schema(type=openapi.TYPE_STRING, description='Mensaje de éxito')
                    }
                )
            ),
            400: openapi.Response(
                description="Error en los datos proporcionados",
                schema=openapi.Schema(
                    type=openapi.TYPE_OBJECT,
                    properties={
                        'error': openapi.Schema(type=openapi.TYPE_STRING)
                    }
                )
            ),
            404: openapi.Response(
                description="Workflow no encontrado",
                schema=openapi.Schema(
                    type=openapi.TYPE_OBJECT,
                    properties={
                        'error': openapi.Schema(type=openapi.TYPE_STRING)
                    }
                )
            )
        }
    )
    @action(detail=False, methods=['post'], url_path='delete_workflow')
    def eliminar(self, request):
        workflow_id = request.data.get('id')

        if not workflow_id:
            return Response({"error": "Falta el ID del workflow"}, status=status.HTTP_400_BAD_REQUEST)

        try:
            workflow_obj = workflow.Workflow.objects.get(id=workflow_id, deleted_at__isnull=True)
            
            # Validar si hay oportunidades asociadas
            if OportunidadDeVenta.objects.filter(column_workflow__workflow_id=workflow_id, deleted_at__isnull=True).exists():
                return Response({
                    "error": "No se puede eliminar el workflow porque tiene oportunidades vinculadas. Por favor mueva las oportunidades a otro workflow antes de eliminar."
                }, status=status.HTTP_200_OK)

            workflow_obj.deleted_at = timezone.now()
            workflow_obj.save(update_fields=['deleted_at'])
            return Response({"mensaje": "Workflow eliminado correctamente"})
        except workflow.Workflow.DoesNotExist:
            return Response({"error": "Workflow no encontrado"}, status=status.HTTP_404_NOT_FOUND)

