/**
 * E2E tests for queue interactions
 * Tests queue management user flows, download control, and persistence
 */

import { expect, test } from '@playwright/test';

test.describe('Queue Page - Initial Load', () => {
    test('should load queue page successfully', async ({ page }) => {
        await page.goto('/queue');
        
        await expect(page).toHaveTitle(/Queue|Downloads/i);
        await expect(page.locator('h1, h2')).toContainText(/Queue|Downloads/i);
    });
    
    test('should display queue statistics', async ({ page }) => {
        await page.goto('/queue');
        
        await expect(page.locator('#pending-count')).toBeVisible();
        await expect(page.locator('#active-count')).toBeVisible();
        await expect(page.locator('#completed-count')).toBeVisible();
        await expect(page.locator('#failed-count')).toBeVisible();
    });
    
    test('should display queue control buttons', async ({ page }) => {
        await page.goto('/queue');
        
        await expect(page.locator('#start-queue-btn')).toBeVisible();
        await expect(page.locator('#stop-queue-btn')).toBeVisible();
        await expect(page.locator('#clear-completed-btn')).toBeVisible();
        await expect(page.locator('#clear-failed-btn')).toBeVisible();
        await expect(page.locator('#retry-all-btn')).toBeVisible();
    });
    
    test('should display queue sections', async ({ page }) => {
        await page.goto('/queue');
        
        await expect(page.locator('#pending-queue')).toBeVisible();
        await expect(page.locator('#active-downloads')).toBeVisible();
        await expect(page.locator('#completed-queue')).toBeVisible();
        await expect(page.locator('#failed-queue')).toBeVisible();
    });
});

test.describe('Queue Controls - Start/Stop', () => {
    test('should start queue on button click', async ({ page }) => {
        await page.goto('/queue');
        
        // Mock API response
        await page.route('/api/queue/start', async route => {
            await route.fulfill({
                status: 200,
                body: JSON.stringify({ message: 'Queue started' })
            });
        });
        
        await page.click('#start-queue-btn');
        
        // Verify toast or visual feedback
        await expect(page.locator('.toast, .notification')).toContainText(/started/i);
    });
    
    test('should stop queue on button click', async ({ page }) => {
        await page.goto('/queue');
        
        // Mock API response
        await page.route('/api/queue/stop', async route => {
            await route.fulfill({
                status: 200,
                body: JSON.stringify({ message: 'Queue stopped' })
            });
        });
        
        await page.click('#stop-queue-btn');
        
        // Verify toast or visual feedback
        await expect(page.locator('.toast, .notification')).toContainText(/stopped/i);
    });
    
    test('should disable start button when queue is running', async ({ page }) => {
        await page.goto('/queue');
        
        // Mock queue status response
        await page.route('/api/queue/status', async route => {
            await route.fulfill({
                status: 200,
                body: JSON.stringify({
                    status: {
                        is_running: true,
                        pending_items: [],
                        active_downloads: [],
                        completed_items: [],
                        failed_items: []
                    },
                    statistics: {
                        pending: 0,
                        active: 0,
                        completed: 0,
                        failed: 0,
                        total: 0
                    }
                })
            });
        });
        
        await page.reload();
        
        const startBtn = page.locator('#start-queue-btn');
        await expect(startBtn).toBeDisabled();
    });
    
    test('should handle queue start error gracefully', async ({ page }) => {
        await page.goto('/queue');
        
        // Mock error response
        await page.route('/api/queue/start', async route => {
            await route.fulfill({
                status: 500,
                body: JSON.stringify({ error: 'Queue already running' })
            });
        });
        
        await page.click('#start-queue-btn');
        
        // Verify error message displayed
        await expect(page.locator('.toast, .error, .notification')).toContainText(/error|failed/i);
    });
});

