/**
 * Sistema de Asignación de Resúmenes Científicos
 * Script mejorado con animaciones profesionales
 */

// Variables globales
let activeEvaluators = [];
let selectedEvaluators = {};
let workloadData = {};
let animationInProgress = false;

// Inicialización de evaluadores con conteo de asignaciones
function initializeEvaluators(evaluatorsData, assignmentsData) {
    
       // Validar si GSAP está disponible
    if (typeof gsap === 'undefined') {
        console.error("ERROR: GSAP no está disponible en initializeEvaluators. Las animaciones no funcionarán.");
        return; // Detener la función si GSAP no está disponible
    }
    
    
    activeEvaluators = evaluatorsData;
    
    // Almacenar datos de carga de trabajo
    if (assignmentsData) {
        workloadData = assignmentsData;
    }
    
    console.log("Evaluadores activos:", activeEvaluators.length);
    
    // Inicializar listeners para insignias de evaluadores
    initializeEvaluatorBadges();
    
    // Inicializar gráfico de carga de trabajo
    initializeWorkloadChart();
    
    // Aplicar animaciones a las insignias de evaluadores
    animateEvaluatorBadges();
    
    // Inicializar toggles de tarjetas
    initializeCardToggles();
    
    // Inicializar botones de acción
    initializeActionButtons();
    
    // Transición de entrada en la página
    animatePageLoad();
}

// Inicialización de las insignias de evaluadores
function initializeEvaluatorBadges() {
    document.querySelectorAll('.evaluator-badge:not(.assigned)').forEach(badge => {
        badge.addEventListener('click', function() {
            // Evitar clic mientras hay animación
            if (animationInProgress) return;
            
            const badgeId = this.id;
            if (!badgeId) return;
            
            // Formato: e1-PAPERCODE, e2-PAPERCODE, e3-PAPERCODE
            const parts = badgeId.split('-');
            if (parts.length !== 2) return;
            
            const position = parts[0]; // e1, e2, e3
            const paperCode = parts[1];
            
            // Efecto de clic
            gsap.to(this, {
                scale: 0.8,
                duration: 0.1,
                yoyo: true,
                repeat: 1,
                onComplete: () => {
                    // Abrir selector de evaluadores
                    openEvaluatorSelector(this, position, paperCode);
                }
            });
        });
    });
}

// Inicializar botones de acción
function initializeActionButtons() {
    // Botón de asignación automática
    const assignBtn = document.getElementById('assign-btn');
    if (assignBtn) {
        assignBtn.addEventListener('mouseenter', () => {
            gsap.to(assignBtn, {
                scale: 1.05,
                duration: 0.2,
                ease: "power1.out"
            });
        });
        
        assignBtn.addEventListener('mouseleave', () => {
            gsap.to(assignBtn, {
                scale: 1,
                duration: 0.2,
                ease: "power1.in"
            });
        });
        
        assignBtn.addEventListener('click', function() {
            if (animationInProgress) return;
            
            // Efecto al hacer clic
            gsap.to(this, {
                scale: 0.95,
                duration: 0.1,
                yoyo: true,
                repeat: 1,
                onComplete: () => {
                    if (confirm('¿Está seguro de que desea asignar automáticamente los evaluadores de manera equitativa?')) {
                        showAssignmentAnimation();
                    }
                }
            });
        });
    }
    
    // Botón de reinicio
    const resetBtn = document.getElementById('reset-btn');
    if (resetBtn) {
        resetBtn.addEventListener('mouseenter', () => {
            gsap.to(resetBtn, {
                scale: 1.05,
                duration: 0.2,
                ease: "power1.out"
            });
        });
        
        resetBtn.addEventListener('mouseleave', () => {
            gsap.to(resetBtn, {
                scale: 1,
                duration: 0.2,
                ease: "power1.in"
            });
        });
        
        resetBtn.addEventListener('click', function() {
            if (animationInProgress) return;
            
            // Efecto al hacer clic
            gsap.to(this, {
                scale: 0.95,
                duration: 0.1,
                yoyo: true,
                repeat: 1,
                onComplete: () => {
                    if (confirm('¿Está seguro de que desea reiniciar todas las asignaciones? Esta acción no se puede deshacer.')) {
                        resetAll();
                    }
                }
            });
        });
    }
}

// Animación de carga de página
function animatePageLoad() {
    // Animación de la sección de progreso
    gsap.from('#assignment-progress', {
        y: -50,
        opacity: 0,
        duration: 0.8,
        ease: 'power3.out',
        delay: 0.2
    });
    
    // Animación de las tarjetas de área
    gsap.from('.area-card', {
        y: 50,
        opacity: 0,
        duration: 0.8,
        stagger: 0.15,
        ease: 'power3.out',
        delay: 0.4
    });
    
    // Animación de botones
    gsap.from('.btn', {
        scale: 0.5,
        opacity: 0,
        duration: 0.8,
        stagger: 0.2,
        ease: 'back.out(1.7)',
        delay: 0.6
    });
}

// Inicializar visualización del gráfico de carga de trabajo con animaciones mejoradas
function initializeWorkloadChart() {
    const chartContainer = document.getElementById('workload-chart');
    if (!chartContainer) {
        console.error("No se encuentra el contenedor del gráfico de carga");
        return;
    }
    
    // Limpiar contenido existente
    chartContainer.innerHTML = '';
    
    // Encontrar carga máxima para escalar
    const maxWorkload = Math.max(...Object.values(workloadData), 1);
    
    // Crear barras para cada evaluador
    activeEvaluators.forEach((evaluator, index) => {
        const workload = workloadData[evaluator.id] || 0;
        const percentage = (workload / maxWorkload) * 100;
        
        // Crear contenedor de barra
        const barContainer = document.createElement('div');
        barContainer.className = 'workload-bar';
        
        // Crear la barra en sí
        const bar = document.createElement('div');
        bar.className = 'workload-value';
        bar.style.height = '0%'; // Empezar en 0 para animación
        bar.setAttribute('data-value', workload);
        
        // Crear etiqueta con avatar y nombre
        const label = document.createElement('div');
        label.className = 'workload-label';
        
        // Añadir avatar si está disponible
        if (evaluator.avatar) {
            const avatar = document.createElement('img');
            avatar.className = 'workload-avatar';
            avatar.src = `dist/pages/evaluadores/acciones_evaluador/fotos_empleados/${evaluator.avatar}`;
            avatar.alt = evaluator.nombre;
            label.appendChild(avatar);
        } else {
            // Usar iniciales si no hay avatar
            const initials = document.createElement('div');
            initials.className = 'evaluator-badge';
            initials.style.width = '28px';
            initials.style.height = '28px';
            initials.style.fontSize = '12px';
            initials.innerHTML = `<span>${getInitials(evaluator.nombre)}</span>`;
            label.appendChild(initials);
        }
        
        // Añadir nombre (abreviado)
        const nameParts = evaluator.nombre.split(' ');
        let shortName = nameParts[0];
        if (nameParts.length > 1) {
            shortName += ` ${nameParts[1].charAt(0)}.`;
        }
        
        const nameSpan = document.createElement('span');
        nameSpan.textContent = shortName;
        nameSpan.title = evaluator.nombre;
        label.appendChild(nameSpan);
        
        // Ensamblar la barra
        barContainer.appendChild(bar);
        barContainer.appendChild(label);
        chartContainer.appendChild(barContainer);
        
        // Animar la altura de la barra con un retraso secuencial para efecto visual
        gsap.to(bar, {
            height: `${percentage}%`,
            duration: 1,
            delay: index * 0.1,
            ease: "elastic.out(1, 0.5)"
        });
    });
}

