/**
 * Unit tests for Queue UI functionality
 * Tests queue management, button handlers, display updates, and statistics
 */

import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest';

// Mock DOM setup
function setupDOM() {
    document.body.innerHTML = `
        <!-- Queue controls -->
        <button id="start-queue-btn">Start Queue</button>
        <button id="stop-queue-btn">Stop Queue</button>
        <button id="clear-completed-btn">Clear Completed</button>
        <button id="clear-failed-btn">Clear Failed</button>
        <button id="clear-pending-btn">Clear Pending</button>
        <button id="retry-all-btn">Retry All</button>
        
        <!-- Queue statistics -->
        <span id="pending-count">0</span>
        <span id="active-count">0</span>
        <span id="completed-count">0</span>
        <span id="failed-count">0</span>
        <span id="total-count">0</span>
        
        <!-- Queue display -->
        <div id="pending-queue"></div>
        <div id="active-downloads"></div>
        <div id="completed-queue"></div>
        <div id="failed-queue"></div>
        
        <!-- Modal -->
        <div id="confirm-modal" class="modal" style="display: none;">
            <div class="modal-overlay"></div>
            <div class="modal-content">
                <h3 id="confirm-title"></h3>
                <p id="confirm-message"></p>
                <button id="confirm-ok">OK</button>
                <button id="confirm-cancel">Cancel</button>
                <button id="close-confirm">×</button>
            </div>
        </div>
        
        <!-- Toast -->
        <div id="toast" class="toast"></div>
    `;
}

// Mock AniWorld global object
function setupMockAniWorld() {
    global.AniWorld = {
        Constants: {
            API: {
                QUEUE_STATUS: '/api/queue/status',
                QUEUE_START: '/api/queue/start',
                QUEUE_STOP: '/api/queue/stop',
                QUEUE_REMOVE: '/api/queue/remove',
                QUEUE_RETRY: '/api/queue/retry',
                QUEUE_COMPLETED: '/api/queue/completed',
                QUEUE_FAILED: '/api/queue/failed',
                QUEUE_PENDING: '/api/queue/pending'
            }
        },
        ApiClient: {
            get: vi.fn(),
            post: vi.fn(),
            delete: vi.fn()
        },
        UI: {
            showConfirmModal: vi.fn(),
            hideConfirmModal: vi.fn(),
            showToast: vi.fn()
        },
        Theme: {
            init: vi.fn(),
            toggle: vi.fn()
        },
        Auth: {
            checkAuth: vi.fn().mockResolvedValue(true),
            logout: vi.fn()
        },
        WebSocketClient: {
            init: vi.fn()
        },
        QueueSocketHandler: {
            init: vi.fn()
        },
        QueueRenderer: {
            updateQueueDisplay: vi.fn(),
            updateDownloadProgress: vi.fn(),
            renderQueueItem: vi.fn()
        },
        ProgressHandler: {
            processPendingProgressUpdates: vi.fn(),
            updateProgress: vi.fn()
        },
        QueueAPI: {
            loadQueueData: vi.fn(),
            startQueue: vi.fn(),
            stopQueue: vi.fn(),
            removeFromQueue: vi.fn(),
            retryDownloads: vi.fn(),
            clearCompleted: vi.fn(),
            clearFailed: vi.fn(),
            clearPending: vi.fn()
        }
    };
}

