from .bullmq_consumer import consumer_bullmq
from .bullmq_sender import bullmq_sender
import pytest
import asyncio
import os
import threading
import time
from bullmq import Queue

def function_worker(message):
    print("Processing message:", message)
    # Almacenar el mensaje procesado para verificar en el test
    if hasattr(function_worker, 'processed_messages'):
        function_worker.processed_messages.append(message)
    return {"status": "processed", "data": message}

queue_name = "test_queue"
redis_url = os.environ.get('REDIS_HOST', 'redis://192.168.1.163:6379')
async def cleanup_queue(queue_name_to_clean):
    """Función para limpiar completamente una cola después de los tests."""
    try:
        queue = Queue(queue_name_to_clean, {"connection": redis_url})
        # Método más simple de limpieza
        await queue.clean(0, 1000, "completed")
        await queue.clean(0, 1000, "failed")
        await queue.close()
        print(f"✅ Queue '{queue_name_to_clean}' cleaned successfully")
    except Exception as e:
        print(f"⚠️ Error cleaning queue '{queue_name_to_clean}': {e}")

async def check_queue_status(queue_name_to_check):
    """Función para verificar el estado de una cola."""
    try:
        queue = Queue(queue_name_to_check, {"connection": redis_url})
        
        # Método más simple para obtener counts
        waiting_count = 0
        completed_count = 0
        failed_count = 0
        
        try:
            waiting_jobs = await queue.getJobs(["waiting"], 0, -1)
            waiting_count = len(waiting_jobs) if waiting_jobs else 0
        except:
            waiting_count = 0
            
        try:
            completed_jobs = await queue.getJobs(["completed"], 0, -1)
            completed_count = len(completed_jobs) if completed_jobs else 0
        except:
            completed_count = 0
            
        try:
            failed_jobs = await queue.getJobs(["failed"], 0, -1)
            failed_count = len(failed_jobs) if failed_jobs else 0
        except:
            failed_count = 0
        
        status = {
            'waiting': waiting_count,
            'completed': completed_count,
            'failed': failed_count
        }
        
        await queue.close()
        return status
    except Exception as e:
        print(f"Error checking queue status: {e}")
        return {'waiting': 0, 'completed': 0, 'failed': 0}

def test_send_message_to_bullmq_queue():
    """Test básico para enviar mensaje a BullMQ queue usando bullmq_sender."""
    # Lista para capturar mensajes procesados
    function_worker.processed_messages = []
    
    # Mensaje de test
    test_message = {"task": "test_task", "data": "Hello BullMQ!"}
    
    def run_consumer():
        """Ejecutar consumer en thread separado."""
        try:
            consumer_bullmq(worker=queue_name, function_process=function_worker)
        except KeyboardInterrupt:
            pass
    
    # Usar bullmq_sender para enviar mensaje
    job_id = bullmq_sender(
        worker=queue_name,
        priority=1,
        message=test_message
    )
    print(f"Message sent with job ID: {job_id}")
    assert job_id is not None, "Failed to send message"
    
    # Iniciar consumer en thread separado
    consumer_thread = threading.Thread(target=run_consumer)
    consumer_thread.daemon = True
    consumer_thread.start()
    
    # Esperar a que el consumer procese el mensaje
    time.sleep(4)
    
    # Verificar que el mensaje fue procesado
    assert len(function_worker.processed_messages) >= 1, "No messages were processed"
    
    # Verificar contenido del mensaje (el sender agrega campos extras)
    processed_msg = function_worker.processed_messages[0]
    assert processed_msg["task"] == test_message["task"], "Task doesn't match"
    assert processed_msg["data"] == test_message["data"], "Data doesn't match"
    assert processed_msg["_priority"] == 1, "Priority doesn't match"
    assert processed_msg["_worker"] == queue_name, "Worker doesn't match"
    
    print("✅ Test passed: Message successfully sent and processed")