// Inicializar toggles de tarjetas
function initializeCardToggles() {
    document.querySelectorAll('.card-toggle').forEach(button => {
        button.addEventListener('click', function() {
            const card = this.closest('.card');
            const body = card.querySelector('.card-body');
            const icon = this.querySelector('i');
            const text = this.querySelector('span');
            
            if (body.classList.contains('active')) {
                // Cerrar
                gsap.to(body, {
                    height: 0,
                    opacity: 0,
                    duration: 0.3,
                    ease: "power2.inOut",
                    onComplete: () => {
                        body.classList.remove('active');
                        body.style.height = '';
                        icon.classList.remove('fa-chevron-up');
                        icon.classList.add('fa-chevron-down');
                        text.textContent = 'Mostrar';
                    }
                });
            } else {
                // Abrir
                body.classList.add('active');
                body.style.opacity = 0;
                body.style.height = 'auto';
                const height = body.offsetHeight;
                body.style.height = 0;
                
                gsap.to(body, {
                    height: height,
                    opacity: 1,
                    duration: 0.5,
                    ease: "power2.out",
                    onComplete: () => {
                        body.style.height = '';
                        icon.classList.remove('fa-chevron-down');
                        icon.classList.add('fa-chevron-up');
                        text.textContent = 'Ocultar';
                    }
                });
            }
        });
    });
}

// Animar insignias de evaluadores para apariencia visual
function animateEvaluatorBadges() {
    gsap.set('.evaluator-badge:not(.assigned)', { 
        scale: 0.5, 
        opacity: 0 
    });
    
    gsap.to('.evaluator-badge:not(.assigned)', {
        scale: 1,
        opacity: 1,
        duration: 0.5,
        stagger: 0.02,
        ease: "back.out(1.7)",
        delay: 0.8
    });
}

// Abrir selector para elegir un evaluador
function openEvaluatorSelector(badge, position, paperCode) {
    // Verificar si el selector ya existe y eliminarlo
    removeExistingSelector();
    
    // Crear contenedor del selector
    const selector = document.createElement('div');
    selector.id = 'evaluator-selector';
    selector.className = 'evaluator-selector';
    selector.style.opacity = 0;
    
    // Agregar título
    const title = document.createElement('div');
    title.className = 'selector-title';
    title.textContent = 'Seleccionar Evaluador';
    selector.appendChild(title);
    
    // Agregar botón de cierre
    const closeBtn = document.createElement('button');
    closeBtn.className = 'selector-close';
    closeBtn.innerHTML = '<i class="fas fa-times"></i>';
    closeBtn.addEventListener('click', removeExistingSelector);
    title.appendChild(closeBtn);
    
    // Agregar opciones de evaluadores
    const optionsContainer = document.createElement('div');
    optionsContainer.className = 'selector-options';
    
    // Obtener otros evaluadores seleccionados para este trabajo
    const paperPositions = ['e1', 'e2', 'e3'];
    const otherPositions = paperPositions.filter(p => p !== position);
    
    const otherSelectedEvaluators = [];
    otherPositions.forEach(pos => {
        const otherBadge = document.getElementById(`${pos}-${paperCode}`);
        if (otherBadge && otherBadge.dataset.evaluatorId) {
            otherSelectedEvaluators.push(otherBadge.dataset.evaluatorId);
        }
    });
    
    // Crear opciones de evaluadores
    activeEvaluators.forEach(evaluator => {
        // Omitir si este evaluador ya está seleccionado para otra posición en este trabajo
        if (otherSelectedEvaluators.includes(evaluator.id)) {
            return;
        }
        
        const option = document.createElement('div');
        option.className = 'selector-option';
        option.dataset.evaluatorId = evaluator.id;
        
        // Obtener información de carga de trabajo
        const workload = workloadData[evaluator.id] || 0;
        
        // Crear contenido de la opción
        option.innerHTML = `
            <div class="evaluator-badge">
                ${evaluator.avatar ? 
                    `<img class="evaluator-avatar" src="dist/pages/evaluadores/acciones_evaluador/fotos_empleados/${evaluator.avatar}" alt="${evaluator.nombre}" style="display: block; width: 100%; height: 100%; object-fit: cover; border-radius: 50%;">` : 
                    `<span class="evaluator-initials">${getInitials(evaluator.nombre)}</span>`
                }
            </div>
            <div class="evaluator-info">
                <div class="evaluator-name">${evaluator.nombre}</div>
                <div class="evaluator-workload">
                    <span class="badge ${workload > 0 ? 'badge-primary' : 'badge-secondary'}">${workload}</span> asignaciones
                </div>
            </div>
        `;
        
        // Agregar evento de clic para seleccionar este evaluador
        option.addEventListener('mouseenter', function() {
            gsap.to(this, {
                backgroundColor: "rgba(67, 97, 238, 0.08)",
                duration: 0.2
            });
        });
        
        option.addEventListener('mouseleave', function() {
            gsap.to(this, {
                backgroundColor: "transparent",
                duration: 0.2
            });
        });
        
        option.addEventListener('click', function() {
            // Efecto de selección
            gsap.to(this, {
                backgroundColor: "rgba(67, 97, 238, 0.15)",
                scale: 0.98,
                duration: 0.1,
                yoyo: true,
                repeat: 1,
                onComplete: () => {
                    selectEvaluator(badge, position, paperCode, evaluator);
                    removeExistingSelector();
                }
            });
        });
        
        optionsContainer.appendChild(option);
    });
    
    selector.appendChild(optionsContainer);
    
    // Posicionar el selector cerca de la insignia
    const badgeRect = badge.getBoundingClientRect();
    const scrollTop = window.pageYOffset || document.documentElement.scrollTop;
    
    selector.style.position = 'absolute';
    selector.style.top = `${badgeRect.bottom + scrollTop + 10}px`;
    selector.style.left = `${badgeRect.left - 100}px`; // Centrar más
    
    // Agregar al documento
    document.body.appendChild(selector);
    
    // Animar la aparición con escala y opacidad
    gsap.fromTo(selector,
        { opacity: 0, y: -20, scale: 0.95 },
        { opacity: 1, y: 0, scale: 1, duration: 0.4, ease: "back.out(1.7)" }
    );
    
    // Animar las opciones con efecto en cascada
    gsap.fromTo(selector.querySelectorAll('.selector-option'),
        { opacity: 0, x: -20 },
        { opacity: 1, x: 0, duration: 0.3, stagger: 0.05, delay: 0.15 }
    );
    
    // Agregar clic fuera para cerrar
    setTimeout(() => {
        document.addEventListener('click', handleClickOutside);
    }, 10);
}

// Eliminar cualquier selector de evaluador existente
function removeExistingSelector() {
    const existingSelector = document.getElementById('evaluator-selector');
    if (existingSelector) {
        gsap.to(existingSelector, {
            opacity: 0, 
            y: -10, 
            scale: 0.9,
            duration: 0.3,
            ease: "power3.in",
            onComplete: () => existingSelector.remove()
        });
        document.removeEventListener('click', handleClickOutside);
    }
}

// Manejar clic fuera del selector para cerrarlo
function handleClickOutside(event) {
    const selector = document.getElementById('evaluator-selector');
    if (selector && !selector.contains(event.target) && !event.target.closest('.evaluator-badge')) {
        removeExistingSelector();
    }
}