describe('Queue API - Data Loading', () => {
    beforeEach(() => {
        setupDOM();
        setupMockAniWorld();
    });
    
    afterEach(() => {
        vi.restoreAllMocks();
    });
    
    it('should load queue data successfully', async () => {
        const mockData = {
            status: {
                is_running: false,
                current_download: null,
                pending_items: [],
                active_downloads: [],
                completed_items: [],
                failed_items: []
            },
            statistics: {
                pending: 0,
                active: 0,
                completed: 0,
                failed: 0,
                total: 0
            }
        };
        
        const mockResponse = {
            json: vi.fn().mockResolvedValue(mockData)
        };
        global.AniWorld.ApiClient.get.mockResolvedValue(mockResponse);
        
        const data = await global.AniWorld.QueueAPI.loadQueueData();
        
        expect(global.AniWorld.ApiClient.get).toHaveBeenCalledWith('/api/queue/status');
        expect(data).toHaveProperty('statistics');
        expect(data.statistics.total).toBe(0);
    });
    
    it('should handle API error gracefully', async () => {
        global.AniWorld.ApiClient.get.mockRejectedValue(new Error('Network error'));
        
        const data = await global.AniWorld.QueueAPI.loadQueueData();
        
        expect(data).toBeNull();
    });
    
    it('should transform nested API response structure', async () => {
        const mockData = {
            status: {
                is_running: true,
                pending_items: [{ id: '1' }]
            },
            statistics: {
                pending: 1,
                active: 0,
                completed: 0,
                failed: 0,
                total: 1
            }
        };
        
        const mockResponse = {
            json: vi.fn().mockResolvedValue(mockData)
        };
        global.AniWorld.ApiClient.get.mockResolvedValue(mockResponse);
        
        const data = await global.AniWorld.QueueAPI.loadQueueData();
        
        expect(data.is_running).toBe(true);
        expect(data.pending_items).toHaveLength(1);
        expect(data.statistics.pending).toBe(1);
    });
});

describe('Queue API - Queue Control', () => {
    beforeEach(() => {
        setupDOM();
        setupMockAniWorld();
    });
    
    afterEach(() => {
        vi.restoreAllMocks();
    });
    
    it('should start queue successfully', async () => {
        const mockResponse = {
            json: vi.fn().mockResolvedValue({ message: 'Queue started' })
        };
        global.AniWorld.ApiClient.post.mockResolvedValue(mockResponse);
        
        const result = await global.AniWorld.QueueAPI.startQueue();
        
        expect(global.AniWorld.ApiClient.post).toHaveBeenCalledWith('/api/queue/start', {});
        expect(result.message).toBe('Queue started');
    });
    
    it('should stop queue successfully', async () => {
        const mockResponse = {
            json: vi.fn().mockResolvedValue({ message: 'Queue stopped' })
        };
        global.AniWorld.ApiClient.post.mockResolvedValue(mockResponse);
        
        const result = await global.AniWorld.QueueAPI.stopQueue();
        
        expect(global.AniWorld.ApiClient.post).toHaveBeenCalledWith('/api/queue/stop', {});
        expect(result.message).toBe('Queue stopped');
    });
    
    it('should handle start queue error', async () => {
        global.AniWorld.ApiClient.post.mockRejectedValue(new Error('Already running'));
        
        await expect(global.AniWorld.QueueAPI.startQueue()).rejects.toThrow('Already running');
    });
    
    it('should handle stop queue error', async () => {
        global.AniWorld.ApiClient.post.mockRejectedValue(new Error('Not running'));
        
        await expect(global.AniWorld.QueueAPI.stopQueue()).rejects.toThrow('Not running');
    });
});