test.describe('Queue Management - Clear Operations', () => {
    test('should show confirmation before clearing completed', async ({ page }) => {
        await page.goto('/queue');
        
        await page.click('#clear-completed-btn');
        
        // Verify confirmation modal appears
        const modal = page.locator('#confirm-modal, .modal');
        await expect(modal).toBeVisible();
        await expect(modal).toContainText(/clear.*completed/i);
    });
    
    test('should clear completed downloads on confirmation', async ({ page }) => {
        await page.goto('/queue');
        
        // Mock API response
        await page.route('/api/queue/completed', async route => {
            await route.fulfill({
                status: 200,
                body: JSON.stringify({ cleared: 5 })
            });
        });
        
        await page.click('#clear-completed-btn');
        
        // Confirm action
        await page.click('#confirm-ok, button:has-text("OK"), button:has-text("Yes")');
        
        // Verify toast confirmation
        await expect(page.locator('.toast, .notification')).toContainText(/cleared|success/i);
    });
    
    test('should cancel clear completed on modal cancel', async ({ page }) => {
        await page.goto('/queue');
        
        let apiCalled = false;
        await page.route('/api/queue/completed', async route => {
            apiCalled = true;
            await route.fulfill({ status: 200, body: '{}' });
        });
        
        await page.click('#clear-completed-btn');
        await page.click('#confirm-cancel, button:has-text("Cancel"), button:has-text("No")');
        
        // Wait a bit to ensure API is not called
        await page.waitForTimeout(500);
        expect(apiCalled).toBe(false);
    });
    
    test('should show confirmation before clearing failed', async ({ page }) => {
        await page.goto('/queue');
        
        await page.click('#clear-failed-btn');
        
        const modal = page.locator('#confirm-modal, .modal');
        await expect(modal).toBeVisible();
        await expect(modal).toContainText(/clear.*failed/i);
    });
    
    test('should clear failed downloads on confirmation', async ({ page }) => {
        await page.goto('/queue');
        
        await page.route('/api/queue/failed', async route => {
            await route.fulfill({
                status: 200,
                body: JSON.stringify({ cleared: 3 })
            });
        });
        
        await page.click('#clear-failed-btn');
        await page.click('#confirm-ok, button:has-text("OK")');
        
        await expect(page.locator('.toast, .notification')).toContainText(/cleared|success/i);
    });
    
    test('should show confirmation before clearing pending', async ({ page }) => {
        await page.goto('/queue');
        
        await page.click('#clear-pending-btn');
        
        const modal = page.locator('#confirm-modal, .modal');
        await expect(modal).toBeVisible();
        await expect(modal).toContainText(/pending|remove/i);
    });
    
    test('should clear pending downloads on confirmation', async ({ page }) => {
        await page.goto('/queue');
        
        await page.route('/api/queue/pending', async route => {
            await route.fulfill({
                status: 200,
                body: JSON.stringify({ cleared: 2 })
            });
        });
        
        await page.click('#clear-pending-btn');
        await page.click('#confirm-ok, button:has-text("OK")');
        
        await expect(page.locator('.toast, .notification')).toContainText(/cleared|removed|success/i);
    });
});

test.describe('Queue Management - Retry Failed', () => {
    test('should show confirmation before retrying failed downloads', async ({ page }) => {
        await page.goto('/queue');
        
        await page.click('#retry-all-btn');
        
        const modal = page.locator('#confirm-modal, .modal');
        await expect(modal).toBeVisible();
        await expect(modal).toContainText(/retry/i);
    });
    
    test('should retry all failed downloads on confirmation', async ({ page }) => {
        await page.goto('/queue');
        
        // Mock initial queue status with failed items
        await page.route('/api/queue/status', async route => {
            await route.fulfill({
                status: 200,
                body: JSON.stringify({
                    status: {
                        is_running: false,
                        pending_items: [],
                        active_downloads: [],
                        completed_items: [],
                        failed_items: [
                            { id: 'failed-1', serie_name: 'Anime 1', episode: 1 },
                            { id: 'failed-2', serie_name: 'Anime 2', episode: 2 }
                        ]
                    },
                    statistics: {
                        pending: 0,
                        active: 0,
                        completed: 0,
                        failed: 2,
                        total: 2
                    }
                })
            });
        });
        
        await page.route('/api/queue/retry', async route => {
            await route.fulfill({
                status: 200,
                body: JSON.stringify({ retried: 2 })
            });
        });
        
        await page.reload();
        await page.click('#retry-all-btn');
        await page.click('#confirm-ok, button:has-text("OK")');
        
        await expect(page.locator('.toast, .notification')).toContainText(/retry|success/i);
    });
    
    test('should not retry if no failed downloads exist', async ({ page }) => {
        await page.goto('/queue');
        
        // Mock queue with no failed items
        await page.route('/api/queue/status', async route => {
            await route.fulfill({
                status: 200,
                body: JSON.stringify({
                    status: {
                        is_running: false,
                        pending_items: [],
                        active_downloads: [],
                        completed_items: [],
                        failed_items: []
                    },
                    statistics: {
                        pending: 0,
                        active: 0,
                        completed: 0,
                        failed: 0,
                        total: 0
                    }
                })
            });
        });
        
        await page.reload();
        
        // Button should be disabled
        const retryBtn = page.locator('#retry-all-btn');
        await expect(retryBtn).toBeDisabled();
    });
});