// Seleccionar un evaluador para una posición con efectos visuales
function selectEvaluator(badge, position, paperCode, evaluator) {
    // Crear el efecto de conexión visual
    createConnectionEffect(badge, evaluator);
    
    // Actualizar la insignia después del retraso de animación
    setTimeout(() => {
        // Actualizar la insignia
        badge.classList.add('assigned');
        badge.title = evaluator.nombre;
        badge.dataset.evaluatorId = evaluator.id;
        
        // Actualizar contenido de la insignia
        if (evaluator.avatar) {
            const avatarImg = badge.querySelector('.evaluator-avatar');
            if (avatarImg) {
                avatarImg.src = `dist/pages/evaluadores/acciones_evaluador/fotos_empleados/${evaluator.avatar}`;
                avatarImg.alt = evaluator.nombre;
                avatarImg.style.display = 'block';
            } else {
                const newAvatarImg = document.createElement('img');
                newAvatarImg.className = 'evaluator-avatar';
                newAvatarImg.src = `dist/pages/evaluadores/acciones_evaluador/fotos_empleados/${evaluator.avatar}`;
                newAvatarImg.alt = evaluator.nombre;
                newAvatarImg.style.display = 'block';
                newAvatarImg.style.width = '100%';
                newAvatarImg.style.height = '100%';
                newAvatarImg.style.objectFit = 'cover';
                newAvatarImg.style.borderRadius = '50%';
                
                const initials = badge.querySelector('.evaluator-initials');
                if (initials) initials.style.display = 'none';
                
                badge.appendChild(newAvatarImg);
            }
        } else {
            const initials = badge.querySelector('.evaluator-initials');
            if (initials) {
                initials.textContent = getInitials(evaluator.nombre);
                initials.style.display = 'block';
            }
            
            const avatarImg = badge.querySelector('.evaluator-avatar');
            if (avatarImg) avatarImg.style.display = 'none';
        }
        
        // Agregar animación de pulso
        gsap.fromTo(badge, 
            { boxShadow: '0 0 0 0 rgba(6, 214, 160, 0)' },
            {
                boxShadow: '0 0 0 8px rgba(6, 214, 160, 0)',
                duration: 1.5,
                ease: "elastic.out(1, 0.3)",
                repeat: 1
            }
        );
        
        // Almacenar selección
        if (!selectedEvaluators[paperCode]) {
            selectedEvaluators[paperCode] = {};
        }
        selectedEvaluators[paperCode][position] = evaluator.id;
        
        // Si los 3 evaluadores están seleccionados, guardar asignación
        if (selectedEvaluators[paperCode]['e1'] && 
            selectedEvaluators[paperCode]['e2'] && 
            selectedEvaluators[paperCode]['e3']) {
            
            // Validar que los tres evaluadores sean diferentes
            const e1 = selectedEvaluators[paperCode]['e1'];
            const e2 = selectedEvaluators[paperCode]['e2'];
            const e3 = selectedEvaluators[paperCode]['e3'];
            
            if (e1 === e2 || e1 === e3 || e2 === e3) {
                showNotification('Error', 'Los tres evaluadores deben ser distintos.', 'error');
                return;
            }
            
            // Mostrar animación de finalización
            showCompletionAnimation(paperCode);
            
            // Guardar la asignación
            saveAssignment(
                paperCode, 
                selectedEvaluators[paperCode]['e1'],
                selectedEvaluators[paperCode]['e2'],
                selectedEvaluators[paperCode]['e3']
            );
        }
    }, 800); // Retraso para coincidir con la animación
}

// Crear efecto de conexión 3D entre la insignia y el evaluador
function createConnectionEffect(badge, evaluator) {
    const badgeRect = badge.getBoundingClientRect();
    const scrollTop = window.pageYOffset || document.documentElement.scrollTop;
    
    // Encontrar la posición del evaluador en la tabla
    const evaluatorRow = Array.from(document.querySelectorAll('tr')).find(row => {
        const evaluatorCell = row.querySelector('td');
        if (!evaluatorCell) return false;
        const evaluatorBadge = evaluatorCell.querySelector('.evaluator-badge');
        if (!evaluatorBadge) return false;
        return evaluatorBadge.parentElement.nextElementSibling && 
               evaluatorBadge.parentElement.nextElementSibling.textContent.includes(evaluator.nombre);
    });
    
    let startElement, startX, startY;
    
    if (evaluatorRow) {
        startElement = evaluatorRow.querySelector('.evaluator-badge');
        const startRect = startElement.getBoundingClientRect();
        startX = startRect.left + startRect.width / 2;
        startY = startRect.top + startRect.height / 2 + scrollTop;
    } else {
        startX = window.innerWidth / 2;
        startY = 100 + scrollTop;
    }
    
    // Posición final (centro de la insignia)
    const endX = badgeRect.left + badgeRect.width / 2;
    const endY = badgeRect.top + badgeRect.height / 2 + scrollTop;
    
    // Crear varios puntos para un efecto más interesante
    const pointsCount = 10;
    const points = [];
    
    for (let i = 0; i < pointsCount; i++) {
        const point = document.createElement('div');
        point.className = 'connection-dot';
        point.style.opacity = 0;
        point.style.backgroundColor = "#4361ee";
        document.body.appendChild(point);
        points.push(point);
    }
    
    // Animar todos los puntos con trayectorias ligeramente diferentes
    points.forEach((dot, index) => {
        // Calcular posición
        const progress = index / (pointsCount - 1);
        
        // Punto de control para curva de Bezier
        const controlX = (startX + endX) / 2 + (Math.random() * 100 - 50);
        const controlY = (startY + endY) / 2 - Math.random() * 100; // Curvar hacia arriba
        
        // Trayectoria en timeline
        const tl = gsap.timeline();
        
        // Establecer posición inicial
        tl.set(dot, {
            left: startX,
            top: startY,
            scale: 0.5
        });
        
        // Mostrar el punto
        tl.to(dot, {
            opacity: 0.8,
            scale: Math.random() * 0.5 + 0.8,
            duration: 0.2
        });
        
        // Animar a lo largo de la trayectoria
        tl.to(dot, {
            motionPath: {
                path: [
                    {x: startX, y: startY},
                    {x: controlX, y: controlY},
                    {x: endX, y: endY}
                ],
                curviness: 1.5
            },
            ease: "power1.inOut",
            duration: 0.8 + Math.random() * 0.4,
            delay: index * 0.05
        });
        
        // Pulso y desvanecimiento en el destino
        tl.to(dot, {
            opacity: 0,
            scale: 2,
            duration: 0.3
        });
        
        // Eliminar después de la animación
        tl.call(() => dot.remove());
    });
    
    // Añadir efecto de destello en la insignia destino
    const flash = document.createElement('div');
    flash.style.position = 'absolute';
    flash.style.width = '50px';
    flash.style.height = '50px';
    flash.style.borderRadius = '50%';
    flash.style.backgroundColor = 'rgba(6, 214, 160, 0.7)';
    flash.style.left = `${endX - 25}px`;
    flash.style.top = `${endY - 25}px`;
    flash.style.transform = 'scale(0)';
    flash.style.opacity = '0';
    flash.style.zIndex = '100';
    
    document.body.appendChild(flash);
    
    // Animar destello
    gsap.to(flash, {
        scale: 1.5,
        opacity: 0.8,
        duration: 0.5,
        delay: 0.7,
        onComplete: () => {
            gsap.to(flash, {
                scale: 0,
                opacity: 0,
                duration: 0.3,
                onComplete: () => flash.remove()
            });
        }
    });
    
    // Si tenemos un elemento inicial, animarlo también
    if (startElement) {
        gsap.to(startElement, {
            scale: 1.2,
            duration: 0.3,
            yoyo: true,
            repeat: 1
        });
    }
}

