import asyncio
import os
from bullmq import Queue
import logging

# Configurar logging
logging.basicConfig(level=logging.INFO)
logger = logging.getLogger(__name__)

def bullmq_sender(worker: str, priority: int = 5, delay_sec: int = 0, message: dict = None, redis_url: str = None, job_id: str = None):
    """
    Función simplificada para enviar mensajes a BullMQ.
    
    Args:
        worker: Nombre de la cola de trabajos
        priority: Prioridad del mensaje (mayor número = mayor prioridad, por defecto 5)
        delay_sec: Delay en segundos antes de procesar el mensaje (por defecto 0)
        message: Diccionario con los datos del mensaje a enviar
        redis_url: URL de Redis (opcional, usa variable de entorno por defecto)
        job_id: ID personalizado del trabajo (opcional, se autogenera si es None)
    
    Returns:
        str: ID del trabajo creado
    """
    if message is None:
        message = {}
    
    if redis_url is None:
        redis_url = os.environ.get('REDIS_HOST', 'redis://192.168.1.163:6379')
    
    async def send_message():
        try:
            # Crear la cola
            queue = Queue(worker, {"connection": redis_url})
            
            # Opciones del trabajo con prioridad y delay
            job_options = {"priority": priority}
            
            # Agregar delay si es mayor a 0 (delay en milisegundos)
            if delay_sec > 0:
                job_options["delay"] = delay_sec * 1000
            
            # Agregar información de prioridad y delay al mensaje para tracking
            message_with_metadata = {
                **message,
                "_priority": priority,
                "_worker": worker,
                "_delay_sec": delay_sec
            }
            
            # Determinar el job_name basado en si hay job_id personalizado
            if job_id is not None:
                job_name = job_id
                message_with_metadata["_custom_job_id"] = job_id
            else:
                job_name = f"job_priority_{priority}_delay_{delay_sec}"
            
            # Enviar el mensaje a la cola
            job = await queue.add(
                job_name,
                message_with_metadata,
                job_options
            )
            
            # Log con información de job_id personalizado
            custom_id_info = f" (custom ID: {job_id})" if job_id is not None else ""
            if delay_sec > 0:
                logger.info(f"Message sent to worker '{worker}' with priority {priority} and {delay_sec}s delay, job ID: {job.id}{custom_id_info}")
            else:
                logger.info(f"Message sent to worker '{worker}' with priority {priority}, job ID: {job.id}{custom_id_info}")
            
            # Cerrar la conexión
            await queue.close()
            
            return job.id
            
        except Exception as e:
            logger.error(f"Error sending message to worker '{worker}': {str(e)}")
            raise e
    
    # Ejecutar la función asíncrona
    try:
        job_id = asyncio.run(send_message())
        return job_id
    except Exception as e:
        logger.error(f"Failed to send message: {str(e)}")
        raise e

# Función asíncrona para uso en contextos async
async def bullmq_sender_async(worker: str, priority: int = 5, delay_sec: int = 0, message: dict = None, redis_url: str = None, job_id: str = None):
    """
    Versión asíncrona de bullmq_sender para uso en contextos async.
    
    Args:
        worker: Nombre de la cola de trabajos
        priority: Prioridad del mensaje (mayor número = mayor prioridad, por defecto 5)
        delay_sec: Delay en segundos antes de procesar el mensaje (por defecto 0)
        message: Diccionario con los datos del mensaje a enviar
        redis_url: URL de Redis (opcional, usa variable de entorno por defecto)
        job_id: ID personalizado del trabajo (opcional, se autogenera si es None)
    
    Returns:
        str: ID del trabajo creado
    """
    if message is None:
        message = {}
    
    if redis_url is None:
        redis_url = os.environ.get('REDIS_HOST', 'redis://192.168.1.163:6379')
    
    try:
        # Crear la cola
        queue = Queue(worker, {"connection": redis_url})
        
        # Opciones del trabajo con prioridad y delay
        job_options = {"priority": priority}
        
        # Agregar delay si es mayor a 0 (delay en milisegundos)
        if delay_sec > 0:
            job_options["delay"] = delay_sec * 1000
        
        # Agregar información de prioridad y delay al mensaje para tracking
        message_with_metadata = {
            **message,
            "_priority": priority,
            "_worker": worker,
            "_delay_sec": delay_sec
        }
        
        # Determinar el job_name basado en si hay job_id personalizado
        if job_id is not None:
            job_name = job_id
            message_with_metadata["_custom_job_id"] = job_id
        else:
            job_name = f"job_priority_{priority}_delay_{delay_sec}"
        
        # Enviar el mensaje a la cola
        job = await queue.add(
            job_name,
            message_with_metadata,
            job_options
        )
        
        # Log con información de job_id personalizado
        custom_id_info = f" (custom ID: {job_id})" if job_id is not None else ""
        if delay_sec > 0:
            logger.info(f"Message sent to worker '{worker}' with priority {priority} and {delay_sec}s delay, job ID: {job.id}{custom_id_info}")
        else:
            logger.info(f"Message sent to worker '{worker}' with priority {priority}, job ID: {job.id}{custom_id_info}")
        
        # Cerrar la conexión
        await queue.close()
        
        return job.id
        
    except Exception as e:
        logger.error(f"Error sending message to worker '{worker}': {str(e)}")
        raise e

# Función de ejemplo/testing
if __name__ == "__main__":
    # Ejemplo de uso sin delay
    test_message = {
        "task_type": "test",
        "data": "Hello from bullmq_sender!",
        "timestamp": "2026-01-05"
    }
    
    try:
        # Enviar mensaje inmediato con prioridad por defecto
        job_id = bullmq_sender(
            worker="test_queue",
            message=test_message
        )
        print(f"✅ Immediate message sent successfully, job ID: {job_id}")
        
        # Enviar mensaje con delay y alta prioridad
        job_id_delayed = bullmq_sender(
            worker="test-delay",
            priority=10,
            delay_sec=5,
            message={
                "test": 1,
                "delayed_task": "This will be processed in 5 seconds"
            }
        )
        print(f"✅ Delayed message sent successfully, job ID: {job_id_delayed}")
        
        # Enviar mensaje con job_id personalizado
        custom_job_id = bullmq_sender(
            worker="test_custom_id",
            priority=7,
            message={
                "test": 2,
                "custom_task": "Message with custom ID for tracking"
            },
            job_id="custom_task_2026_001"
        )
        print(f"✅ Custom ID message sent successfully, job ID: {custom_job_id}")
        
    except Exception as e:
        print(f"❌ Failed to send message: {e}")
