<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Test Filters v2 - Gherkin-Driven</title>
    <style>
        * {
            box-sizing: border-box;
            margin: 0;
            padding: 0;
        }

        body {
            font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
            background: #111827;
            color: #e5e7eb;
            min-height: 100vh;
        }

        .container {
            max-width: 1600px;
            margin: 0 auto;
            padding: 20px;
        }

        header {
            display: flex;
            justify-content: space-between;
            align-items: center;
            margin-bottom: 20px;
            padding-bottom: 20px;
            border-bottom: 1px solid #374151;
        }

        h1 {
            font-size: 1.5rem;
            font-weight: 600;
            color: #f9fafb;
        }

        .version-badge {
            background: #1e3a8a;
            color: #60a5fa;
            padding: 4px 12px;
            border-radius: 12px;
            font-size: 0.75rem;
            font-weight: 600;
            text-transform: uppercase;
        }

        .nav-links {
            display: flex;
            gap: 12px;
            font-size: 0.875rem;
        }

        .nav-links a {
            color: #60a5fa;
            text-decoration: none;
            padding: 6px 12px;
            border-radius: 4px;
            transition: background 0.2s;
        }

        .nav-links a:hover {
            background: #374151;
        }

        .nav-links a.active {
            background: #2563eb;
            color: white;
        }

        /* Quick Presets */
        .quick-presets {
            background: #1f2937;
            border-radius: 8px;
            padding: 16px;
            margin-bottom: 20px;
        }

        .preset-label {
            font-size: 0.75rem;
            color: #9ca3af;
            text-transform: uppercase;
            font-weight: 600;
            margin-bottom: 10px;
        }

        .preset-chips {
            display: flex;
            gap: 8px;
            flex-wrap: wrap;
        }

        .preset-chip {
            padding: 8px 16px;
            background: #374151;
            border: 2px solid transparent;
            border-radius: 6px;
            font-size: 0.875rem;
            cursor: pointer;
            transition: all 0.2s;
            color: #e5e7eb;
        }

        .preset-chip:hover {
            background: #4b5563;
            border-color: #60a5fa;
        }

        .preset-chip.active {
            background: #2563eb;
            border-color: #1d4ed8;
            color: white;
        }

        .preset-shortcut {
            font-size: 0.7rem;
            opacity: 0.7;
            margin-left: 6px;
        }

        /* Filter Sections */
        .filter-grid {
            display: grid;
            grid-template-columns: 1fr 1fr;
            gap: 20px;
            margin-bottom: 20px;
        }

        @media (max-width: 1200px) {
            .filter-grid {
                grid-template-columns: 1fr;
            }
        }

        .filter-panel {
            background: #1f2937;
            border-radius: 8px;
            padding: 20px;
        }

        .panel-header {
            font-size: 0.875rem;
            font-weight: 600;
            color: #f9fafb;
            margin-bottom: 12px;
            display: flex;
            align-items: center;
            gap: 8px;
        }

        .panel-icon {
            font-size: 1.2rem;
        }

        .filter-group {
            display: flex;
            gap: 6px;
            flex-wrap: wrap;
            margin-bottom: 12px;
        }

        .filter-chip {
            padding: 6px 12px;
            border-radius: 6px;
            font-size: 0.875rem;
            cursor: pointer;
            transition: all 0.2s;
            background: #374151;
            color: #e5e7eb;
            border: 2px solid transparent;
        }

        .filter-chip:hover {
            background: #4b5563;
        }

        .filter-chip.active {
            background: #2563eb;
            color: white;
            border-color: #1d4ed8;
        }

        .filter-chip.all {
            background: #374151;
            border-color: #4b5563;
        }

        .filter-chip.all.active {
            background: #4b5563;
            border-color: #6b7280;
        }

        .search-box {
            width: 100%;
            padding: 10px 12px;
            background: #374151;
            border: 2px solid #4b5563;
            border-radius: 6px;
            color: #e5e7eb;
            font-size: 0.875rem;
            transition: border-color 0.2s;
        }

        .search-box:focus {
            outline: none;
            border-color: #2563eb;
        }

        .search-box::placeholder {
            color: #6b7280;
        }

        /* Test List */
        .test-list-container {
            background: #1f2937;
            border-radius: 8px;
            overflow: hidden;
        }

        .list-header {
            padding: 16px;
            background: #374151;
            display: flex;
            justify-content: space-between;
            align-items: center;
        }

        .list-title {
            font-weight: 600;
            font-size: 1rem;
        }

        .test-count {
            font-size: 0.875rem;
            color: #9ca3af;
            background: #1f2937;
            padding: 4px 12px;
            border-radius: 12px;
        }

        .list-body {
            padding: 16px;
            max-height: 600px;
            overflow-y: auto;
        }

        .test-card {
            background: #374151;
            border-radius: 6px;
            padding: 12px;
            margin-bottom: 8px;
            cursor: pointer;
            transition: all 0.2s;
            border: 2px solid transparent;
        }

        .test-card:hover {
            background: #4b5563;
            border-color: #60a5fa;
        }

        .test-card.selected {
            border-color: #2563eb;
            background: #1e3a8a;
        }

        .test-header {
            display: flex;
            justify-content: space-between;
            align-items: start;
            margin-bottom: 6px;
        }

        .test-title {
            font-weight: 600;
            color: #f9fafb;
            font-size: 0.95rem;
        }

        .test-meta {
            display: flex;
            gap: 8px;
            margin-top: 6px;
            font-size: 0.75rem;
            flex-wrap: wrap;
        }

        .meta-badge {
            padding: 2px 8px;
            border-radius: 4px;
            background: #1f2937;
            color: #9ca3af;
        }

        .meta-badge.feature {
            background: #065f46;
            color: #34d399;
        }

        .meta-badge.tag {
            background: #78350f;
            color: #fbbf24;
        }

        .meta-badge.pulse {
            background: #1e3a8a;
            color: #60a5fa;
        }

        .test-type {
            font-size: 0.7rem;
            padding: 2px 6px;
            border-radius: 3px;
            background: #4b5563;
        }

        .test-type.backend {
            background: #065f46;
            color: #34d399;
        }

        .test-type.frontend {
            background: #7c2d12;
            color: #fb923c;
        }

        /* Action Bar */
        .action-bar {
            display: flex;
            justify-content: space-between;
            align-items: center;
            padding: 12px 16px;
            background: #1f2937;
            border-radius: 8px;
            margin-bottom: 20px;
        }

        .selection-info {
            font-size: 0.875rem;
            color: #9ca3af;
        }

        .selection-info strong {
            color: #60a5fa;
            font-size: 1.1rem;
        }

        .action-buttons {
            display: flex;
            gap: 10px;
        }

        .btn {
            padding: 8px 16px;
            border: none;
            border-radius: 6px;
            font-size: 0.875rem;
            cursor: pointer;
            transition: all 0.2s;
            font-weight: 500;
        }

        .btn-primary {
            background: #2563eb;
            color: white;
        }

        .btn-primary:hover {
            background: #1d4ed8;
        }

        .btn-primary:disabled {
            background: #4b5563;
            cursor: not-allowed;
            opacity: 0.5;
        }

        .btn-secondary {
            background: #374151;
            color: #e5e7eb;
        }

        .btn-secondary:hover {
            background: #4b5563;
        }

        .empty-state {
            text-align: center;
            padding: 60px 20px;
            color: #6b7280;
        }

        .empty-state-icon {
            font-size: 3rem;
            margin-bottom: 16px;
            opacity: 0.5;
        }

        /* Keyboard shortcuts help */
        .shortcuts-help {
            position: fixed;
            bottom: 20px;
            right: 20px;
            background: #1f2937;
            border: 1px solid #374151;
            border-radius: 8px;
            padding: 12px;
            font-size: 0.75rem;
            color: #9ca3af;
            max-width: 250px;
            box-shadow: 0 4px 6px rgba(0, 0, 0, 0.3);
        }

        .shortcuts-help.hidden {
            display: none;
        }

        .shortcut-item {
            display: flex;
            justify-content: space-between;
            margin-bottom: 4px;
        }

        .shortcut-key {
            background: #374151;
            padding: 2px 6px;
            border-radius: 3px;
            font-family: monospace;
        }

        /* Loading state */
        .loading {
            text-align: center;
            padding: 40px;
            color: #9ca3af;
        }

        .spinner {
            border: 3px solid #374151;
            border-top: 3px solid #60a5fa;
            border-radius: 50%;
            width: 40px;
            height: 40px;
            animation: spin 1s linear infinite;
            margin: 0 auto 12px;
        }

        @keyframes spin {
            0% { transform: rotate(0deg); }
            100% { transform: rotate(360deg); }
        }
    </style>