test.describe('Queue Display - Real-time Updates', () => {
    test('should update statistics when queue changes', async ({ page }) => {
        await page.goto('/queue');
        
        // Initial state
        await expect(page.locator('#pending-count')).toHaveText('0');
        
        // Simulate queue update via WebSocket
        await page.evaluate(() => {
            document.getElementById('pending-count').textContent = '5';
            document.getElementById('active-count').textContent = '1';
        });
        
        await expect(page.locator('#pending-count')).toHaveText('5');
        await expect(page.locator('#active-count')).toHaveText('1');
    });
    
    test('should display pending queue items', async ({ page }) => {
        await page.goto('/queue');
        
        // Mock queue with pending items
        await page.route('/api/queue/status', async route => {
            await route.fulfill({
                status: 200,
                body: JSON.stringify({
                    status: {
                        is_running: false,
                        pending_items: [
                            { id: '1', serie_name: 'Anime 1', episode: 1 },
                            { id: '2', serie_name: 'Anime 2', episode: 2 }
                        ],
                        active_downloads: [],
                        completed_items: [],
                        failed_items: []
                    },
                    statistics: {
                        pending: 2,
                        active: 0,
                        completed: 0,
                        failed: 0,
                        total: 2
                    }
                })
            });
        });
        
        await page.reload();
        
        const pendingQueue = page.locator('#pending-queue');
        await expect(pendingQueue.locator('.queue-item')).toHaveCount(2);
    });
    
    test('should display active downloads with progress', async ({ page }) => {
        await page.goto('/queue');
        
        // Mock queue with active download
        await page.route('/api/queue/status', async route => {
            await route.fulfill({
                status: 200,
                body: JSON.stringify({
                    status: {
                        is_running: true,
                        pending_items: [],
                        active_downloads: [
                            { id: '1', serie_name: 'Anime 1', episode: 1, progress: 45 }
                        ],
                        completed_items: [],
                        failed_items: []
                    },
                    statistics: {
                        pending: 0,
                        active: 1,
                        completed: 0,
                        failed: 0,
                        total: 1
                    }
                })
            });
        });
        
        await page.reload();
        
        const activeQueue = page.locator('#active-downloads');
        await expect(activeQueue.locator('.queue-item')).toHaveCount(1);
        await expect(activeQueue.locator('.progress-bar, .progress')).toBeVisible();
    });
    
    test('should update progress bar in real-time', async ({ page }) => {
        await page.goto('/queue');
        
        // Simulate progress update
        await page.evaluate(() => {
            const progressBar = document.createElement('div');
            progressBar.className = 'progress-bar';
            const progressFill = document.createElement('div');
            progressFill.className = 'progress-fill';
            progressFill.style.width = '50%';
            progressBar.appendChild(progressFill);
            document.getElementById('active-downloads').appendChild(progressBar);
        });
        
        const progressFill = page.locator('.progress-fill');
        await expect(progressFill).toHaveCSS('width', /50%|[0-9]+px/);
    });
});

test.describe('Queue Persistence', () => {
    test('should persist queue state across page refresh', async ({ page }) => {
        await page.goto('/queue');
        
        // Mock queue state
        await page.route('/api/queue/status', async route => {
            await route.fulfill({
                status: 200,
                body: JSON.stringify({
                    status: {
                        is_running: false,
                        pending_items: [
                            { id: '1', serie_name: 'Persisted Anime', episode: 1 }
                        ],
                        active_downloads: [],
                        completed_items: [],
                        failed_items: []
                    },
                    statistics: {
                        pending: 1,
                        active: 0,
                        completed: 0,
                        failed: 0,
                        total: 1
                    }
                })
            });
        });
        
        await page.reload();
        
        // Verify queue items persist
        await expect(page.locator('#pending-count')).toHaveText('1');
        await expect(page.locator('#pending-queue')).toContainText('Persisted Anime');
    });
    
    test('should maintain queue statistics after navigation', async ({ page }) => {
        await page.goto('/queue');
        
        // Set initial statistics
        await page.evaluate(() => {
            document.getElementById('pending-count').textContent = '3';
            document.getElementById('completed-count').textContent = '7';
        });
        
        const initialPending = await page.locator('#pending-count').textContent();
        const initialCompleted = await page.locator('#completed-count').textContent();
        
        // Navigate away and back
        await page.goto('/');
        await page.goto('/queue');
        
        // Note: In real app, these would be loaded from API
        // This test verifies the structure exists
        await expect(page.locator('#pending-count')).toBeVisible();
        await expect(page.locator('#completed-count')).toBeVisible();
    });
});