describe('Queue API - Item Management', () => {
    beforeEach(() => {
        setupDOM();
        setupMockAniWorld();
    });
    
    afterEach(() => {
        vi.restoreAllMocks();
    });
    
    it('should remove item from queue', async () => {
        const mockResponse = {
            status: 204
        };
        global.AniWorld.ApiClient.delete.mockResolvedValue(mockResponse);
        
        const result = await global.AniWorld.QueueAPI.removeFromQueue('item-123');
        
        expect(global.AniWorld.ApiClient.delete).toHaveBeenCalledWith('/api/queue/remove/item-123');
        expect(result).toBe(true);
    });
    
    it('should retry failed downloads', async () => {
        const mockResponse = {
            json: vi.fn().mockResolvedValue({ retried: 2 })
        };
        global.AniWorld.ApiClient.post.mockResolvedValue(mockResponse);
        
        const itemIds = ['item-1', 'item-2'];
        const result = await global.AniWorld.QueueAPI.retryDownloads(itemIds);
        
        expect(global.AniWorld.ApiClient.post).toHaveBeenCalledWith('/api/queue/retry', { item_ids: itemIds });
        expect(result.retried).toBe(2);
    });
    
    it('should clear completed downloads', async () => {
        const mockResponse = {
            json: vi.fn().mockResolvedValue({ cleared: 5 })
        };
        global.AniWorld.ApiClient.delete.mockResolvedValue(mockResponse);
        
        const result = await global.AniWorld.QueueAPI.clearCompleted();
        
        expect(global.AniWorld.ApiClient.delete).toHaveBeenCalledWith('/api/queue/completed');
        expect(result.cleared).toBe(5);
    });
    
    it('should clear failed downloads', async () => {
        const mockResponse = {
            json: vi.fn().mockResolvedValue({ cleared: 3 })
        };
        global.AniWorld.ApiClient.delete.mockResolvedValue(mockResponse);
        
        const result = await global.AniWorld.QueueAPI.clearFailed();
        
        expect(global.AniWorld.ApiClient.delete).toHaveBeenCalledWith('/api/queue/failed');
        expect(result.cleared).toBe(3);
    });
    
    it('should clear pending downloads', async () => {
        const mockResponse = {
            json: vi.fn().mockResolvedValue({ cleared: 2 })
        };
        global.AniWorld.ApiClient.delete.mockResolvedValue(mockResponse);
        
        const result = await global.AniWorld.QueueAPI.clearPending();
        
        expect(global.AniWorld.ApiClient.delete).toHaveBeenCalledWith('/api/queue/pending');
        expect(result.cleared).toBe(2);
    });
});

describe('Queue Renderer - Statistics Display', () => {
    beforeEach(() => {
        setupDOM();
        setupMockAniWorld();
    });
    
    afterEach(() => {
        vi.restoreAllMocks();
    });
    
    it('should update queue statistics display', () => {
        const data = {
            statistics: {
                pending: 5,
                active: 2,
                completed: 10,
                failed: 1,
                total: 18
            }
        };
        
        // Manually update DOM (simulating renderer behavior)
        document.getElementById('pending-count').textContent = data.statistics.pending;
        document.getElementById('active-count').textContent = data.statistics.active;
        document.getElementById('completed-count').textContent = data.statistics.completed;
        document.getElementById('failed-count').textContent = data.statistics.failed;
        document.getElementById('total-count').textContent = data.statistics.total;
        
        expect(document.getElementById('pending-count').textContent).toBe('5');
        expect(document.getElementById('active-count').textContent).toBe('2');
        expect(document.getElementById('completed-count').textContent).toBe('10');
        expect(document.getElementById('failed-count').textContent).toBe('1');
        expect(document.getElementById('total-count').textContent).toBe('18');
    });
    
    it('should handle zero statistics', () => {
        const data = {
            statistics: {
                pending: 0,
                active: 0,
                completed: 0,
                failed: 0,
                total: 0
            }
        };
        
        document.getElementById('pending-count').textContent = data.statistics.pending;
        document.getElementById('active-count').textContent = data.statistics.active;
        document.getElementById('completed-count').textContent = data.statistics.completed;
        document.getElementById('failed-count').textContent = data.statistics.failed;
        document.getElementById('total-count').textContent = data.statistics.total;
        
        expect(document.getElementById('pending-count').textContent).toBe('0');
        expect(document.getElementById('active-count').textContent).toBe('0');
        expect(document.getElementById('completed-count').textContent).toBe('0');
        expect(document.getElementById('failed-count').textContent).toBe('0');
        expect(document.getElementById('total-count').textContent).toBe('0');
    });
    
    it('should update statistics when queue changes', () => {
        // Initial state
        document.getElementById('pending-count').textContent = '5';
        expect(document.getElementById('pending-count').textContent).toBe('5');
        
        // After starting download (one moves from pending to active)
        document.getElementById('pending-count').textContent = '4';
        document.getElementById('active-count').textContent = '1';
        
        expect(document.getElementById('pending-count').textContent).toBe('4');
        expect(document.getElementById('active-count').textContent).toBe('1');
    });
});

