# This is a placeholder for the proper backup test file
import time
from datetime import datetime, timezone
from tredops_eval.connect import db
from .bullmaq_backup import (
    bullmq_backup,
    bullmq_restore,
    list_backups,
    delete_backup,
    bullmq_delete_backup,
    mongodb_collection_backup
)
from .bullmq_sender import bullmq_sender
from .bullmq_consumer import consumer_bullmq
import threading

def backup_test_worker(message):
    """Worker de prueba para tests de backup."""
    print(f"Backup test processing: {message}")
    time.sleep(0.2)
    return {"status": "processed", "data": message}

@pytest.mark.skipif(db is None, reason="Requires real MongoDB connection")
def test_bullmq_backup_basic():
    """Test básico de backup de BullMQ con base de datos real."""
    redis_url = "redis://192.168.1.163:6379"
    backup_name = "test_backup_basic_001"
    
    # Limpiar backup anterior si existe
    bullmq_delete_backup(backup_name, db=db)

    # Crear algunos jobs para hacer backup
    test_queues = ["backup_test_queue_1", "backup_test_queue_2"]

    job_ids = []
    for i, queue_name in enumerate(test_queues):
        job_id = bullmq_sender(
            worker=queue_name,
            priority=5 + i,
            delay_sec=2,
            message={"backup_test": True, "queue_index": i, "data": f"Test data {i}"},
            job_id=f"backup_test_job_{i}"
        )
        job_ids.append(job_id)

    print(f"Created {len(job_ids)} jobs for backup test")

    # Esperar que se registren los jobs
    time.sleep(1)

    # Hacer backup
    backup_result = bullmq_backup(
        db=db,
        queue_names=test_queues,
        redis_url=redis_url,
        backup_name=backup_name
    )

    # Verificaciones
    assert backup_result["status"] == "success", f"Backup failed: {backup_result}"
    assert backup_result["backup_id"] == backup_name
    assert backup_result["total_jobs"] >= 0  # Pueden ser 0 si los jobs ya se procesaron
    assert backup_result["total_queues"] >= 0
    
    # Verificar que se guardó en la base de datos real
    collection = db[mongodb_collection_backup]
    backup_docs = list(collection.find({"backup_id": backup_name}))
    print(f"Found {len(backup_docs)} backup documents in database")
    
    # Limpiar después del test
    cleanup_result = bullmq_delete_backup(backup_name, db=db)
    print(f"Cleanup: {cleanup_result['message']}")

@pytest.mark.skipif(db is None, reason="Requires real MongoDB connection")
def test_bullmq_backup_with_real_jobs():
    """Test de backup con jobs reales procesándose usando base de datos real."""
    queue_name = "backup_real_jobs_test"
    backup_name = "real_jobs_backup_test"
    
    # Limpiar backup anterior si existe
    bullmq_delete_backup(backup_name, db=db)

    # Crear jobs con diferentes estados
    job_ids = []
    for i in range(3):
        job_id = bullmq_sender(
            worker=queue_name,
            priority=5,
            delay_sec=0 if i < 2 else 5,  # Último job con delay
            message={"real_job_test": i, "content": f"Real job content {i}"}
        )
        job_ids.append(job_id)

    print(f"Created {len(job_ids)} real jobs")

    # Procesar algunos jobs
    backup_test_worker.processed_messages = []

    def run_consumer():
        try:
            consumer_bullmq(worker=queue_name, function_process=backup_test_worker)
        except KeyboardInterrupt:
            pass

    consumer_thread = threading.Thread(target=run_consumer)
    consumer_thread.daemon = True
    consumer_thread.start()

    time.sleep(2)  # Dejar que se procesen algunos jobs

    # Hacer backup
    backup_result = bullmq_backup(
        db=db,
        queue_names=[queue_name],
        backup_name=backup_name
    )

    # Verificaciones
    assert backup_result["status"] == "success", f"Real jobs backup failed: {backup_result}"
    assert backup_result["backup_id"] == backup_name
    
    # Verificar que se guardaron documentos en la base de datos real
    collection = db[mongodb_collection_backup]
    backup_docs = list(collection.find({"backup_id": backup_name}))
    print(f"Backup saved {len(backup_docs)} job documents")
    
    # Limpiar después del test
    cleanup_result = bullmq_delete_backup(backup_name, db=db)
    print(f"Cleanup: {cleanup_result['message']}")

@pytest.mark.skipif(db is None, reason="Requires real MongoDB connection")
def test_bullmq_restore_basic():
    """Test básico de restore de BullMQ usando base de datos real."""
    backup_name = "restore_test_backup"
    test_queue = "restore_test_queue"
    
    # Limpiar backup anterior si existe
    bullmq_delete_backup(backup_name, db=db)
    
    # Crear un job para backup
    job_id = bullmq_sender(
        worker=test_queue,
        priority=7,
        delay_sec=3,
        message={"restore_test": True, "content": "Test restore data"}
    )
    
    time.sleep(1)
    
    # Crear backup
    backup_result = bullmq_backup(
        db=db,
        queue_names=[test_queue],
        backup_name=backup_name
    )
    
    assert backup_result["status"] == "success"
    
    # Hacer restore
    restore_result = bullmq_restore(
        db=db,
        backup_id=backup_name
    )

    # Verificaciones
    assert restore_result["backup_id"] == backup_name
    print(f"Restore completed: {restore_result['message']}")
    
    # Limpiar después del test
    bullmq_delete_backup(backup_name, db=db)