def test_priority_messages():
    """Test para verificar procesamiento por prioridades usando bullmq_sender."""
    function_worker.processed_messages = []
    
    priority_queue_name = "priority_test_queue"
    
    # Mensajes con diferentes prioridades
    messages = [
        {"id": "high", "message": "High priority"}, 
        {"id": "medium", "message": "Medium priority"},
        {"id": "low", "message": "Low priority"}
    ]
    
    priorities = [10, 5, 1]  # Del más alto al más bajo
    
    # Usar bullmq_sender para enviar mensajes con diferentes prioridades
    job_ids = []
    for msg, priority in zip(messages, priorities):
        job_id = bullmq_sender(
            worker=priority_queue_name,
            priority=priority,
            message=msg
        )
        job_ids.append(job_id)
        print(f"Added message: {msg['message']} (priority: {priority}, job_id: {job_id})")
        time.sleep(0.1)  # Pequeño delay
    
    assert len(job_ids) == 3, "Failed to send all messages"
    
    # Ejecutar consumer por tiempo limitado
    def run_priority_consumer():
        try:
            consumer_bullmq(worker=priority_queue_name, function_process=function_worker)
        except KeyboardInterrupt:
            pass
    
    consumer_thread = threading.Thread(target=run_priority_consumer)
    consumer_thread.daemon = True
    consumer_thread.start()
    
    # Esperar procesamiento
    time.sleep(5)
    
    # Verificar que se procesaron mensajes
    assert len(function_worker.processed_messages) >= 1, "No priority messages processed"
    
    # Debug: Ver estructura completa de mensajes procesados
    print("=== DEBUG: Processed messages structure ===")
    for i, msg in enumerate(function_worker.processed_messages):
        print(f"Message {i}: {type(msg)} = {msg}")
    print("=== END DEBUG ===")
    
    # Verificar que todos los mensajes fueron procesados
    if len(function_worker.processed_messages) >= 1:
        # Extraer IDs de manera más segura
        processed_ids = []
        for msg in function_worker.processed_messages:
            if isinstance(msg, dict) and "id" in msg:
                processed_ids.append(msg["id"])
            else:
                print(f"Warning: Message without 'id' field: {msg}")
        
        print(f"Processed message IDs: {processed_ids}")
        
        # Verificar que al menos algunos mensajes están presentes
        expected_ids = {"high", "medium", "low"}
        actual_ids = set(processed_ids)
        
        if len(processed_ids) > 0:
            assert len(actual_ids.intersection(expected_ids)) >= 1, \
                f"Expected some IDs from {expected_ids}, got {actual_ids}"
            print("✅ Priority messages processed successfully")
        else:
            # Si no hay IDs, al menos verificar que se procesaron mensajes
            print("⚠️ No ID fields found, but messages were processed")
            assert len(function_worker.processed_messages) >= 1, "Should have processed messages"
    
    print("✅ Priority test completed")

def test_consumer_activation():
    """Test para verificar activación del consumer usando bullmq_sender."""
    function_worker.processed_messages = []
    
    activation_queue_name = "activation_test_queue"
    
    # Mensajes de prueba
    test_messages = [
        {"task": "task_1", "content": "First message"},
        {"task": "task_2", "content": "Second message"}
    ]
    
    # Usar bullmq_sender para enviar mensajes
    job_ids = []
    for i, msg in enumerate(test_messages):
        job_id = bullmq_sender(
            worker=activation_queue_name,
            priority=1,
            message=msg
        )
        job_ids.append(job_id)
        print(f"Sent message {i+1}: {msg['content']} (job_id: {job_id})")
    
    assert len(job_ids) == 2, "Failed to send all messages"
    
    # Activar consumer
    def run_activation_consumer():
        consumer_bullmq(worker=activation_queue_name, function_process=function_worker)
    
    consumer_thread = threading.Thread(target=run_activation_consumer)
    consumer_thread.daemon = True
    consumer_thread.start()
    
    # Esperar procesamiento
    time.sleep(4)
    
    # Verificar que llegaron mensajes a la función destino
    assert len(function_worker.processed_messages) >= 1, "Consumer not activated properly"
    
    processed_contents = [msg.get('content', '') for msg in function_worker.processed_messages]
    expected_contents = [msg['content'] for msg in test_messages]
    
    # Verificar que al menos uno de los mensajes esperados fue procesado
    found_message = any(content in processed_contents for content in expected_contents)
    assert found_message, "Expected messages not found in processed messages"
    
    print("✅ Consumer activation test passed")
    
    # Activar consumer
    def run_activation_consumer():
        consumer_bullmq(worker=activation_queue_name, function_process=function_worker)
    
    consumer_thread = threading.Thread(target=run_activation_consumer)
    consumer_thread.daemon = True
    consumer_thread.start()
    
    # Esperar procesamiento
    time.sleep(3)
    
    # Verificar que llegaron mensajes a la función destino
    assert len(function_worker.processed_messages) >= 1, "Consumer not activated properly"
    
    processed_contents = [msg.get('content', '') for msg in function_worker.processed_messages]
    expected_contents = [msg['content'] for msg in test_messages]
    
    # Verificar que al menos uno de los mensajes esperados fue procesado
    found_message = any(content in processed_contents for content in expected_contents)
    assert found_message, "Expected messages not found in processed messages"
    
    # Verificar remoción de mensajes de Redis
    final_status = asyncio.run(check_queue_status(activation_queue_name))
    print(f"Final activation queue status: {final_status}")
    
    assert final_status['waiting'] == 0, f"Expected 0 waiting messages, found {final_status['waiting']}"
    assert final_status['completed'] >= len(function_worker.processed_messages), \
        "Not all processed messages marked as completed"
    
    # Limpiar cola después del test
    asyncio.run(cleanup_queue(activation_queue_name))
    
    print("✅ Consumer activation test passed - Messages processed and removed")