</head>
<body>
    <div class="container">
        <header>
            <div>
                <h1>
                    Test Filters v2 - Gherkin-Driven
                    <span class="version-badge">Beta</span>
                </h1>
                <div class="nav-links" style="margin-top: 8px;">
                    <a href="/tools/tester/">Runner</a>
                    <a href="/tools/tester/filters">Filters v1</a>
                    <a href="/tools/tester/filters_v2" class="active">Filters v2</a>
                </div>
            </div>
            <div style="display: flex; align-items: center; gap: 12px; font-size: 0.875rem; color: #9ca3af;">
                <span>Target:</span>
                <select id="environmentSelector" style="background: #374151; color: #e5e7eb; border: 1px solid #4b5563; border-radius: 4px; padding: 4px 8px; font-size: 0.875rem; cursor: pointer;">
                    <option value="">Loading...</option>
                </select>
                <strong id="currentUrl" style="color: #60a5fa;">Loading...</strong>
            </div>
        </header>

        <!-- Quick Presets -->
        <div class="quick-presets">
            <div class="preset-label">⚡ Quick Filters</div>
            <div class="preset-chips">
                <div class="preset-chip" data-preset="all" onclick="applyPreset('all')">
                    All Tests
                </div>
                <div class="preset-chip" data-preset="smoke" onclick="applyPreset('smoke')">
                    🔥 Smoke Tests <span class="preset-shortcut">Ctrl+1</span>
                </div>
                <div class="preset-chip" data-preset="payment" onclick="applyPreset('payment')">
                    💳 Payment Flow <span class="preset-shortcut">Ctrl+2</span>
                </div>
                <div class="preset-chip" data-preset="coverage" onclick="applyPreset('coverage')">
                    📍 Coverage Check <span class="preset-shortcut">Ctrl+3</span>
                </div>
                <div class="preset-chip" data-preset="frontend" onclick="applyPreset('frontend')">
                    🎨 Frontend Only <span class="preset-shortcut">Ctrl+4</span>
                </div>
                <div class="preset-chip" data-preset="backend" onclick="applyPreset('backend')">
                    ⚙️ Backend Only <span class="preset-shortcut">Ctrl+5</span>
                </div>
            </div>
        </div>

        <!-- Filter Grid -->
        <div class="filter-grid">
            <!-- Gherkin Filters -->
            <div class="filter-panel">
                <div class="panel-header">
                    <span class="panel-icon">📋</span>
                    Gherkin Filters
                </div>

                <div style="margin-bottom: 12px;">
                    <div style="font-size: 0.75rem; color: #9ca3af; margin-bottom: 6px;">Features</div>
                    <div class="filter-group" id="featureFilters">
                        <div class="filter-chip all active" data-filter="all" onclick="toggleFeatureFilter(this)">
                            All Features
                        </div>
                        <!-- Populated from API -->
                    </div>
                </div>

                <div style="margin-bottom: 12px;">
                    <div style="font-size: 0.75rem; color: #9ca3af; margin-bottom: 6px;">Tags</div>
                    <div class="filter-group" id="tagFilters">
                        <div class="filter-chip all active" data-filter="all" onclick="toggleTagFilter(this)">
                            All Tags
                        </div>
                        <!-- Populated from API -->
                    </div>
                </div>
            </div>

            <!-- Pulse Variables -->
            <div class="filter-panel">
                <div class="panel-header">
                    <span class="panel-icon">💫</span>
                    Pulse Variables (Amar Context)
                </div>

                <div style="margin-bottom: 12px;">
                    <div style="font-size: 0.75rem; color: #9ca3af; margin-bottom: 6px;">Role</div>
                    <div class="filter-group" id="roleFilters">
                        <div class="filter-chip all active" data-filter="all" onclick="toggleRoleFilter(this)">All</div>
                        <div class="filter-chip" data-filter="VET" onclick="toggleRoleFilter(this)">VET</div>
                        <div class="filter-chip" data-filter="USER" onclick="toggleRoleFilter(this)">USER</div>
                        <div class="filter-chip" data-filter="ADMIN" onclick="toggleRoleFilter(this)">ADMIN</div>
                        <div class="filter-chip" data-filter="GUEST" onclick="toggleRoleFilter(this)">GUEST</div>
                    </div>
                </div>

                <div style="margin-bottom: 12px;">
                    <div style="font-size: 0.75rem; color: #9ca3af; margin-bottom: 6px;">Stage</div>
                    <div class="filter-group" id="stageFilters">
                        <div class="filter-chip all active" data-filter="all" onclick="toggleStageFilter(this)">All</div>
                        <div class="filter-chip" data-filter="coverage" onclick="toggleStageFilter(this)">Coverage</div>
                        <div class="filter-chip" data-filter="services" onclick="toggleStageFilter(this)">Services</div>
                        <div class="filter-chip" data-filter="cart" onclick="toggleStageFilter(this)">Cart</div>
                        <div class="filter-chip" data-filter="payment" onclick="toggleStageFilter(this)">Payment</div>
                        <div class="filter-chip" data-filter="turno" onclick="toggleStageFilter(this)">Turno</div>
                    </div>
                </div>
            </div>
        </div>

        <!-- Search & Test Type -->
        <div class="filter-panel" style="margin-bottom: 20px;">
            <div style="display: grid; grid-template-columns: 1fr auto; gap: 16px; align-items: end;">
                <div>
                    <div style="font-size: 0.75rem; color: #9ca3af; margin-bottom: 6px;">🔍 Search</div>
                    <input
                        type="text"
                        class="search-box"
                        id="searchInput"
                        placeholder="Search by test name, feature, scenario..."
                        autocomplete="off"
                    >
                </div>
                <div>
                    <div style="font-size: 0.75rem; color: #9ca3af; margin-bottom: 6px;">Test Type</div>
                    <div class="filter-group">
                        <div class="filter-chip all active" data-filter="all" onclick="toggleTypeFilter(this)">All</div>
                        <div class="filter-chip" data-filter="backend" onclick="toggleTypeFilter(this)">Backend</div>
                        <div class="filter-chip" data-filter="frontend" onclick="toggleTypeFilter(this)">Frontend</div>
                    </div>
                </div>
            </div>
        </div>

        <!-- Action Bar -->
        <div class="action-bar">
            <div class="selection-info">
                <strong id="selectedCount">0</strong> tests selected
            </div>
            <div class="action-buttons">
                <button class="btn btn-secondary" onclick="clearFilters()">Clear Filters</button>
                <button class="btn btn-secondary" onclick="selectAll()">Select All Visible</button>
                <button class="btn btn-secondary" onclick="deselectAll()">Deselect All</button>
                <button class="btn btn-primary" id="runSelectedBtn" onclick="runSelected()">▶ Run Selected</button>
            </div>
        </div>

        <!-- Test List -->
        <div class="test-list-container">
            <div class="list-header">
                <span class="list-title">Tests</span>
                <span class="test-count" id="testCount">Loading...</span>
            </div>
            <div class="list-body" id="testListBody">
                <div class="loading">
                    <div class="spinner"></div>
                    <div>Loading tests and features...</div>
                </div>
            </div>
        </div>
    </div>

    <!-- Keyboard Shortcuts Help -->
    <div class="shortcuts-help" id="shortcutsHelp">
        <strong style="display: block; margin-bottom: 8px; color: #e5e7eb;">Keyboard Shortcuts</strong>
        <div class="shortcut-item">
            <span>Run selected</span>
            <span class="shortcut-key">Enter</span>
        </div>
        <div class="shortcut-item">
            <span>Select all</span>
            <span class="shortcut-key">Ctrl+A</span>
        </div>
        <div class="shortcut-item">
            <span>Deselect all</span>
            <span class="shortcut-key">Ctrl+D</span>
        </div>
        <div class="shortcut-item">
            <span>Search</span>
            <span class="shortcut-key">Ctrl+F</span>
        </div>
        <div class="shortcut-item">
            <span>Quick filters</span>
            <span class="shortcut-key">Ctrl+1-5</span>
        </div>
        <div class="shortcut-item">
            <span>Toggle help</span>
            <span class="shortcut-key">?</span>
        </div>
    </div>

    <script>
        // State
        let allTests = [];
        let allFeatures = [];
        let selectedTests = new Set();

        // Filter state
        let filters = {
            search: '',
            features: new Set(['all']),
            tags: new Set(['all']),
            roles: new Set(['all']),
            stages: new Set(['all']),
            testType: new Set(['all']),
        };

        // Quick preset definitions
        const presets = {
            all: {
                features: ['all'],
                tags: ['all'],
                roles: ['all'],
                stages: ['all'],
                testType: ['all'],
            },
            smoke: {
                tags: ['@smoke'],
                testType: ['all'],
            },
            payment: {
                tags: ['@payment'],
                stages: ['payment'],
                testType: ['all'],
            },
            coverage: {
                tags: ['@coverage'],
                stages: ['coverage'],
                testType: ['all'],
            },
            frontend: {
                testType: ['frontend'],
            },
            backend: {
                testType: ['backend'],
            },
        };

        // Initialize
        async function init() {
            await loadEnvironments();
            await loadFeatures();
            await loadTests();
            setupKeyboardShortcuts();
        }

        // Load environments
        async function loadEnvironments() {
            try {
                const response = await fetch('/tools/tester/api/environments');
                const data = await response.json();
                const selector = document.getElementById('environmentSelector');
                const currentUrl = document.getElementById('currentUrl');

                const savedEnvId = localStorage.getItem('selectedEnvironment');
                let selectedEnv = null;

                selector.innerHTML = data.environments.map(env => {
                    const isDefault = env.default || env.id === savedEnvId;
                    if (isDefault) selectedEnv = env;
                    return `<option value="${env.id}" ${isDefault ? 'selected' : ''}>${env.name} ${env.has_api_key ? '🔑' : ''}</option>`;
                }).join('');

                if (selectedEnv) {
                    currentUrl.textContent = selectedEnv.url;
                }

                selector.addEventListener('change', async (e) => {
                    const envId = e.target.value;
                    try {
                        const response = await fetch(`/tools/tester/api/environment/select?env_id=${envId}`, {
                            method: 'POST'
                        });
                        const data = await response.json();

                        if (data.success) {
                            currentUrl.textContent = data.environment.url;
                            localStorage.setItem('selectedEnvironment', envId);
                        }
                    } catch (error) {
                        console.error('Failed to switch environment:', error);
                    }
                });
            } catch (error) {
                console.error('Failed to load environments:', error);
            }
        }

        // Load features from API
        async function loadFeatures() {
            try {
                // First sync features
                await fetch('/tools/tester/api/features/sync', { method: 'POST' });

                // Then load them
                const response = await fetch('/tools/tester/api/features');
                const data = await response.json();
                allFeatures = data.features;

                // Populate feature filters
                const featureFilters = document.getElementById('featureFilters');
                data.features.forEach(feature => {
                    const chip = document.createElement('div');
                    chip.className = 'filter-chip';
                    chip.dataset.filter = feature.name;
                    chip.textContent = feature.name;
                    chip.onclick = function() { toggleFeatureFilter(this); };
                    featureFilters.appendChild(chip);
                });

                // Load tags
                const tagsResponse = await fetch('/tools/tester/api/features/tags');
                const tagsData = await tagsResponse.json();

                const tagFilters = document.getElementById('tagFilters');
                tagsData.tags.forEach(tag => {
                    const chip = document.createElement('div');
                    chip.className = 'filter-chip';
                    chip.dataset.filter = tag;
                    chip.textContent = tag;
                    chip.onclick = function() { toggleTagFilter(this); };
                    tagFilters.appendChild(chip);
                });

            } catch (error) {
                console.error('Failed to load features:', error);
            }
        }

        // Load tests
        async function loadTests() {
            try {
                const response = await fetch('/tools/tester/api/tests');
                const data = await response.json();

                // For now, all tests are backend (until we integrate Playwright discovery)
                allTests = data.tests.map(t => ({
                    ...t,
                    type: 'backend',
                    feature: null,  // Will be populated from docstrings later
                    scenario: null,
                    tags: [],
                    pulse: {
                        role: null,
                        stage: null,
                    }
                }));

                renderTests();
            } catch (error) {
                console.error('Failed to load tests:', error);
                document.getElementById('testListBody').innerHTML = `
                    <div class="empty-state">
                        <div class="empty-state-icon">⚠️</div>
                        <div>Failed to load tests</div>
                    </div>
                `;
            }
        }

        // Apply preset filter
        function applyPreset(presetName) {
            const preset = presets[presetName];
            if (!preset) return;

            // Clear all filter chips
            document.querySelectorAll('.filter-chip').forEach(chip => {
                chip.classList.remove('active');
            });

            // Apply preset
            if (preset.features) {
                filters.features = new Set(preset.features);
                preset.features.forEach(f => {
                    const chip = document.querySelector(`#featureFilters [data-filter="${f}"]`);
                    if (chip) chip.classList.add('active');
                });
            }

            if (preset.tags) {
                filters.tags = new Set(preset.tags);
                preset.tags.forEach(t => {
                    const chip = document.querySelector(`#tagFilters [data-filter="${t}"]`);
                    if (chip) chip.classList.add('active');
                });
            }

            if (preset.roles) {
                filters.roles = new Set(preset.roles);
                preset.roles.forEach(r => {
                    const chip = document.querySelector(`#roleFilters [data-filter="${r}"]`);
                    if (chip) chip.classList.add('active');
                });
            }

            if (preset.stages) {
                filters.stages = new Set(preset.stages);
                preset.stages.forEach(s => {
                    const chip = document.querySelector(`#stageFilters [data-filter="${s}"]`);
                    if (chip) chip.classList.add('active');
                });
            }

            if (preset.testType) {
                filters.testType = new Set(preset.testType);
                preset.testType.forEach(t => {
                    const chip = document.querySelector(`[data-filter="${t}"]`);
                    if (chip && chip.parentElement.id !== 'featureFilters' && chip.parentElement.id !== 'tagFilters' && chip.parentElement.id !== 'roleFilters' && chip.parentElement.id !== 'stageFilters') {
                        chip.classList.add('active');
                    }
                });
            }

            // Update preset chips
            document.querySelectorAll('.preset-chip').forEach(chip => {
                chip.classList.toggle('active', chip.dataset.preset === presetName);
            });

            renderTests();
        }

        // Toggle filter functions
        function toggleFeatureFilter(chip) {
            toggleFilter(chip, filters.features, '#featureFilters');
        }

        function toggleTagFilter(chip) {
            toggleFilter(chip, filters.tags, '#tagFilters');
        }

        function toggleRoleFilter(chip) {
            toggleFilter(chip, filters.roles, '#roleFilters');
        }

        function toggleStageFilter(chip) {
            toggleFilter(chip, filters.stages, '#stageFilters');
        }

        function toggleTypeFilter(chip) {
            toggleFilter(chip, filters.testType, 'type');
        }

        function toggleFilter(chip, filterSet, containerSelector) {
            const filter = chip.dataset.filter;

            if (filter === 'all') {
                // Deselect all others
                if (containerSelector === 'type') {
                    document.querySelectorAll('[data-filter]').forEach(c => {
                        if (c.dataset.filter !== 'all' && c.parentElement.querySelector('.filter-chip[data-filter="all"]')) {
                            c.classList.remove('active');
                        }
                    });
                } else {
                    document.querySelectorAll(`${containerSelector} .filter-chip`).forEach(c => {
                        c.classList.remove('active');
                    });
                }
                chip.classList.add('active');
                filterSet.clear();
                filterSet.add('all');
            } else {
                // Remove 'all'
                if (containerSelector === 'type') {
                    document.querySelectorAll('[data-filter="all"]').forEach(c => {
                        if (c.parentElement.querySelector('.filter-chip[data-filter="all"]')) {
                            c.classList.remove('active');
                        }
                    });
                } else {
                    document.querySelector(`${containerSelector} [data-filter="all"]`).classList.remove('active');
                }

                if (filterSet.has(filter)) {
                    filterSet.delete(filter);
                    chip.classList.remove('active');
                } else {
                    filterSet.add(filter);
                    chip.classList.add('active');
                }

                filterSet.delete('all');

                // If nothing selected, select all
                if (filterSet.size === 0) {
                    if (containerSelector === 'type') {
                        document.querySelector('[data-filter="all"]').classList.add('active');
                    } else {
                        document.querySelector(`${containerSelector} [data-filter="all"]`).classList.add('active');
                    }
                    filterSet.add('all');
                }
            }

            renderTests();
        }

        // Clear filters
        function clearFilters() {
            document.getElementById('searchInput').value = '';
            filters.search = '';

            document.querySelectorAll('.filter-chip').forEach(chip => chip.classList.remove('active'));
            document.querySelectorAll('.filter-chip.all').forEach(chip => chip.classList.add('active'));

            filters.features = new Set(['all']);
            filters.tags = new Set(['all']);
            filters.roles = new Set(['all']);
            filters.stages = new Set(['all']);
            filters.testType = new Set(['all']);

            document.querySelectorAll('.preset-chip').forEach(chip => {
                chip.classList.toggle('active', chip.dataset.preset === 'all');
            });

            renderTests();
        }

        // Filter tests
        function filterTests() {
            return allTests.filter(test => {
                // Search filter
                if (filters.search) {
                    const searchLower = filters.search.toLowerCase();
                    const matchesSearch =
                        test.name.toLowerCase().includes(searchLower) ||
                        test.id.toLowerCase().includes(searchLower) ||
                        (test.doc && test.doc.toLowerCase().includes(searchLower)) ||
                        (test.feature && test.feature.toLowerCase().includes(searchLower)) ||
                        (test.scenario && test.scenario.toLowerCase().includes(searchLower));

                    if (!matchesSearch) return false;
                }

                // Feature filter
                if (!filters.features.has('all') && test.feature) {
                    if (!filters.features.has(test.feature)) return false;
                }

                // Tag filter
                if (!filters.tags.has('all') && test.tags.length > 0) {
                    const hasMatchingTag = test.tags.some(tag => filters.tags.has(tag));
                    if (!hasMatchingTag) return false;
                }

                // Role filter
                if (!filters.roles.has('all') && test.pulse.role) {
                    if (!filters.roles.has(test.pulse.role)) return false;
                }

                // Stage filter
                if (!filters.stages.has('all') && test.pulse.stage) {
                    if (!filters.stages.has(test.pulse.stage)) return false;
                }

                // Test type filter
                if (!filters.testType.has('all')) {
                    if (!filters.testType.has(test.type)) return false;
                }

                return true;
            });
        }

        // Render tests
        function renderTests() {
            const filteredTests = filterTests();
            const container = document.getElementById('testListBody');

            document.getElementById('testCount').textContent = `${filteredTests.length} of ${allTests.length}`;

            if (filteredTests.length === 0) {
                container.innerHTML = `
                    <div class="empty-state">
                        <div class="empty-state-icon">🔍</div>
                        <div>No tests match your filters</div>
                    </div>
                `;
                return;
            }

            container.innerHTML = filteredTests.map(test => {
                const isSelected = selectedTests.has(test.id);

                return `
                    <div class="test-card ${isSelected ? 'selected' : ''}" onclick="toggleTestSelection('${test.id}')" data-test-id="${test.id}">
                        <div class="test-header">
                            <div class="test-title">${formatTestName(test.name)}</div>
                            <span class="test-type ${test.type}">${test.type}</span>
                        </div>
                        <div style="font-size: 0.75rem; color: #9ca3af; margin-bottom: 6px;">
                            ${test.id}
                        </div>
                        <div style="font-size: 0.875rem; color: #d1d5db; margin-bottom: 6px;">
                            ${test.doc || 'No description'}
                        </div>
                        <div class="test-meta">
                            ${test.feature ? `<span class="meta-badge feature">📋 ${test.feature}</span>` : ''}
                            ${test.scenario ? `<span class="meta-badge">📝 ${test.scenario}</span>` : ''}
                            ${test.tags.map(tag => `<span class="meta-badge tag">${tag}</span>`).join('')}
                            ${test.pulse.role ? `<span class="meta-badge pulse">👤 ${test.pulse.role}</span>` : ''}
                            ${test.pulse.stage ? `<span class="meta-badge pulse">📍 ${test.pulse.stage}</span>` : ''}
                        </div>
                    </div>
                `;
            }).join('');

            updateSelectionInfo();
        }

        function formatTestName(name) {
            return name.replace(/^test_/, '').replace(/_/g, ' ');
        }

        function toggleTestSelection(testId) {
            if (selectedTests.has(testId)) {
                selectedTests.delete(testId);
            } else {
                selectedTests.add(testId);
            }

            const card = document.querySelector(`[data-test-id="${testId}"]`);
            if (card) {
                card.classList.toggle('selected');
            }

            updateSelectionInfo();
        }

        function selectAll() {
            const filteredTests = filterTests();
            filteredTests.forEach(test => selectedTests.add(test.id));
            renderTests();
        }

        function deselectAll() {
            selectedTests.clear();
            renderTests();
        }

        function updateSelectionInfo() {
            document.getElementById('selectedCount').textContent = selectedTests.size;
            document.getElementById('runSelectedBtn').disabled = selectedTests.size === 0;
        }

        async function runSelected() {
            if (selectedTests.size === 0) {
                alert('No tests selected');
                return;
            }

            const testIds = Array.from(selectedTests);

            try {
                const response = await fetch('/tools/tester/api/run', {
                    method: 'POST',
                    headers: { 'Content-Type': 'application/json' },
                    body: JSON.stringify({ test_ids: testIds }),
                });
                const data = await response.json();

                // Redirect to runner
                window.location.href = `/tools/tester/?run=${data.run_id}`;
            } catch (error) {
                console.error('Failed to start run:', error);
                alert('Failed to start test run');
            }
        }

        // Search input handler
        document.getElementById('searchInput').addEventListener('input', (e) => {
            filters.search = e.target.value;
            renderTests();
        });

        // Keyboard shortcuts
        function setupKeyboardShortcuts() {
            document.addEventListener('keydown', (e) => {
                // Ignore if typing in input
                if (e.target.tagName === 'INPUT') {
                    if (e.key === 'Escape') {
                        e.target.blur();
                    }
                    return;
                }

                // Enter - run selected
                if (e.key === 'Enter') {
                    e.preventDefault();
                    runSelected();
                }

                // Ctrl+A - select all
                if (e.ctrlKey && e.key === 'a') {
                    e.preventDefault();
                    selectAll();
                }

                // Ctrl+D - deselect all
                if (e.ctrlKey && e.key === 'd') {
                    e.preventDefault();
                    deselectAll();
                }

                // Ctrl+F - focus search
                if (e.ctrlKey && e.key === 'f') {
                    e.preventDefault();
                    document.getElementById('searchInput').focus();
                }

                // Ctrl+1-5 - quick presets
                if (e.ctrlKey && e.key >= '1' && e.key <= '5') {
                    e.preventDefault();
                    const presetNames = ['smoke', 'payment', 'coverage', 'frontend', 'backend'];
                    applyPreset(presetNames[parseInt(e.key) - 1]);
                }

                // ? - toggle help
                if (e.key === '?') {
                    const help = document.getElementById('shortcutsHelp');
                    help.classList.toggle('hidden');
                }
            });
        }

        // Initialize on page load
        init();
    </script>
</body>
</html>