describe('Queue Renderer - Queue Display', () => {
    beforeEach(() => {
        setupDOM();
        setupMockAniWorld();
    });
    
    afterEach(() => {
        vi.restoreAllMocks();
    });
    
    it('should render pending queue items', () => {
        const pendingItems = [
            { id: '1', serie_name: 'Anime 1', episode: 1, status: 'pending' },
            { id: '2', serie_name: 'Anime 2', episode: 2, status: 'pending' }
        ];
        
        const pendingQueue = document.getElementById('pending-queue');
        pendingQueue.innerHTML = pendingItems.map(item => 
            `<div class="queue-item" data-id="${item.id}">${item.serie_name} - Episode ${item.episode}</div>`
        ).join('');
        
        expect(pendingQueue.children.length).toBe(2);
        expect(pendingQueue.children[0].textContent).toBe('Anime 1 - Episode 1');
        expect(pendingQueue.children[1].textContent).toBe('Anime 2 - Episode 2');
    });
    
    it('should render active downloads with progress', () => {
        const activeDownloads = [
            { id: '1', serie_name: 'Anime 1', episode: 1, progress: 45, status: 'active' }
        ];
        
        const activeQueue = document.getElementById('active-downloads');
        activeQueue.innerHTML = activeDownloads.map(item => 
            `<div class="queue-item" data-id="${item.id}">
                ${item.serie_name} - Episode ${item.episode}
                <div class="progress-bar">
                    <div class="progress-fill" style="width: ${item.progress}%"></div>
                </div>
            </div>`
        ).join('');
        
        expect(activeQueue.children.length).toBe(1);
        const progressFill = activeQueue.querySelector('.progress-fill');
        expect(progressFill.style.width).toBe('45%');
    });
    
    it('should render completed queue items', () => {
        const completedItems = [
            { id: '1', serie_name: 'Anime 1', episode: 1, status: 'completed' },
            { id: '2', serie_name: 'Anime 2', episode: 2, status: 'completed' }
        ];
        
        const completedQueue = document.getElementById('completed-queue');
        completedQueue.innerHTML = completedItems.map(item => 
            `<div class="queue-item" data-id="${item.id}">${item.serie_name} - Episode ${item.episode}</div>`
        ).join('');
        
        expect(completedQueue.children.length).toBe(2);
    });
    
    it('should render failed queue items', () => {
        const failedItems = [
            { id: '1', serie_name: 'Anime 1', episode: 1, status: 'failed', error: 'Network error' }
        ];
        
        const failedQueue = document.getElementById('failed-queue');
        failedQueue.innerHTML = failedItems.map(item => 
            `<div class="queue-item" data-id="${item.id}">
                ${item.serie_name} - Episode ${item.episode}
                <span class="error">${item.error}</span>
            </div>`
        ).join('');
        
        expect(failedQueue.children.length).toBe(1);
        expect(failedQueue.querySelector('.error').textContent).toBe('Network error');
    });
    
    it('should clear queue display when empty', () => {
        const pendingQueue = document.getElementById('pending-queue');
        pendingQueue.innerHTML = '<div>Item 1</div><div>Item 2</div>';
        expect(pendingQueue.children.length).toBe(2);
        
        // Clear display
        pendingQueue.innerHTML = '';
        expect(pendingQueue.children.length).toBe(0);
    });
});