// Mostrar animación de finalización cuando los 3 evaluadores están asignados
function showCompletionAnimation(paperCode) {
    const row = document.querySelector(`.paper-row[data-paper="${paperCode}"]`);
    if (!row) return;
    
    // Crear animación de marca de verificación
    const checkmark = document.createElement('div');
    checkmark.className = 'checkmark-container';
    checkmark.innerHTML = '<i class="fas fa-check"></i>';
    document.body.appendChild(checkmark);
    
    // Posicionar en el centro de la fila
    const rowRect = row.getBoundingClientRect();
    const scrollTop = window.pageYOffset || document.documentElement.scrollTop;
    
    checkmark.style.left = `${rowRect.left + rowRect.width / 2}px`;
    checkmark.style.top = `${rowRect.top + rowRect.height / 2 + scrollTop}px`;
    
    // Animar la aparición de la marca con rebote
    gsap.fromTo(checkmark,
        { scale: 0, rotation: -45, opacity: 0 },
        { 
            scale: 1, 
            rotation: 0,
            opacity: 1, 
            duration: 0.7, 
            ease: "elastic.out(1, 0.5)"
        }
    );
    
    // Crear efecto de confeti mejorado
    createConfetti(rowRect.left + rowRect.width / 2, rowRect.top + scrollTop, 30);
    
    // Resaltar la fila completa
    gsap.fromTo(row,
        { backgroundColor: "rgba(6, 214, 160, 0)" },
        { 
            backgroundColor: "rgba(6, 214, 160, 0.1)", 
            duration: 0.5,
            yoyo: true,
            repeat: 1
        }
    );
    
    // Eliminar después de la animación
    setTimeout(() => {
        gsap.to(checkmark, {
            scale: 0,
            opacity: 0,
            duration: 0.3,
            onComplete: () => checkmark.remove()
        });
    }, 1500);
    
    // Actualizar la insignia de estado
    const statusBadge = document.getElementById(`status-${paperCode}`);
    if (statusBadge) {
        setTimeout(() => {
            statusBadge.textContent = 'Asignado';
            
            // Animar transición de estado
            const originalBackground = window.getComputedStyle(statusBadge).backgroundColor;
            
            gsap.fromTo(statusBadge,
                { 
                    backgroundColor: "rgba(6, 214, 160, 0.5)",
                    scale: 0.5,
                    opacity: 0
                },
                { 
                    backgroundColor: originalBackground,
                    scale: 1,
                    opacity: 1,
                    duration: 0.5,
                    ease: "back.out(1.7)",
                    onStart: () => {
                        statusBadge.classList.remove('status-pending');
                        statusBadge.classList.add('status-assigned');
                    }
                }
            );
        }, 800);
    }
}

// Crear animación de confeti mejorada
function createConfetti(x, y, count) {
    // Colores para el confeti
    const colors = [
        '#4361ee', '#3a0ca3', '#7209b7', '#f72585', 
        '#4cc9f0', '#4895ef', '#560bad', '#b5179e',
        '#06d6a0', '#ffd166', '#073b4c', '#118ab2'
    ];
    
    // Formas para el confeti
    const shapes = ['circle', 'square', 'triangle', 'line'];
    
    for (let i = 0; i < count; i++) {
        // Crear elemento de confeti
        const confetti = document.createElement('div');
        confetti.className = 'confetti-piece';
        
        // Seleccionar color y forma aleatorios
        const color = colors[Math.floor(Math.random() * colors.length)];
        const shape = shapes[Math.floor(Math.random() * shapes.length)];
        
        // Tamaño aleatorio
        const size = Math.random() * 10 + 5;
        
        // Estilo según forma
        confetti.style.position = 'fixed';
        confetti.style.zIndex = '1000';
        confetti.style.top = `${y}px`;
        confetti.style.left = `${x}px`;
        confetti.style.backgroundColor = color;
        confetti.style.width = `${size}px`;
        
        // Estilos específicos por forma
        if (shape === 'circle') {
            confetti.style.height = `${size}px`;
            confetti.style.borderRadius = '50%';
        } else if (shape === 'square') {
            confetti.style.height = `${size}px`;
        } else if (shape === 'triangle') {
            confetti.style.width = '0';
            confetti.style.height = '0';
            confetti.style.backgroundColor = 'transparent';
            confetti.style.borderLeft = `${size}px solid transparent`;
            confetti.style.borderRight = `${size}px solid transparent`;
            confetti.style.borderBottom = `${size * 1.5}px solid ${color}`;
        } else if (shape === 'line') {
            confetti.style.height = `${size * 2}px`;
            confetti.style.width = `${size / 3}px`;
        }
        
        // Agregar al documento
        document.body.appendChild(confetti);
        
        // Animar con GSAP para movimientos más naturales
        gsap.to(confetti, {
            x: (Math.random() - 0.5) * 200,
            y: window.innerHeight,
            rotation: Math.random() * 520,
            duration: 1 + Math.random() * 2,
            ease: "power1.out",
            onComplete: () => confetti.remove()
        });
    }
}

// Obtener iniciales de un nombre
function getInitials(name) {
    if (!name) return '-';
    
    const words = name.split(' ');
    let initials = '';
    
    for (const word of words) {
        if (word.length > 0) {
            initials += word[0].toUpperCase();
            if (initials.length >= 2) break;
        }
    }
    
    return initials;
}

// Guardar asignación en el servidor
function saveAssignment(paperCode, evaluator1, evaluator2, evaluator3) {
    // Mostrar indicador de carga
    const loadingIndicator = showLoadingOverlay(`Guardando asignación para ${paperCode}...`);
    
    $.ajax({
        url: window.location.href,
        type: 'POST',
        data: {
            ajax_action: 'save_assignment',
            paper_code: paperCode,
            evaluator1: evaluator1,
            evaluator2: evaluator2,
            evaluator3: evaluator3
        },
        dataType: 'json',
        success: function(response) {
            // Ocultar indicador de carga
            hideLoadingOverlay(loadingIndicator);
            
            if (response.success) {
                // Actualizar contadores de carga
                if (workloadData[evaluator1] !== undefined) workloadData[evaluator1]++;
                if (workloadData[evaluator2] !== undefined) workloadData[evaluator2]++;
                if (workloadData[evaluator3] !== undefined) workloadData[evaluator3]++;
                
                // Actualizar contadores de progreso
                updateProgressCounters();
                
                // Actualizar gráfico de carga
                initializeWorkloadChart();
                
                // Mostrar notificación de éxito
                showNotification('Asignación Guardada', 'Los evaluadores han sido asignados correctamente.', 'success');
            } else {
                showNotification('Error', response.message, 'error');
            }
        },
        error: function() {
            // Ocultar indicador de carga
            hideLoadingOverlay(loadingIndicator);
            showNotification('Error', 'Error en la comunicación con el servidor', 'error');
        }
    });
}

// Mostrar indicador de carga
function showLoadingOverlay(message) {
    const overlay = document.createElement('div');
    overlay.className = 'loading-overlay';
    overlay.innerHTML = `
        <div class="loading-container">
            <div class="loading-spinner"></div>
            <div class="loading-message">${message}</div>
        </div>
    `;
    
    // Estilo para el overlay
    overlay.style.position = 'fixed';
    overlay.style.top = '0';
    overlay.style.left = '0';
    overlay.style.width = '100%';
    overlay.style.height = '100%';
    overlay.style.backgroundColor = 'rgba(0, 0, 0, 0.5)';
    overlay.style.display = 'flex';
    overlay.style.justifyContent = 'center';
    overlay.style.alignItems = 'center';
    overlay.style.zIndex = '9999';
    overlay.style.opacity = '0';
    
    // Estilo para el contenedor
    const container = overlay.querySelector('.loading-container');
    container.style.backgroundColor = 'white';
    container.style.borderRadius = '8px';
    container.style.padding = '20px';
    container.style.boxShadow = '0 4px 20px rgba(0, 0, 0, 0.2)';
    container.style.display = 'flex';
    container.style.flexDirection = 'column';
    container.style.alignItems = 'center';
    container.style.gap = '15px';
    
    // Estilo para el spinner
    const spinner = overlay.querySelector('.loading-spinner');
    spinner.style.width = '40px';
    spinner.style.height = '40px';
    spinner.style.border = '4px solid #f3f3f3';
    spinner.style.borderTop = '4px solid #4361ee';
    spinner.style.borderRadius = '50%';
    spinner.style.animation = 'spin 1s linear infinite';
    
    // Agregar el overlay al documento
    document.body.appendChild(overlay);
    
    // Mostrar con animación
    gsap.to(overlay, {
        opacity: 1,
        duration: 0.3
    });
    
    // Agregar keyframe para la animación del spinner
    if (!document.querySelector('#spin-keyframes')) {
        const style = document.createElement('style');
        style.id = 'spin-keyframes';
        style.textContent = `
            @keyframes spin {
                0% { transform: rotate(0deg); }
                100% { transform: rotate(360deg); }
            }
        `;
        document.head.appendChild(style);
    }
    
    return overlay;
}