test.describe('Queue Accessibility', () => {
    test('should have accessible button labels', async ({ page }) => {
        await page.goto('/queue');
        
        await expect(page.locator('#start-queue-btn')).toHaveAccessibleName();
        await expect(page.locator('#stop-queue-btn')).toHaveAccessibleName();
        await expect(page.locator('#clear-completed-btn')).toHaveAccessibleName();
        await expect(page.locator('#clear-failed-btn')).toHaveAccessibleName();
        await expect(page.locator('#retry-all-btn')).toHaveAccessibleName();
    });
    
    test('should support keyboard navigation for buttons', async ({ page }) => {
        await page.goto('/queue');
        
        const startBtn = page.locator('#start-queue-btn');
        await startBtn.focus();
        await expect(startBtn).toBeFocused();
        
        await page.keyboard.press('Tab');
        const stopBtn = page.locator('#stop-queue-btn');
        await expect(stopBtn).toBeFocused();
    });
    
    test('should support Enter key for button activation', async ({ page }) => {
        await page.goto('/queue');
        
        let apiCalled = false;
        await page.route('/api/queue/start', async route => {
            apiCalled = true;
            await route.fulfill({
                status: 200,
                body: JSON.stringify({ message: 'Started' })
            });
        });
        
        await page.locator('#start-queue-btn').focus();
        await page.keyboard.press('Enter');
        
        await page.waitForTimeout(500);
        expect(apiCalled).toBe(true);
    });
    
    test('should have ARIA labels for statistics', async ({ page }) => {
        await page.goto('/queue');
        
        // Verify statistics have accessible context
        await expect(page.locator('#pending-count').locator('..')).toContainText(/pending/i);
        await expect(page.locator('#active-count').locator('..')).toContainText(/active/i);
        await expect(page.locator('#completed-count').locator('..')).toContainText(/completed/i);
        await expect(page.locator('#failed-count').locator('..')).toContainText(/failed/i);
    });
});

test.describe('Queue Edge Cases', () => {
    test('should handle empty queue gracefully', async ({ page }) => {
        await page.goto('/queue');
        
        await page.route('/api/queue/status', async route => {
            await route.fulfill({
                status: 200,
                body: JSON.stringify({
                    status: {
                        is_running: false,
                        pending_items: [],
                        active_downloads: [],
                        completed_items: [],
                        failed_items: []
                    },
                    statistics: {
                        pending: 0,
                        active: 0,
                        completed: 0,
                        failed: 0,
                        total: 0
                    }
                })
            });
        });
        
        await page.reload();
        
        await expect(page.locator('#pending-count')).toHaveText('0');
        await expect(page.locator('#total-count')).toHaveText('0');
    });
    
    test('should handle API error gracefully', async ({ page }) => {
        await page.goto('/queue');
        
        await page.route('/api/queue/status', async route => {
            await route.fulfill({
                status: 500,
                body: JSON.stringify({ error: 'Internal server error' })
            });
        });
        
        await page.reload();
        
        // Should display error message or default state
        await expect(page.locator('.error, .toast, .notification, body')).toBeVisible();
    });
    
    test('should handle rapid button clicks gracefully', async ({ page }) => {
        await page.goto('/queue');
        
        let apiCallCount = 0;
        await page.route('/api/queue/start', async route => {
            apiCallCount++;
            await route.fulfill({
                status: 200,
                body: JSON.stringify({ message: 'Started' })
            });
        });
        
        // Click button multiple times rapidly
        const startBtn = page.locator('#start-queue-btn');
        await startBtn.click();
        await startBtn.click();
        await startBtn.click();
        
        await page.waitForTimeout(500);
        
        // Should not call API multiple times (debouncing/button state management)
        // This depends on implementation - may be 1 or 3
        expect(apiCallCount).toBeGreaterThan(0);
    });
    
    test('should handle very long queue items list', async ({ page }) => {
        await page.goto('/queue');
        
        const longItemsList = Array.from({ length: 100 }, (_, i) => ({
            id: `item-${i}`,
            serie_name: `Anime ${i}`,
            episode: i + 1
        }));
        
        await page.route('/api/queue/status', async route => {
            await route.fulfill({
                status: 200,
                body: JSON.stringify({
                    status: {
                        is_running: false,
                        pending_items: longItemsList,
                        active_downloads: [],
                        completed_items: [],
                        failed_items: []
                    },
                    statistics: {
                        pending: 100,
                        active: 0,
                        completed: 0,
                        failed: 0,
                        total: 100
                    }
                })
            });
        });
        
        await page.reload();
        
        await expect(page.locator('#pending-count')).toHaveText('100');
        // Should handle scrolling for long lists
        await expect(page.locator('#pending-queue')).toBeVisible();
    });
});

test.describe('Queue Theme Integration', () => {
    test('should respect current theme', async ({ page }) => {
        await page.goto('/queue');
        
        // Check that theme toggle exists
        const themeToggle = page.locator('#theme-toggle');
        await expect(themeToggle).toBeVisible();
    });
    
    test('should apply theme to queue elements', async ({ page }) => {
        await page.goto('/queue');
        
        // Get initial theme
        const initialTheme = await page.evaluate(() => 
            document.documentElement.getAttribute('data-theme')
        );
        
        // Toggle theme
        await page.click('#theme-toggle');
        
        // Verify theme changed
        const newTheme = await page.evaluate(() => 
            document.documentElement.getAttribute('data-theme')
        );
        
        expect(newTheme).not.toBe(initialTheme);
    });
});