describe('Queue Progress Handler', () => {
    beforeEach(() => {
        setupDOM();
        setupMockAniWorld();
    });
    
    afterEach(() => {
        vi.restoreAllMocks();
    });
    
    it('should update progress bar for active download', () => {
        // Setup active download card
        const activeQueue = document.getElementById('active-downloads');
        activeQueue.innerHTML = `
            <div class="queue-item" data-id="download-123">
                <div class="progress-bar">
                    <div class="progress-fill" style="width: 0%"></div>
                </div>
                <span class="progress-text">0%</span>
            </div>
        `;
        
        // Simulate progress update
        const progressData = {
            item_id: 'download-123',
            progress: 75
        };
        
        const card = activeQueue.querySelector(`[data-id="${progressData.item_id}"]`);
        const progressFill = card.querySelector('.progress-fill');
        const progressText = card.querySelector('.progress-text');
        
        progressFill.style.width = `${progressData.progress}%`;
        progressText.textContent = `${progressData.progress}%`;
        
        expect(progressFill.style.width).toBe('75%');
        expect(progressText.textContent).toBe('75%');
    });
    
    it('should handle progress update for non-existent card', () => {
        const activeQueue = document.getElementById('active-downloads');
        
        const progressData = {
            item_id: 'nonexistent-123',
            progress: 50
        };
        
        const card = activeQueue.querySelector(`[data-id="${progressData.item_id}"]`);
        expect(card).toBeNull();
    });
    
    it('should update progress from 0 to 100', () => {
        const activeQueue = document.getElementById('active-downloads');
        activeQueue.innerHTML = `
            <div class="queue-item" data-id="download-123">
                <div class="progress-bar">
                    <div class="progress-fill" style="width: 0%"></div>
                </div>
            </div>
        `;
        
        const card = activeQueue.querySelector('[data-id="download-123"]');
        const progressFill = card.querySelector('.progress-fill');
        
        // Simulate progress updates
        [0, 25, 50, 75, 100].forEach(progress => {
            progressFill.style.width = `${progress}%`;
            expect(progressFill.style.width).toBe(`${progress}%`);
        });
    });
});