def test_bullmq_delay():
    """Test para verificar funcionamiento de delay_sec en bullmq_sender."""
    # Limpiar mensajes globales al inicio del test
    function_worker.processed_messages = []
    
    delay_queue_name = "test_delay_unique_queue"
    delay_seconds = 3  # 3 segundos de delay
    
    # Mensaje de test con delay
    test_message = {
        "task": "delayed_task", 
        "content": "This should be delayed",
        "test_id": "delay_001"
    }
    
    def run_delay_consumer():
        """Ejecutar consumer en thread separado."""
        try:
            consumer_bullmq(worker=delay_queue_name, function_process=function_worker)
        except KeyboardInterrupt:
            pass
    
    # Iniciar consumer antes de enviar mensaje
    consumer_thread = threading.Thread(target=run_delay_consumer)
    consumer_thread.daemon = True
    consumer_thread.start()
    
    # Enviar mensaje con delay usando bullmq_sender
    start_time = time.time()
    job_id = bullmq_sender(
        worker=delay_queue_name,
        priority=5,
        delay_sec=delay_seconds,
        message=test_message
    )
    
    print(f"Delayed message sent with job ID: {job_id} (delay: {delay_seconds}s)")
    assert job_id is not None, "Failed to send delayed message"
    
    # Verificar que NO se procesa inmediatamente (esperar 1 segundo)
    time.sleep(1)
    
    # Debug: mostrar mensajes actuales
    print(f"Debug: Messages after 1s: {len(function_worker.processed_messages)}")
    if len(function_worker.processed_messages) > 0:
        print(f"Unexpected messages: {function_worker.processed_messages}")
    
    assert len(function_worker.processed_messages) == 0, \
        f"Message was processed too early! Expected 0 messages, got {len(function_worker.processed_messages)}"
    print(f"✅ Verified message not processed immediately (after 1s)")
    
    # Esperar hasta que se complete el delay + tiempo extra para procesamiento
    total_wait_time = delay_seconds + 2
    remaining_wait = total_wait_time - 1  # Ya esperamos 1 segundo
    
    print(f"Waiting additional {remaining_wait}s for delay to complete...")
    time.sleep(remaining_wait)
    
    # Verificar que el mensaje fue procesado después del delay
    assert len(function_worker.processed_messages) >= 1, \
        "Delayed message was not processed after delay period"
    
    # Verificar contenido del mensaje procesado
    processed_msg = function_worker.processed_messages[0]
    assert processed_msg["task"] == test_message["task"], "Task doesn't match"
    assert processed_msg["content"] == test_message["content"], "Content doesn't match"
    assert processed_msg["test_id"] == test_message["test_id"], "Test ID doesn't match"
    assert processed_msg["_delay_sec"] == delay_seconds, "Delay metadata doesn't match"
    assert processed_msg["_worker"] == delay_queue_name, "Worker metadata doesn't match"
    
    # Calcular tiempo transcurrido desde el envío
    elapsed_time = time.time() - start_time
    print(f"Message processed after {elapsed_time:.1f}s (expected ~{delay_seconds}s)")
    
    # Verificar que el tiempo transcurrido es aproximadamente correcto
    # Debe ser al menos el delay_seconds, pero no demasiado más
    assert elapsed_time >= delay_seconds, \
        f"Message processed too early: {elapsed_time:.1f}s < {delay_seconds}s"
    assert elapsed_time <= delay_seconds + 3, \
        f"Message processed too late: {elapsed_time:.1f}s > {delay_seconds + 3}s"
    
    print(f"✅ Delay test passed: Message processed correctly after {delay_seconds}s delay")