// Ocultar indicador de carga
function hideLoadingOverlay(overlay) {
    gsap.to(overlay, {
        opacity: 0,
        duration: 0.3,
        onComplete: () => overlay.remove()
    });
}

// Actualizar contadores de progreso con animación
function updateProgressCounters() {
    // Obtener los elementos del contador
    const pendingCount = document.getElementById('pending-count');
    const assignedCount = document.getElementById('assigned-count');
    const totalCount = document.getElementById('total-count');
    const progressBar = document.getElementById('progress-bar');
    
    if (!pendingCount || !assignedCount || !totalCount || !progressBar) return;
    
    // Calcular valores actuales
    const assigned = document.querySelectorAll('.status-badge.status-assigned').length;
    const total = parseInt(totalCount.textContent);
    const pending = total - assigned;
    
    // Animar actualizaciones de contador
    animateCounterValue(pendingCount, parseInt(pendingCount.textContent), pending);
    animateCounterValue(assignedCount, parseInt(assignedCount.textContent), assigned);
    
    // Actualizar barra de progreso con animación
    const percentage = (assigned / total) * 100;
    gsap.to(progressBar, {
        width: `${percentage}%`,
        duration: 1,
        ease: "elastic.out(1, 0.75)"
    });
    
    // Actualizar insignias de área
    document.querySelectorAll('.area-card').forEach(card => {
        const areaId = card.getAttribute('data-area');
        const areaPapers = card.querySelectorAll('.paper-row').length;
        const areaAssigned = card.querySelectorAll('.status-badge.status-assigned').length;
        const areaBadge = card.querySelector('.card-header .status-badge');
        
        if (areaBadge) {
            // Guardar texto original para animación
            const originalText = areaBadge.textContent;
            const newText = `${areaAssigned}/${areaPapers}`;
            
            if (originalText !== newText) {
                // Animar actualización de texto
                gsap.to(areaBadge, {
                    opacity: 0,
                    y: -10,
                    duration: 0.2,
                    onComplete: () => {
                        areaBadge.textContent = newText;
                        
                        gsap.to(areaBadge, {
                            opacity: 1,
                            y: 0,
                            duration: 0.3
                        });
                    }
                });
            }
            
            if (areaAssigned === areaPapers) {
                if (!areaBadge.classList.contains('status-assigned')) {
                    areaBadge.classList.remove('status-pending');
                    areaBadge.classList.add('status-assigned');
                    
                    // Celebrar asignación completa de área
                    if (!card.hasAttribute('data-celebrated') && areaAssigned > 0) {
                        card.setAttribute('data-celebrated', 'true');
                        
                        // Animación de celebración para el área
                        gsap.fromTo(card, 
                            { boxShadow: '0 0 0 2px rgba(6, 214, 160, 0)' },
                            { 
                                boxShadow: '0 0 0 2px rgba(6, 214, 160, 1), 0 5px 15px rgba(6, 214, 160, 0.3)',
                                duration: 0.5,
                                yoyo: true,
                                repeat: 1
                            }
                        );
                    }
                }
            } else {
                areaBadge.classList.remove('status-assigned');
                areaBadge.classList.add('status-pending');
                card.removeAttribute('data-celebrated');
            }
        }
    });
}

// Animar valores de contador con interpolación suave
function animateCounterValue(element, fromValue, toValue) {
    // No animar si no hay cambio
    if (fromValue === toValue) return;
    
    // Usar GSAP para animar el valor numérico
    const obj = { value: fromValue };
    
    gsap.to(obj, {
        value: toValue,
        duration: 1,
        ease: "elastic.out(1, 0.5)",
        onUpdate: function() {
            element.textContent = Math.round(obj.value);
        }
    });
    
    // Animar también el tamaño para dar efecto de pulso
    gsap.fromTo(element,
        { scale: 1 },
        { 
            scale: 1.2, 
            duration: 0.3,
            yoyo: true,
            repeat: 1
        }
    );
}

// Función para reiniciar todas las asignaciones
function resetAll() {
    // Mostrar indicador de carga
    const loadingIndicator = showLoadingOverlay("Reiniciando todas las asignaciones...");
    
    $.ajax({
        url: window.location.href,
        type: 'POST',
        data: {
            ajax_action: 'reset_all'
        },
        dataType: 'json',
        success: function(response) {
            // Ocultar indicador de carga
            hideLoadingOverlay(loadingIndicator);
            
            if (response.success) {
                showNotification('Reinicio Completado', response.message, 'success');
                
                // Reinicio visual gradual de elementos en lugar de recargar la página
                resetVisualElements();
                
                // Recargar página después de efectos visuales
                setTimeout(() => {
                    window.location.reload();
                }, 2000);
            } else {
                showNotification('Error', response.message, 'error');
            }
        },
        error: function() {
            // Ocultar indicador de carga
            hideLoadingOverlay(loadingIndicator);
            showNotification('Error', 'Error en la comunicación con el servidor', 'error');
        }
    });
}

// Reiniciar elementos visuales con animación
function resetVisualElements() {
    // Efecto de "barrido" sobre toda la interfaz
    const resetOverlay = document.createElement('div');
    resetOverlay.style.position = 'fixed';
    resetOverlay.style.top = '0';
    resetOverlay.style.left = '-100%';
    resetOverlay.style.width = '100%';
    resetOverlay.style.height = '100%';
    resetOverlay.style.background = 'linear-gradient(to right, rgba(6, 214, 160, 0.2), transparent)';
    resetOverlay.style.zIndex = '9000';
    resetOverlay.style.pointerEvents = 'none';
    
    document.body.appendChild(resetOverlay);
    
    // Animar barrido
    gsap.to(resetOverlay, {
        left: '100%',
        duration: 1.5,
        ease: "power2.inOut",
        onComplete: () => resetOverlay.remove()
    });
    
    // Reiniciar barra de progreso
    const progressBar = document.getElementById('progress-bar');
    if (progressBar) {
        gsap.to(progressBar, {
            width: '0%',
            duration: 1.5,
            ease: "power2.inOut"
        });
    }
    
    // Reiniciar contadores
    const pendingCount = document.getElementById('pending-count');
    const assignedCount = document.getElementById('assigned-count');
    const totalCount = document.getElementById('total-count');
    
    if (pendingCount && assignedCount && totalCount) {
        const total = parseInt(totalCount.textContent);
        animateCounterValue(pendingCount, parseInt(pendingCount.textContent), total);
        animateCounterValue(assignedCount, parseInt(assignedCount.textContent), 0);
    }
    
    // Reiniciar insignias de evaluador con animación en cascada
    document.querySelectorAll('.evaluator-badge.assigned').forEach((badge, index) => {
        gsap.to(badge, {
            backgroundColor: 'var(--gray-400)',
            scale: 0.5,
            opacity: 0.5,
            duration: 0.5,
            delay: index * 0.02,
            ease: "power2.inOut"
        });
    });
    
    // Reiniciar insignias de estado con animación
    document.querySelectorAll('.status-badge.status-assigned').forEach((badge, index) => {
        gsap.to(badge, {
            backgroundColor: 'rgba(239, 71, 111, 0.15)',
            y: 10,
            opacity: 0,
            duration: 0.3,
            delay: index * 0.01,
            ease: "power2.in",
            onComplete: () => {
                badge.classList.remove('status-assigned');
                badge.classList.add('status-pending');
                badge.textContent = 'Pendiente';
                
                gsap.fromTo(badge,
                    { y: -10, opacity: 0 },
                    { y: 0, opacity: 1, duration: 0.3, ease: "power2.out" }
                );
            }
        });
    });
    
    // Reiniciar barras del gráfico de carga
    document.querySelectorAll('.workload-value').forEach((bar, index) => {
        gsap.to(bar, {
            height: '0%',
            duration: 0.8,
            delay: index * 0.05,
            ease: "power3.inOut"
        });
    });
}