describe('Queue Button Handlers', () => {
    beforeEach(() => {
        setupDOM();
        setupMockAniWorld();
    });
    
    afterEach(() => {
        vi.restoreAllMocks();
    });
    
    it('should call start queue on button click', async () => {
        const mockResponse = {
            json: vi.fn().mockResolvedValue({ message: 'Queue started' })
        };
        global.AniWorld.ApiClient.post.mockResolvedValue(mockResponse);
        
        const button = document.getElementById('start-queue-btn');
        const handler = async () => {
            await global.AniWorld.QueueAPI.startQueue();
            global.AniWorld.UI.showToast('Queue started', 'success');
        };
        
        button.addEventListener('click', handler);
        button.click();
        
        await new Promise(resolve => setTimeout(resolve, 0));
        
        expect(global.AniWorld.ApiClient.post).toHaveBeenCalledWith('/api/queue/start', {});
    });
    
    it('should call stop queue on button click', async () => {
        const mockResponse = {
            json: vi.fn().mockResolvedValue({ message: 'Queue stopped' })
        };
        global.AniWorld.ApiClient.post.mockResolvedValue(mockResponse);
        
        const button = document.getElementById('stop-queue-btn');
        const handler = async () => {
            await global.AniWorld.QueueAPI.stopQueue();
            global.AniWorld.UI.showToast('Queue stopped', 'success');
        };
        
        button.addEventListener('click', handler);
        button.click();
        
        await new Promise(resolve => setTimeout(resolve, 0));
        
        expect(global.AniWorld.ApiClient.post).toHaveBeenCalledWith('/api/queue/stop', {});
    });
    
    it('should show confirmation before clearing completed', async () => {
        global.AniWorld.UI.showConfirmModal.mockResolvedValue(true);
        const mockResponse = {
            json: vi.fn().mockResolvedValue({ cleared: 5 })
        };
        global.AniWorld.ApiClient.delete.mockResolvedValue(mockResponse);
        
        const button = document.getElementById('clear-completed-btn');
        const handler = async () => {
            const confirmed = await global.AniWorld.UI.showConfirmModal(
                'Clear Completed Downloads',
                'Are you sure you want to clear all completed downloads?'
            );
            if (confirmed) {
                await global.AniWorld.QueueAPI.clearCompleted();
            }
        };
        
        button.addEventListener('click', handler);
        button.click();
        
        await new Promise(resolve => setTimeout(resolve, 0));
        
        expect(global.AniWorld.UI.showConfirmModal).toHaveBeenCalled();
        expect(global.AniWorld.ApiClient.delete).toHaveBeenCalledWith('/api/queue/completed');
    });
    
    it('should not clear completed if confirmation cancelled', async () => {
        global.AniWorld.UI.showConfirmModal.mockResolvedValue(false);
        
        const button = document.getElementById('clear-completed-btn');
        const handler = async () => {
            const confirmed = await global.AniWorld.UI.showConfirmModal(
                'Clear Completed Downloads',
                'Are you sure?'
            );
            if (confirmed) {
                await global.AniWorld.QueueAPI.clearCompleted();
            }
        };
        
        button.addEventListener('click', handler);
        button.click();
        
        await new Promise(resolve => setTimeout(resolve, 0));
        
        expect(global.AniWorld.UI.showConfirmModal).toHaveBeenCalled();
        expect(global.AniWorld.ApiClient.delete).not.toHaveBeenCalled();
    });
    
    it('should show confirmation before clearing failed', async () => {
        global.AniWorld.UI.showConfirmModal.mockResolvedValue(true);
        const mockResponse = {
            json: vi.fn().mockResolvedValue({ cleared: 3 })
        };
        global.AniWorld.ApiClient.delete.mockResolvedValue(mockResponse);
        
        const button = document.getElementById('clear-failed-btn');
        const handler = async () => {
            const confirmed = await global.AniWorld.UI.showConfirmModal(
                'Clear Failed Downloads',
                'Are you sure you want to clear all failed downloads?'
            );
            if (confirmed) {
                await global.AniWorld.QueueAPI.clearFailed();
            }
        };
        
        button.addEventListener('click', handler);
        button.click();
        
        await new Promise(resolve => setTimeout(resolve, 0));
        
        expect(global.AniWorld.UI.showConfirmModal).toHaveBeenCalled();
        expect(global.AniWorld.ApiClient.delete).toHaveBeenCalledWith('/api/queue/failed');
    });
    
    it('should show confirmation before clearing pending', async () => {
        global.AniWorld.UI.showConfirmModal.mockResolvedValue(true);
        const mockResponse = {
            json: vi.fn().mockResolvedValue({ cleared: 2 })
        };
        global.AniWorld.ApiClient.delete.mockResolvedValue(mockResponse);
        
        const button = document.getElementById('clear-pending-btn');
        const handler = async () => {
            const confirmed = await global.AniWorld.UI.showConfirmModal(
                'Remove All Pending Downloads',
                'Are you sure you want to remove all pending downloads from the queue?'
            );
            if (confirmed) {
                await global.AniWorld.QueueAPI.clearPending();
            }
        };
        
        button.addEventListener('click', handler);
        button.click();
        
        await new Promise(resolve => setTimeout(resolve, 0));
        
        expect(global.AniWorld.UI.showConfirmModal).toHaveBeenCalled();
        expect(global.AniWorld.ApiClient.delete).toHaveBeenCalledWith('/api/queue/pending');
    });
    
    it('should retry all failed downloads', async () => {
        global.AniWorld.UI.showConfirmModal.mockResolvedValue(true);
        const mockResponse = {
            json: vi.fn().mockResolvedValue({ retried: 2 })
        };
        global.AniWorld.ApiClient.post.mockResolvedValue(mockResponse);
        
        // Simulate failed items in DOM
        const failedQueue = document.getElementById('failed-queue');
        failedQueue.innerHTML = `
            <div class="queue-item" data-id="item-1"></div>
            <div class="queue-item" data-id="item-2"></div>
        `;
        
        const button = document.getElementById('retry-all-btn');
        const handler = async () => {
            const failedItems = Array.from(failedQueue.querySelectorAll('.queue-item'));
            const itemIds = failedItems.map(item => item.dataset.id);
            
            const confirmed = await global.AniWorld.UI.showConfirmModal(
                'Retry Failed Downloads',
                `Retry ${itemIds.length} failed downloads?`
            );
            if (confirmed && itemIds.length > 0) {
                await global.AniWorld.QueueAPI.retryDownloads(itemIds);
            }
        };
        
        button.addEventListener('click', handler);
        button.click();
        
        await new Promise(resolve => setTimeout(resolve, 0));
        
        expect(global.AniWorld.UI.showConfirmModal).toHaveBeenCalled();
        expect(global.AniWorld.ApiClient.post).toHaveBeenCalledWith(
            '/api/queue/retry',
            { item_ids: ['item-1', 'item-2'] }
        );
    });
});