def test_bullmq_multiple_delays():
    """Test para verificar múltiples mensajes con diferentes delays."""
    # Limpiar mensajes globales al inicio del test
    function_worker.processed_messages = []
    
    multi_delay_queue_name = "test_multi_delay_unique_queue"
    
    # Mensajes con diferentes delays
    test_messages = [
        {"id": "immediate", "delay": 0, "message": "No delay"},
        {"id": "short", "delay": 2, "message": "Short delay"}, 
        {"id": "long", "delay": 4, "message": "Long delay"}
    ]
    
    def run_multi_delay_consumer():
        try:
            consumer_bullmq(worker=multi_delay_queue_name, function_process=function_worker)
        except KeyboardInterrupt:
            pass
    
    # Iniciar consumer
    consumer_thread = threading.Thread(target=run_multi_delay_consumer)
    consumer_thread.daemon = True
    consumer_thread.start()
    
    # Enviar mensajes con diferentes delays
    start_time = time.time()
    job_ids = []
    
    for msg_data in test_messages:
        job_id = bullmq_sender(
            worker=multi_delay_queue_name,
            priority=5,
            delay_sec=msg_data["delay"],
            message={"id": msg_data["id"], "content": msg_data["message"]}
        )
        job_ids.append(job_id)
        print(f"Sent {msg_data['id']} message with {msg_data['delay']}s delay (job_id: {job_id})")
    
    assert len(job_ids) == 3, "Failed to send all delayed messages"
    
    # Esperar tiempo suficiente para que se procesen todos los mensajes
    time.sleep(6)  # 4s (max delay) + 2s extra
    
    # Verificar que se procesaron mensajes
    assert len(function_worker.processed_messages) >= 1, "No delayed messages were processed"
    
    # Verificar que el mensaje inmediato se procesó primero
    if len(function_worker.processed_messages) >= 1:
        # Debug: Ver estructura de mensajes procesados
        print("=== DEBUG: Processed messages structure ===")
        for i, msg in enumerate(function_worker.processed_messages):
            print(f"Message {i}: {type(msg)} = {msg}")
        print("=== END DEBUG ===")
        
        # Verificar que los mensajes tienen el campo 'id'
        processed_ids = []
        for msg in function_worker.processed_messages:
            if isinstance(msg, dict) and "id" in msg:
                processed_ids.append(msg["id"])
            else:
                print(f"Warning: Message without 'id' field: {msg}")
        
        print(f"Processed message IDs: {processed_ids}")
        
        # Verificar que todos los IDs están presentes
        expected_ids = {"immediate", "short", "long"}
        actual_ids = set(processed_ids)
        
        found_ids = actual_ids.intersection(expected_ids)
        if len(processed_ids) > 0:
            assert len(found_ids) >= 1, f"Expected some IDs from {expected_ids}, got {actual_ids}"
        else:
            print("⚠️ No IDs found in processed messages")
            assert len(function_worker.processed_messages) >= 1, "Should have processed messages"
        
        print(f"✅ Multiple delay test completed: {len(found_ids)} messages processed correctly")