// Mostrar notificación con animación mejorada
function showNotification(title, message, type = 'success') {
    // Eliminar notificación existente
    const existingNotification = document.querySelector('.notification');
    if (existingNotification) {
        gsap.to(existingNotification, {
            opacity: 0,
            y: 20,
            duration: 0.3,
            onComplete: () => existingNotification.remove()
        });
    }
    
    // Crear elemento de notificación
    const notification = document.createElement('div');
    notification.className = 'notification';
    notification.style.transform = 'translateY(100px)';
    notification.style.opacity = '0';
    
    // Establecer icono según tipo
    let icon = 'check-circle';
    let color = 'var(--success)';
    
    if (type === 'error') {
        icon = 'exclamation-circle';
        color = 'var(--danger)';
    } else if (type === 'warning') {
        icon = 'exclamation-triangle';
        color = 'var(--warning)';
    } else if (type === 'info') {
        icon = 'info-circle';
        color = 'var(--info)';
    }
    
    // Crear contenido de notificación
    notification.innerHTML = `
        <div class="notification-icon" style="background: linear-gradient(135deg, ${color}, ${color}CC)">
            <i class="fas fa-${icon}"></i>
        </div>
        <div class="notification-content">
            <div class="notification-title">${title}</div>
            <div class="notification-message">${message}</div>
        </div>
        <button class="notification-close">
            <i class="fas fa-times"></i>
        </button>
    `;
    
    // Agregar al documento
    document.body.appendChild(notification);
    
    // Mostrar con animación
    gsap.to(notification, {
        opacity: 1,
        y: 0,
        duration: 0.5,
        ease: "back.out(1.7)"
    });
    
    // Agregar funcionalidad de cierre
    notification.querySelector('.notification-close').addEventListener('click', () => {
        gsap.to(notification, {
            opacity: 0,
            x: 100,
            duration: 0.3,
            ease: "power3.in",
            onComplete: () => notification.remove()
        });
    });
    
    // Auto-cerrar después de 5 segundos
    setTimeout(() => {
        if (document.body.contains(notification)) {
            gsap.to(notification, {
                opacity: 0,
                y: 20,
                duration: 0.5,
                onComplete: () => notification.remove()
            });
        }
    }, 5000);
}

// Mostrar animación de asignación automática
function showAssignmentAnimation() {
    animationInProgress = true;
    
    // Crear contenedor de animación de algoritmo
    const animationContainer = document.createElement('div');
    animationContainer.className = 'algorithm-animation';
    
    // Crear contenido
    animationContainer.innerHTML = `
        <h2 class="algorithm-title">Asignando Evaluadores de Manera Equitativa</h2>
        <div class="algorithm-visualization"></div>
        <div class="algorithm-status">
            Inicializando algoritmo de asignación
            <div class="loading-dots">
                <span></span>
                <span></span>
                <span></span>
            </div>
        </div>
        <div class="algorithm-progress">
            <div class="algorithm-progress-value"></div>
        </div>
        <button class="algorithm-close"><i class="fas fa-times"></i></button>
    `;
    
    // Agregar al documento
    document.body.appendChild(animationContainer);
    
    // Impedir desplazamiento
    document.body.style.overflow = 'hidden';
    
    // Mostrar animación con fade in
    gsap.fromTo(animationContainer,
        { opacity: 0 },
        { opacity: 1, duration: 0.5, ease: "power2.out" }
    );
    
    // Funcionalidad de botón de cierre
    animationContainer.querySelector('.algorithm-close').addEventListener('click', () => {
        gsap.to(animationContainer, {
            opacity: 0,
            duration: 0.5,
            ease: "power2.in",
            onComplete: () => {
                animationContainer.remove();
                document.body.style.overflow = '';
                animationInProgress = false;
            }
        });
    });
    
    // Inicializar visualización
    initializeAlgorithmVisualization(animationContainer);
    
    // Ejecutar asignación real después de la animación
    setTimeout(() => {
        autoAssign();
    }, 6000);
}