describe('Queue Real-time Updates', () => {
    beforeEach(() => {
        setupDOM();
        setupMockAniWorld();
    });
    
    afterEach(() => {
        vi.restoreAllMocks();
    });
    
    it('should update display on queue_updated event', () => {
        const updateHandler = vi.fn();
        
        // Simulate WebSocket event
        const data = {
            statistics: {
                pending: 3,
                active: 1,
                completed: 5,
                failed: 0,
                total: 9
            }
        };
        
        updateHandler(data);
        expect(updateHandler).toHaveBeenCalledWith(data);
    });
    
    it('should update display on download_progress event', () => {
        const progressHandler = vi.fn();
        
        const progressData = {
            item_id: 'download-123',
            progress: 65,
            speed: '5.2 MB/s',
            eta: '2 minutes'
        };
        
        progressHandler(progressData);
        expect(progressHandler).toHaveBeenCalledWith(progressData);
    });
    
    it('should reload queue on download_completed event', () => {
        const reloadHandler = vi.fn();
        
        const completedData = {
            item_id: 'download-123',
            serie_name: 'Anime 1',
            episode: 1
        };
        
        reloadHandler(completedData);
        expect(reloadHandler).toHaveBeenCalledWith(completedData);
    });
    
    it('should reload queue on download_failed event', () => {
        const reloadHandler = vi.fn();
        
        const failedData = {
            item_id: 'download-123',
            error: 'Network timeout'
        };
        
        reloadHandler(failedData);
        expect(reloadHandler).toHaveBeenCalledWith(failedData);
    });
});

describe('Queue Edge Cases', () => {
    beforeEach(() => {
        setupDOM();
        setupMockAniWorld();
    });
    
    afterEach(() => {
        vi.restoreAllMocks();
    });
    
    it('should handle empty queue gracefully', () => {
        const data = {
            statistics: {
                pending: 0,
                active: 0,
                completed: 0,
                failed: 0,
                total: 0
            },
            pending_items: [],
            active_downloads: [],
            completed_items: [],
            failed_items: []
        };
        
        document.getElementById('pending-count').textContent = data.statistics.pending;
        document.getElementById('pending-queue').innerHTML = '';
        
        expect(document.getElementById('pending-count').textContent).toBe('0');
        expect(document.getElementById('pending-queue').children.length).toBe(0);
    });
    
    it('should handle rapid progress updates', () => {
        const activeQueue = document.getElementById('active-downloads');
        activeQueue.innerHTML = `
            <div class="queue-item" data-id="download-123">
                <div class="progress-bar">
                    <div class="progress-fill" style="width: 0%"></div>
                </div>
            </div>
        `;
        
        const card = activeQueue.querySelector('[data-id="download-123"]');
        const progressFill = card.querySelector('.progress-fill');
        
        // Simulate rapid updates
        for (let i = 0; i <= 100; i += 5) {
            progressFill.style.width = `${i}%`;
        }
        
        expect(progressFill.style.width).toBe('100%');
    });
    
    it('should handle missing progress bar element', () => {
        const activeQueue = document.getElementById('active-downloads');
        activeQueue.innerHTML = `
            <div class="queue-item" data-id="download-123">
                <!-- No progress bar -->
            </div>
        `;
        
        const card = activeQueue.querySelector('[data-id="download-123"]');
        const progressFill = card.querySelector('.progress-fill');
        
        expect(progressFill).toBeNull();
    });
});