def test_send_message_error():
    """Test para verificar manejo de errores en el consumer."""
    function_worker.processed_messages = []
    
    error_queue_name = "error_test_queue"
    
    def error_function(message):
        """Función que genera diferentes tipos de errores según el mensaje."""
        print(f"Processing message that will cause error: {message}")
        
        # Almacenar el mensaje para verificar que llegó
        if hasattr(error_function, 'processed_messages'):
            error_function.processed_messages.append(message)
        else:
            error_function.processed_messages = [message]
        
        # Generar diferentes tipos de errores según el tipo especificado en el mensaje
        error_type = message.get("error_type", "generic")
        
        if error_type == "value_error":
            raise ValueError(f"Invalid value provided: {message.get('invalid_value', 'unknown')}")
        elif error_type == "key_error":
            missing_key = message.get("missing_key", "required_field")
            raise KeyError(f"Missing required key: '{missing_key}'")
        elif error_type == "type_error":
            raise TypeError(f"Invalid type for operation: expected str, got {type(message.get('wrong_type', 123))}")
        elif error_type == "custom_error":
            class CustomBusinessError(Exception):
                pass
            raise CustomBusinessError(f"Business logic error: {message.get('business_reason', 'Invalid operation')}")
        else:
            # Error genérico con información detallada
            raise Exception(f"Generic processing error for message ID: {message.get('id', 'unknown')}")
    
    # Mensajes que causarán diferentes tipos de errores
    error_messages = [
        {
            "id": "error_001",
            "error_type": "value_error",
            "invalid_value": "negative_number",
            "task": "process_number"
        },
        {
            "id": "error_002", 
            "error_type": "key_error",
            "missing_key": "user_id",
            "task": "process_user"
        },
        {
            "id": "error_003",
            "error_type": "type_error", 
            "wrong_type": 123,
            "task": "process_string"
        },
        {
            "id": "error_004",
            "error_type": "custom_error",
            "business_reason": "Insufficient funds",
            "task": "process_payment"
        }
    ]
    
    def run_error_consumer():
        """Ejecutar consumer que manejará errores."""
        try:
            consumer_bullmq(worker=error_queue_name, function_process=error_function)
        except KeyboardInterrupt:
            pass
    
    # Iniciar consumer
    consumer_thread = threading.Thread(target=run_error_consumer)
    consumer_thread.daemon = True
    consumer_thread.start()
    
    # Enviar mensajes que causarán errores
    job_ids = []
    for msg in error_messages:
        job_id = bullmq_sender(
            worker=error_queue_name,
            priority=1,
            message=msg
        )
        job_ids.append(job_id)
        print(f"Sent error message {msg['id']}: {msg['error_type']} (job_id: {job_id})")
    
    assert len(job_ids) == 4, "Failed to send all error messages"
    
    # Esperar a que se procesen los mensajes (y fallen)
    time.sleep(5)
    
    # Verificar que los mensajes llegaron a la función (antes de fallar)
    assert hasattr(error_function, 'processed_messages'), "Error function was not called"
    assert len(error_function.processed_messages) >= 1, "No messages reached the error function"
    
    # Verificar que los mensajes procesados contienen los IDs esperados
    processed_ids = [msg["id"] for msg in error_function.processed_messages]
    expected_ids = {"error_001", "error_002", "error_003", "error_004"}
    actual_ids = set(processed_ids)
    
    found_ids = actual_ids.intersection(expected_ids)
    assert len(found_ids) >= 1, f"Expected some error IDs from {expected_ids}, got {actual_ids}"
    
    print(f"✅ Error messages processed: {found_ids}")
    
    # Verificar el estado de la cola - los jobs deberían estar en estado "failed"
    final_status = asyncio.run(check_queue_status(error_queue_name))
    print(f"Final error queue status: {final_status}")
    
    # Al menos algunos trabajos deberían haber fallado
    assert final_status['failed'] >= 1, \
        f"Expected at least 1 failed job, found {final_status['failed']}"
    
    # No debería haber trabajos completados exitosamente
    assert final_status['completed'] == 0, \
        f"Expected 0 completed jobs (all should fail), found {final_status['completed']}"
    
    print(f"✅ Error handling verified: {final_status['failed']} jobs failed as expected")
    
    # Limpiar cola después del test
    asyncio.run(cleanup_queue(error_queue_name))
    
    print(f"✅ Error test passed - All messages failed correctly and errors should be visible in BullMQ dashboard")