// Inicializar visualización del algoritmo con efectos 3D
function initializeAlgorithmVisualization(container) {
    const visualization = container.querySelector('.algorithm-visualization');
    const status = container.querySelector('.algorithm-status');
    const progressValue = container.querySelector('.algorithm-progress-value');
    
    // Agregar efecto de "grid" para dar profundidad
    const grid = document.createElement('div');
    grid.className = 'algorithm-grid';
    grid.style.position = 'absolute';
    grid.style.top = '0';
    grid.style.left = '0';
    grid.style.width = '100%';
    grid.style.height = '100%';
    grid.style.backgroundImage = 'radial-gradient(circle, rgba(255,255,255,0.1) 1px, transparent 1px)';
    grid.style.backgroundSize = '30px 30px';
    grid.style.opacity = '0.3';
    
    visualization.appendChild(grid);
    
    // Crear nodos de papel y evaluador
    const papers = [];
    const evaluators = [];
    
    // Agregar nodos de papel (representando resúmenes a asignar)
    document.querySelectorAll('.paper-row').forEach((row, index) => {
        if (index > 15) return; // Limitar para evitar saturación
        
        const paperCode = row.getAttribute('data-paper');
        if (!paperCode) return;
        
        // Omitir si ya está asignado
        const statusBadge = row.querySelector('.status-badge');
        if (statusBadge && statusBadge.classList.contains('status-assigned')) return;
        
        const paperNode = document.createElement('div');
        paperNode.className = 'paper-node';
        paperNode.textContent = paperCode;
        paperNode.style.left = `${Math.random() * 40 + 5}%`;
        paperNode.style.top = `${Math.random() * 70 + 10}%`;
        paperNode.style.opacity = '0';
        paperNode.style.scale = '0.5';
        
        visualization.appendChild(paperNode);
        papers.push(paperNode);
        
        // Animar aparición con retardo
        gsap.to(paperNode, {
            opacity: 1,
            scale: 1,
            duration: 0.5,
            delay: index * 0.05,
            ease: "back.out(1.7)"
        });
    });
    
    // Agregar nodos de evaluador con animación mejorada
    activeEvaluators.forEach((evaluator, index) => {
        if (index > 15) return; // Limitar para evitar saturación
        
        const evaluatorNode = document.createElement('div');
        evaluatorNode.className = 'evaluator-node';
        evaluatorNode.textContent = getInitials(evaluator.nombre);
        evaluatorNode.title = evaluator.nombre;
        evaluatorNode.style.right = `${Math.random() * 40 + 5}%`;
        evaluatorNode.style.top = `${Math.random() * 70 + 10}%`;
        evaluatorNode.style.opacity = '0';
        evaluatorNode.style.scale = '0.5';
        
        visualization.appendChild(evaluatorNode);
        evaluators.push(evaluatorNode);
        
        // Animar aparición con retardo y rebote
        gsap.to(evaluatorNode, {
            opacity: 1,
            scale: 1,
            duration: 0.5,
            delay: 0.5 + index * 0.05,
            ease: "back.out(1.7)"
        });
    });
    
    // Secuencia de animación
    const steps = [
        "Analizando trabajos pendientes por asignar...",
        "Calculando carga actual de evaluadores...",
        "Aplicando algoritmo de distribución equitativa...",
        "Verificando restricciones de asignación única...",
        "Optimizando distribución de carga de trabajo...",
        "Finalizando asignaciones..."
    ];
    
    // Agregar partículas de fondo para efecto futurista
    for (let i = 0; i < 30; i++) {
        const particle = document.createElement('div');
        particle.className = 'algorithm-particle';
        particle.style.position = 'absolute';
        particle.style.width = `${Math.random() * 4 + 1}px`;
        particle.style.height = `${Math.random() * 4 + 1}px`;
        particle.style.backgroundColor = 'rgba(67, 97, 238, 0.3)';
        particle.style.borderRadius = '50%';
        particle.style.left = `${Math.random() * 100}%`;
        particle.style.top = `${Math.random() * 100}%`;
        
        visualization.appendChild(particle);
        
        // Animar partícula
        gsap.to(particle, {
            x: Math.random() * 200 - 100,
            y: Math.random() * 200 - 100,
            opacity: Math.random() * 0.5 + 0.1,
            duration: Math.random() * 5 + 3,
            repeat: -1,
            yoyo: true,
            ease: "sine.inOut"
        });
    }
    
    // Animar cada paso con efectos avanzados
    steps.forEach((step, index) => {
        setTimeout(() => {
            // Mostrar texto animado
            gsap.fromTo(status,
                { opacity: 0.5, y: 10 },
                {
                    opacity: 1,
                    y: 0,
                    duration: 0.3,
                    onStart: () => {
                        status.innerHTML = `${step} <div class="loading-dots"><span></span><span></span><span></span></div>`;
                    }
                }
            );
            
            // Actualizar barra de progreso con animación elástica
            const progress = (index + 1) / steps.length * 100;
            gsap.to(progressValue, {
                width: `${progress}%`,
                duration: 0.8,
                ease: "elastic.out(1, 0.75)"
            });
            
            // Agregar conexiones entre papeles y evaluadores
            if (index > 1) {
                // Número de conexiones escalando con el paso
                const connectionsCount = Math.min(5, Math.floor((index + 1) * 1.5));
                
                for (let i = 0; i < connectionsCount; i++) {
                    setTimeout(() => {
                        if (papers.length && evaluators.length) {
                            // Seleccionar aleatoriamente papel y evaluador para conectar
                            const paperIndex = Math.floor(Math.random() * papers.length);
                            const evaluatorIndex = Math.floor(Math.random() * evaluators.length);
                            
                            connectNodesAdvanced(
                                papers[paperIndex], 
                                evaluators[evaluatorIndex],
                                visualization
                            );
                        }
                    }, i * 300);
                }
            }
            
            // Efectos especiales en pasos específicos
            if (index === 2) {
                // Efecto de "scan" en el paso de algoritmo
                const scanEffect = document.createElement('div');
                scanEffect.style.position = 'absolute';
                scanEffect.style.top = '0';
                scanEffect.style.left = '-100%';
                scanEffect.style.width = '100%';
                scanEffect.style.height = '100%';
                scanEffect.style.background = 'linear-gradient(to right, transparent, rgba(67, 97, 238, 0.2), transparent)';
                scanEffect.style.zIndex = '5';
                
                visualization.appendChild(scanEffect);
                
                gsap.to(scanEffect, {
                    left: '100%',
                    duration: 2,
                    ease: "power1.inOut",
                    onComplete: () => scanEffect.remove()
                });
            }
            
            if (index === 4) {
                // Destacar evaluadores con menos carga
                evaluators.forEach((node, idx) => {
                    if (idx < 3) { // Primeros 3 evaluadores (menos carga simulada)
                        gsap.to(node, {
                            boxShadow: '0 0 15px rgba(6, 214, 160, 0.8)',
                            scale: 1.1,
                            duration: 0.5,
                            yoyo: true,
                            repeat: 1
                        });
                    }
                });
            }
            
        }, index * 1000);
    });
    
    // Completar animación con efecto especial
    setTimeout(() => {
        // Efecto de "completado"
        const completeEffect = document.createElement('div');
        completeEffect.style.position = 'absolute';
        completeEffect.style.top = '0';
        completeEffect.style.left = '0';
        completeEffect.style.width = '100%';
        completeEffect.style.height = '100%';
        completeEffect.style.background = 'radial-gradient(circle, rgba(6, 214, 160, 0.3) 0%, transparent 70%)';
        completeEffect.style.zIndex = '5';
        completeEffect.style.opacity = '0';
        
        visualization.appendChild(completeEffect);
        
        gsap.to(completeEffect, {
            opacity: 1,
            duration: 0.5,
            ease: "power2.out",
            onComplete: () => {
                // Actualizar texto de estado
                status.innerHTML = `<span style="color: var(--success); font-weight: bold;">¡Asignación completada correctamente!</span>`;
                
                // Actualizar barra a 100%
                gsap.to(progressValue, {
                    width: '100%',
                    duration: 0.8,
                    ease: "elastic.out(1, 0.75)"
                });
                
                // Animar desvanecimiento del efecto
                gsap.to(completeEffect, {
                    opacity: 0,
                    delay: 1,
                    duration: 0.8
                });
            }
        });
        
        // Mostrar marca de verificación de éxito
        const successMark = document.createElement('div');
        successMark.className = 'success-checkmark';
        successMark.innerHTML = '<i class="fas fa-check"></i>';
        document.body.appendChild(successMark);
        
        setTimeout(() => {
            gsap.fromTo(successMark,
                { 
                    scale: 0, 
                    opacity: 0,
                    rotation: -45
                },
                { 
                    scale: 1, 
                    opacity: 1,
                    rotation: 0,
                    duration: 0.7,
                    ease: "elastic.out(1, 0.5)"
                }
            );
            
            setTimeout(() => {
                gsap.to(successMark, {
                    scale: 0,
                    opacity: 0,
                    rotation: 45,
                    duration: 0.5,
                    onComplete: () => successMark.remove()
                });
            }, 1500);
        }, 500);
        
        // Cerrar animación
        setTimeout(() => {
            gsap.to(container, {
                opacity: 0,
                duration: 0.5,
                ease: "power2.in",
                onComplete: () => {
                    container.remove();
                    document.body.style.overflow = '';
                    animationInProgress = false;
                    
                    // Recargar la página para mostrar resultados
                    window.location.reload();
                }
            });
        }, 3000);
    }, steps.length * 1000 + 500);
}

// Conectar nodos en la visualización del algoritmo con efectos avanzados
function connectNodesAdvanced(nodeA, nodeB, container) {
    const nodeARect = nodeA.getBoundingClientRect();
    const nodeBRect = nodeB.getBoundingClientRect();
    const containerRect = container.getBoundingClientRect();
    
    // Calcular posiciones relativas al contenedor
    const startX = nodeARect.left - containerRect.left + nodeARect.width / 2;
    const startY = nodeARect.top - containerRect.top + nodeARect.height / 2;
    const endX = nodeBRect.left - containerRect.left + nodeBRect.width / 2;
    const endY = nodeBRect.top - containerRect.top + nodeBRect.height / 2;
    
    // Crear múltiples puntos de conexión para efecto avanzado
    const pointsCount = 5;
    
    // Crear puntos de la conexión
    for (let i = 0; i < pointsCount; i++) {
        // Crear punto
        const point = document.createElement('div');
        point.className = 'connection-dot';
        point.style.width = '8px';
        point.style.height = '8px';
        point.style.position = 'absolute';
        point.style.borderRadius = '50%';
        point.style.backgroundColor = '#4361ee';
        point.style.opacity = '0';
        point.style.zIndex = '10';
        
        container.appendChild(point);
        
        // Animar punto a lo largo de la trayectoria
        const delay = i * 0.1;
        const duration = 0.8;
        
        // Punto de control para una curva Bezier
        const controlX = (startX + endX) / 2;
        const controlY = Math.min(startY, endY) - 30;
        
        // Timeline para cada punto
        const tl = gsap.timeline();
        
        // Posición inicial
        tl.set(point, { left: startX, top: startY, scale: 0.5 });
        
        // Mostrar punto
        tl.to(point, { 
            opacity: 0.8, 
            scale: 1, 
            duration: 0.2,
            delay: delay
        });
        
        // Animar a lo largo de la trayectoria
        tl.to(point, {
            motionPath: {
                path: [
                    {x: startX, y: startY},
                    {x: controlX, y: controlY},
                    {x: endX, y: endY}
                ],
                curviness: 1.5
            },
            ease: "power1.inOut",
            duration: duration
        });
        
        // Eliminar punto al llegar al destino
        tl.to(point, {
            opacity: 0,
            scale: 2,
            duration: 0.2,
            onComplete: () => point.remove()
        });
    }
    
    // Crear línea de conexión permanente
    const link = document.createElement('div');
    link.className = 'visualization-link';
    container.appendChild(link);
    
    // Calcular ángulo y distancia
    const angle = Math.atan2(endY - startY, endX - startX);
    const distance = Math.sqrt(Math.pow(endX - startX, 2) + Math.pow(endY - startY, 2));
    
    // Posicionar y rotar línea
    link.style.width = `${distance}px`;
    link.style.left = `${startX}px`;
    link.style.top = `${startY}px`;
    link.style.transform = `rotate(${angle}rad)`;
    
    // Animar aparición de la línea con retraso
    link.style.opacity = '0';
    link.style.transformOrigin = 'left center';
    link.style.transform = `rotate(${angle}rad) scaleX(0)`;
    
    gsap.to(link, {
        opacity: 0.7,
        scaleX: 1,
        duration: 0.7,
        delay: 0.5,
        ease: "power2.out"
    });
    
    // Pulsar los nodos conectados
    gsap.fromTo(nodeA, 
        { boxShadow: '0 0 0 0 rgba(67, 97, 238, 0.7)' },
        { 
            boxShadow: '0 0 15px 5px rgba(67, 97, 238, 0)',
            scale: 1.2,
            yoyo: true,
            repeat: 1,
            duration: 0.4
        }
    );
    
    gsap.fromTo(nodeB, 
        { boxShadow: '0 0 0 0 rgba(6, 214, 160, 0.7)' },
        { 
            boxShadow: '0 0 15px 5px rgba(6, 214, 160, 0)',
            scale: 1.2,
            yoyo: true,
            repeat: 1,
            duration: 0.4,
            delay: 0.6
        }
    );
}