@pytest.mark.skipif(db is None, reason="Requires real MongoDB connection")
def test_bullmq_restore_latest_backup():
    """Test de restore usando el backup más reciente con base de datos real."""
    old_backup = "old_backup_test"
    recent_backup = "recent_backup_test"
    test_queue = "recent_test_queue"
    
    # Limpiar backups anteriores si existen
    bullmq_delete_backup(old_backup, db=db)
    bullmq_delete_backup(recent_backup, db=db)
    
    # Crear backup más antiguo
    old_job_id = bullmq_sender(
        worker=test_queue,
        priority=5,
        message={"old_backup": True}
    )
    time.sleep(0.5)
    
    old_backup_result = bullmq_backup(
        db=db,
        queue_names=[test_queue],
        backup_name=old_backup
    )
    
    # Esperar un momento para diferencia temporal
    time.sleep(1)
    
    # Crear backup más reciente
    recent_job_id = bullmq_sender(
        worker=test_queue,
        priority=5,
        message={"recent_backup": True}
    )
    time.sleep(0.5)
    
    recent_backup_result = bullmq_backup(
        db=db,
        queue_names=[test_queue],
        backup_name=recent_backup
    )
    
    assert old_backup_result["status"] == "success"
    assert recent_backup_result["status"] == "success"

    # Restore sin especificar backup_id (debería usar el más reciente)
    restore_result = bullmq_restore(db=db)

    # Verificaciones
    assert restore_result["backup_id"] == recent_backup, "Should have used most recent backup"
    print(f"Successfully used most recent backup: {restore_result['backup_id']}")
    
    # Limpiar después del test
    bullmq_delete_backup(old_backup, db=db)
    bullmq_delete_backup(recent_backup, db=db)

@pytest.mark.skipif(db is None, reason="Requires real MongoDB connection")
def test_list_backups():
    """Test de listado de backups usando base de datos real."""
    test_backup_name = "list_backups_test"
    test_queue = "list_test_queue"
    
    # Limpiar backup anterior si existe
    bullmq_delete_backup(test_backup_name, db=db)
    
    # Crear un backup para probar
    job_id = bullmq_sender(
        worker=test_queue,
        priority=5,
        message={"list_test": True}
    )
    time.sleep(0.5)
    
    backup_result = bullmq_backup(
        db=db,
        queue_names=[test_queue],
        backup_name=test_backup_name
    )
    
    assert backup_result["status"] == "success"
    
    # Listar backups
    backups = list_backups(db)
    
    # Verificaciones
    assert isinstance(backups, list), "Should return list of backups"
    
    # Buscar nuestro backup en la lista
    found_backup = None
    for backup in backups:
        if backup["backup_id"] == test_backup_name:
            found_backup = backup
            break
    
    assert found_backup is not None, f"Should find backup '{test_backup_name}' in list"
    assert "total_jobs" in found_backup
    assert "total_queues" in found_backup
    
    print(f"Found backup: {found_backup}")
    
    # Limpiar después del test
    bullmq_delete_backup(test_backup_name, db=db)

@pytest.mark.skipif(db is None, reason="Requires real MongoDB connection")
def test_delete_backup():
    """Test de eliminación de backup usando base de datos real."""
    test_backup_name = "delete_test_backup"
    test_queue = "delete_test_queue"
    
    # Crear un backup para eliminar
    job_id = bullmq_sender(
        worker=test_queue,
        priority=5,
        message={"delete_test": True}
    )
    time.sleep(0.5)
    
    backup_result = bullmq_backup(
        db=db,
        queue_names=[test_queue],
        backup_name=test_backup_name
    )
    
    assert backup_result["status"] == "success"
    
    # Verificar que existe
    collection = db[mongodb_collection_backup]
    backup_docs_before = list(collection.find({"backup_id": test_backup_name}))
    assert len(backup_docs_before) > 0, "Backup should exist before deletion"
    
    # Eliminar backup usando la nueva función
    delete_result = bullmq_delete_backup(test_backup_name, db=db)
    
    # Verificaciones
    assert delete_result["status"] == "success", f"Delete failed: {delete_result}"
    assert delete_result["backup_id"] == test_backup_name
    assert delete_result["deleted_count"] > 0
    
    # Verificar que ya no existe
    backup_docs_after = list(collection.find({"backup_id": test_backup_name}))
    assert len(backup_docs_after) == 0, "Backup should not exist after deletion"
    
    print(f"Successfully deleted backup: {delete_result['message']}")

def test_bullmq_backup_error_handling():
    """Test de manejo de errores en backup."""
    # Test con base de datos None
    backup_result = bullmq_backup(
        db=None,
        queue_names=["test_queue"],
        backup_name="error_test"
    )
    
    assert backup_result["status"] == "error"
    assert "Database connection required" in backup_result["message"]

def test_bullmq_restore_error_handling():
    """Test de manejo de errores en restore."""
    # Test con base de datos None
    restore_result = bullmq_restore(db=None)
    
    assert restore_result["status"] == "error"
    assert "Database connection required" in restore_result["message"]
    
    if db is not None:
        # Test con backup inexistente
        restore_result = bullmq_restore(
            db=db,
            backup_id="nonexistent_backup_12345"
        )
        
        assert restore_result["status"] == "error"
        assert "not found" in restore_result["message"]