def test_dashboard_visibility():
    """Test para verificar visibilidad de mensajes en diferentes secciones del dashboard."""
    function_worker.processed_messages = []
    
    dashboard_queue_name = "delay_test_queue"
    
    print("🎯 DASHBOARD VISIBILITY TEST")
    print("=" * 50)
    
    # PASO 1: Enviar mensajes SIN consumer (para verlos en dashboard)
    print("\n📋 PASO 1: Enviando mensajes SIN consumer activo...")
    
    # Mensaje inmediato con prioridad normal
    job1 = bullmq_sender(
        worker=dashboard_queue_name,
        priority=1,
        message={"id": "waiting_msg", "type": "normal", "content": "Should appear in WAITING"}
    )
    print(f"✅ Sent WAITING message (priority 1): {job1}")
    
    # Mensaje con alta prioridad
    job2 = bullmq_sender(
        worker=dashboard_queue_name,
        priority=10,
        message={"id": "priority_high", "type": "high_priority", "content": "Should appear in PRIORITIZED"}
    )
    print(f"✅ Sent HIGH PRIORITY message (priority 10): {job2}")
    
    # Mensaje con delay
    job3 = bullmq_sender(
        worker=dashboard_queue_name,
        priority=5,
        delay_sec=30,  # 30 segundos de delay
        message={"id": "delayed_msg", "type": "delayed", "content": "Should appear in DELAYED"}
    )
    print(f"✅ Sent DELAYED message (30s delay): {job3}")
    
    # Otro mensaje con prioridad media
    job4 = bullmq_sender(
        worker=dashboard_queue_name,
        priority=5,
        message={"id": "priority_medium", "type": "medium_priority", "content": "Should appear in PRIORITIZED"}
    )
    print(f"✅ Sent MEDIUM PRIORITY message (priority 5): {job4}")
    
    print("\n🔍 VERIFICA EN EL DASHBOARD DE BULLMQ:")
    print("- WAITING: Debería mostrar mensaje con priority 1")
    print("- PRIORITIZED: Debería mostrar mensajes con priority 10 y 5")
    print("- DELAYED: Debería mostrar mensaje con 30s delay")
    print("\nEspera 10 segundos para revisar el dashboard...")
    
    # Esperar para que el usuario pueda revisar el dashboard
    time.sleep(10)
    
    # PASO 2: Activar consumer y procesar algunos mensajes
    print("\n📋 PASO 2: Activando consumer...")
    
    def run_dashboard_consumer():
        try:
            consumer_bullmq(worker=dashboard_queue_name, function_process=function_worker)
        except KeyboardInterrupt:
            pass
    
    consumer_thread = threading.Thread(target=run_dashboard_consumer)
    consumer_thread.daemon = True
    consumer_thread.start()
    
    # Esperar que procese los mensajes inmediatos
    print("Procesando mensajes inmediatos...")
    time.sleep(5)
    
    print("\n🔍 VERIFICA EN EL DASHBOARD DE BULLMQ:")
    print("- ACTIVE: Posiblemente mostrando mensaje siendo procesado")
    print("- COMPLETED: Mensajes que ya se procesaron")
    print("- DELAYED: Aún debería mostrar el mensaje con delay")
    
    # Verificar que algunos mensajes fueron procesados
    processed_count = len(function_worker.processed_messages)
    print(f"\n📊 Mensajes procesados hasta ahora: {processed_count}")
    
    if processed_count > 0:
        for i, msg in enumerate(function_worker.processed_messages):
            print(f"  {i+1}. {msg.get('id', 'unknown')} - {msg.get('type', 'unknown')}")
    
    # PASO 3: Enviar más mensajes mientras consumer está activo
    print("\n📋 PASO 3: Enviando mensajes con consumer ACTIVO...")
    
    job5 = bullmq_sender(
        worker=dashboard_queue_name,
        priority=8,
        message={"id": "runtime_msg", "type": "runtime", "content": "Sent while consumer running"}
    )
    print(f"✅ Sent runtime message: {job5}")
    
    time.sleep(3)
    
    # Verificar estado final
    final_status = asyncio.run(check_queue_status(dashboard_queue_name))
    print(f"\n📊 ESTADO FINAL DE LA COLA:")
    print(f"  - Waiting: {final_status['waiting']}")
    print(f"  - Completed: {final_status['completed']}")
    print(f"  - Failed: {final_status['failed']}")
    
    final_processed = len(function_worker.processed_messages)
    print(f"\n✅ Total mensajes procesados: {final_processed}")
    
    # Limpiar cola
    asyncio.run(cleanup_queue(dashboard_queue_name))
    
    print("\n🎯 DASHBOARD TEST COMPLETED!")
    print("Deberías haber visto mensajes en diferentes secciones del dashboard.")
    
    assert final_processed >= 1, "Al menos algunos mensajes deberían haberse procesado"

# Función para limpiar todas las colas al final de todos los tests
def cleanup_all_test_queues():
    """Limpia todas las colas de test al final."""
    test_queues = ["test_queue", "priority_test_queue", "activation_test_queue", 
                   "test_delay_unique_queue", "test_multi_delay_unique_queue", "error_test_queue", 
                   "dashboard_test_queue"]
    
    async def cleanup_all():
        for queue_name in test_queues:
            await cleanup_queue(queue_name)
    
    asyncio.run(cleanup_all())
    print("✅ All test queues cleaned")