// Auto-asignar evaluadores
function autoAssign() {
    $.ajax({
        url: window.location.href,
        type: 'POST',
        data: {
            ajax_action: 'auto_assign'
        },
        dataType: 'json',
        success: function(response) {
            // Esto es manejado por la secuencia de animación
            console.log("Asignación completada:", response);
        },
        error: function() {
            showNotification('Error', 'Error en la comunicación con el servidor', 'error');
            animationInProgress = false;
            
            // Restaurar interfaz en caso de error
            document.body.style.overflow = '';
            const animContainer = document.querySelector('.algorithm-animation');
            if (animContainer) {
                animContainer.remove();
            }
        }
    });
}

// Agregar esta función al principio del archivo enhanced-script.js
document.addEventListener('DOMContentLoaded', function() {
    console.log("Inicializando efectos de botones...");

    // Aplicar efectos avanzados a los botones
    initializeButtonEffects();
    
    // Resto del código de inicialización...
});

// Agregar esta función después de la función initializeActionButtons()
function initializeButtonEffects() {
    // Obtener todos los botones con clase button-3d
    const buttons = document.querySelectorAll('.button-3d');
    
    buttons.forEach(button => {
        // Efecto de onda al hacer clic
        button.addEventListener('click', function(e) {
            // Crear efecto de onda
            const effect = this.querySelector('.button-effect');
            
            // Reiniciar animación
            effect.style.animation = 'none';
            
            // Calcular el tamaño de la onda (diagonal del botón para cubrir toda el área)
            const buttonWidth = this.offsetWidth;
            const buttonHeight = this.offsetHeight;
            const diameter = Math.max(buttonWidth, buttonHeight) * 2;
            
            // Posicionar y dimensionar efecto
            effect.style.width = `${diameter}px`;
            effect.style.height = `${diameter}px`;
            
            // Posición relativa al clic dentro del botón
            const rect = this.getBoundingClientRect();
            const offsetX = e.clientX - rect.left;
            const offsetY = e.clientY - rect.top;
            
            effect.style.left = `${offsetX}px`;
            effect.style.top = `${offsetY}px`;
            
            // Aplicar animación
            effect.style.opacity = '0.7';
            effect.style.transform = 'translate(-50%, -50%) scale(0)';
            
            // Forzar reflow
            void effect.offsetWidth;
            
            // Animar con GSAP
            gsap.to(effect, {
                opacity: 0,
                scale: 1,
                duration: 0.6,
                ease: "power1.out"
            });
        });
        
        // Efecto hover 3D
        button.addEventListener('mousemove', function(e) {
            const rect = this.getBoundingClientRect();
            const x = e.clientX - rect.left;
            const y = e.clientY - rect.top;
            
            // Calcular rotación (ligera)
            const centerX = rect.width / 2;
            const centerY = rect.height / 2;
            
            const rotateX = (y - centerY) / 15;
            const rotateY = (centerX - x) / 15;
            
            // Aplicar transformación
            gsap.to(this, {
                rotationX: rotateX,
                rotationY: rotateY,
                duration: 0.3,
                ease: "power1.out"
            });
        });
        
        // Restablecer al salir
        button.addEventListener('mouseleave', function() {
            gsap.to(this, {
                rotationX: 0,
                rotationY: 0,
                duration: 0.5,
                ease: "elastic.out(1, 0.7)"
            });
        });
        
        // Añadir un efecto inicial de atención
        const delay = button.id === 'assign-btn' ? 1 : 2;
        
        setTimeout(() => {
            gsap.fromTo(button,
                { y: 0, boxShadow: '0 6px 12px rgba(0, 0, 0, 0.1), 0 3px 0 rgba(0, 0, 0, 0.1)' },
                {
                    y: -5,
                    boxShadow: '0 15px 25px rgba(0, 0, 0, 0.15), 0 6px 0 rgba(0, 0, 0, 0.1)',
                    duration: 0.4,
                    repeat: 1,
                    yoyo: true,
                    ease: "power2.inOut"
                }
            );
        }, delay * 1000);
    });
    
    // Efecto especial para el botón principal de asignación
    const assignBtn = document.getElementById('assign-btn');
    if (assignBtn) {
        // Añadir brillo intermitente para el botón de asignación
        const highlight = document.createElement('div');
        highlight.className = 'button-highlight';
        highlight.style.position = 'absolute';
        highlight.style.top = '0';
        highlight.style.left = '0';
        highlight.style.width = '100%';
        highlight.style.height = '100%';
        highlight.style.background = 'linear-gradient(90deg, transparent, rgba(255,255,255,0.2), transparent)';
        highlight.style.pointerEvents = 'none';
        highlight.style.opacity = '0';
        
        assignBtn.appendChild(highlight);
        
        // Animar brillo periódicamente
        setInterval(() => {
            gsap.fromTo(highlight,
                { opacity: 0, left: '-100%' },
                {
                    opacity: 0.8,
                    left: '100%',
                    duration: 1.5,
                    ease: "power2.inOut"
                }
            );
        }, 5000);
    }
}

// Ejecutar cuando el DOM está completamente cargado
document.addEventListener('DOMContentLoaded', function() {
    console.log("DOM cargado - inicializando interfaz mejorada...");
    
    // La inicialización ocurrirá a través del lado PHP mediante initializeEvaluators
    
      // Validar si GSAP está disponible
    if (typeof gsap === 'undefined') {
        console.error("ERROR: GSAP no está disponible. Los efectos de animación no funcionarán.");
        return; // Detener la ejecución si GSAP no está disponible
    } else {
        console.log("GSAP cargado correctamente, versión:", gsap.version);
    }
    
    // Añadir efecto de transición de página
    gsap.from('.container', {
        opacity: 0,
        y: 20,
        duration: 0.6,
        ease: "power2.out",
        stagger: 0.1
    });
    
    // Añadir el contenedor del gráfico si no existe
    const workloadCard = document.getElementById('evaluator-workload');
    if (workloadCard) {
        const cardBody = workloadCard.querySelector('.card-body');
        if (cardBody && !document.getElementById('workload-chart')) {
            const chartDiv = document.createElement('div');
            chartDiv.id = 'workload-chart';
            chartDiv.className = 'workload-chart';
            // Insertarlo como primer hijo del cardBody
            if (cardBody.firstChild) {
                cardBody.insertBefore(chartDiv, cardBody.firstChild);
            } else {
                cardBody.appendChild(chartDiv);
            }
            console.log("Contenedor de gráfico de carga añadido");
        }
    }
});


