#!/usr/bin/env python3
"""
HTML Report Generator

Generates a clean, professional HTML report from JSON report data with search and filter capabilities.
"""

import json
from pathlib import Path
from datetime import datetime
from typing import Dict, List, Optional


def format_date(date_str: Optional[str]) -> str:
    """Format date string for display."""
    if not date_str:
        return "N/A"
    try:
        # Try parsing various formats
        if "/" in date_str:
            # MM/DD/YY or MM/DD/YYYY
            parts = date_str.split("/")
            if len(parts) == 3:
                if len(parts[2]) == 2:
                    # Convert YY to YYYY
                    parts[2] = "20" + parts[2]
                return "/".join(parts)
        # Already formatted or ISO format
        return date_str.split()[0] if " " in date_str else date_str
    except:
        return date_str


def get_status_badge_class(status: str) -> str:
    """Get CSS class for status badge."""
    status_lower = status.lower().strip()
    # Check for incomplete FIRST (before checking for "complete" substring)
    # because "incomplete" contains "complete" as a substring!
    if "incomplete" in status_lower:
        return "badge-warning"  # Yellow/orange like Monitor
    elif "complete" in status_lower:
        return "badge-success"  # Green
    elif "monitor" in status_lower:
        return "badge-warning"  # Yellow/orange
    else:
        return "badge-secondary"


def get_priority_badge_class(priority: Optional[str]) -> str:
    """Get CSS class for priority badge."""
    if not priority:
        return "badge-secondary"
    priority_lower = priority.lower()
    if "very high" in priority_lower or "(1)" in priority_lower:
        return "badge-critical"
    elif "high" in priority_lower or "(2)" in priority_lower:
        return "badge-high"
    elif "medium" in priority_lower or "(3)" in priority_lower:
        return "badge-medium"
    elif "low" in priority_lower or "(4)" in priority_lower:
        return "badge-low"
    else:
        return "badge-secondary"


def escape_js_string(s: str) -> str:
    """Escape a string for use in JavaScript double-quoted strings."""
    return s.replace('\\', '\\\\').replace('"', '\\"').replace('\n', '\\n').replace('\r', '\\r')


def generate_html_report(json_path: str, output_path: Optional[str] = None) -> str:
    """
    Generate HTML report from JSON report file.
    
    Args:
        json_path: Path to JSON report file
        output_path: Optional output HTML file path (defaults to same location as JSON with .html extension)
    
    Returns:
        Path to generated HTML file
    """
    # Load JSON report
    with open(json_path, 'r', encoding='utf-8') as f:
        report_data = json.load(f)
    
    # Determine output path
    if output_path is None:
        json_file = Path(json_path)
        output_path = json_file.parent / f"{json_file.stem}.html"
    else:
        output_path = Path(output_path)
    
    # Generate HTML
    html_content = generate_html_content(report_data)
    
    # Save HTML file
    output_path.parent.mkdir(parents=True, exist_ok=True)
    with open(output_path, 'w', encoding='utf-8') as f:
        f.write(html_content)
    
    return str(output_path)


def generate_html_content(report_data: Dict) -> str:
    """Generate HTML content from report data."""
    
    vendors = report_data.get('vendors', [])
    summary = report_data.get('summary', {})
    report_generated_at = report_data.get('report_generated_at', datetime.now().isoformat())
    
    # Format generation time
    try:
        gen_time = datetime.fromisoformat(report_generated_at.replace('Z', '+00:00'))
        gen_time_str = gen_time.strftime('%Y-%m-%d %H:%M:%S')
    except:
        gen_time_str = report_generated_at
    
    # Extract vendor names for filter
    vendor_names = sorted([v.get('vendor_name', '') for v in vendors if v.get('vendor_name')])
    
    html = rf"""<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Vendor Punchlist Report</title>
    <style>
        * {{
            margin: 0;
            padding: 0;
            box-sizing: border-box;
        }}
        
        body {{
            font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, 'Helvetica Neue', Arial, sans-serif;
            line-height: 1.6;
            color: #1f2937;
            background-color: #f9fafb;
            padding: 20px;
        }}
        
        .container {{
            max-width: 1600px;
            margin: 0 auto;
            background: white;
            border-radius: 8px;
            box-shadow: 0 4px 6px rgba(0,0,0,0.1);
            padding: 40px;
        }}
        
        header {{
            border-bottom: 3px solid #2563eb;
            padding-bottom: 25px;
            margin-bottom: 30px;
        }}
        
        h1 {{
            color: #1e40af;
            font-size: 2.5em;
            margin-bottom: 10px;
            font-weight: 600;
        }}
        
        .meta {{
            color: #6b7280;
            font-size: 0.95em;
        }}
        
        .filters-bar {{
            background: #f3f4f6;
            padding: 20px;
            border-radius: 8px;
            margin-bottom: 30px;
            border: 1px solid #e5e7eb;
        }}
        
        .filters-title {{
            font-weight: 600;
            color: #374151;
            margin-bottom: 15px;
            font-size: 1.1em;
        }}
        
        .filters-grid {{
            display: grid;
            grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
            gap: 15px;
            margin-bottom: 15px;
        }}
        
        .filter-group {{
            display: flex;
            flex-direction: column;
        }}
        
        .filter-label {{
            font-size: 0.85em;
            color: #6b7280;
            margin-bottom: 5px;
            font-weight: 500;
        }}
        
        .filter-input {{
            padding: 8px 12px;
            border: 1px solid #d1d5db;
            border-radius: 6px;
            font-size: 0.95em;
            background: white;
            color: #1f2937;
        }}
        
        .filter-input:focus {{
            outline: none;
            border-color: #2563eb;
            box-shadow: 0 0 0 3px rgba(37, 99, 235, 0.1);
        }}
        
        .filter-select {{
            padding: 8px 12px;
            border: 1px solid #d1d5db;
            border-radius: 6px;
            font-size: 0.95em;
            background: white;
            color: #1f2937;
            cursor: pointer;
        }}
        
        .filter-select:focus {{
            outline: none;
            border-color: #2563eb;
            box-shadow: 0 0 0 3px rgba(37, 99, 235, 0.1);
        }}
        
        .filter-actions {{
            display: flex;
            gap: 10px;
            margin-top: 10px;
        }}
        
        .btn {{
            padding: 8px 16px;
            border: none;
            border-radius: 6px;
            font-size: 0.9em;
            font-weight: 500;
            cursor: pointer;
            transition: all 0.2s;
        }}
        
        .btn-primary {{
            background: #2563eb;
            color: white;
        }}
        
        .btn-primary:hover {{
            background: #1d4ed8;
        }}
        
        .btn-secondary {{
            background: #6b7280;
            color: white;
        }}
        
        .btn-secondary:hover {{
            background: #4b5563;
        }}
        
        .results-count {{
            color: #6b7280;
            font-size: 0.9em;
            margin-top: 10px;
        }}
        
        .quick-filters-bar {{
            background: #f9fafb;
            padding: 20px;
            border-radius: 8px;
            margin-bottom: 30px;
            border: 1px solid #e5e7eb;
        }}
        
        .quick-filters-title {{
            font-weight: 600;
            color: #374151;
            margin-bottom: 15px;
            font-size: 1.05em;
        }}
        
        .quick-filters {{
            display: flex;
            gap: 12px;
            flex-wrap: wrap;
        }}
        
        .quick-filter-btn {{
            padding: 10px 20px;
            border: 2px solid #2563eb;
            border-radius: 6px;
            font-size: 0.95em;
            font-weight: 500;
            cursor: pointer;
            transition: all 0.2s;
            background: white;
            color: #2563eb;
        }}
        
        .quick-filter-btn:hover {{
            background: #eff6ff;
            border-color: #1d4ed8;
        }}
        
        .quick-filter-btn.active {{
            background: #2563eb;
            color: white;
            border-color: #2563eb;
        }}
        
        .summary-cards {{
            display: grid;
            grid-template-columns: repeat(auto-fit, minmax(180px, 1fr));
            gap: 20px;
            margin-bottom: 40px;
        }}
        
        .summary-card {{
            background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
            color: white;
            padding: 24px;
            border-radius: 8px;
            text-align: center;
            box-shadow: 0 2px 4px rgba(0,0,0,0.1);
        }}
        
        .summary-card h3 {{
            font-size: 2.2em;
            margin-bottom: 8px;
            font-weight: 600;
        }}
        
        .summary-card p {{
            opacity: 0.95;
            font-size: 0.95em;
            font-weight: 500;
        }}
        
        .summary-card.success {{
            background: linear-gradient(135deg, #10b981 0%, #059669 100%);
        }}
        
        .summary-card.warning {{
            background: linear-gradient(135deg, #f59e0b 0%, #d97706 100%);
        }}
        
        .summary-card.danger {{
            background: linear-gradient(135deg, #ef4444 0%, #dc2626 100%);
        }}
        
        .vendor-section {{
            margin-bottom: 40px;
            border: 1px solid #e5e7eb;
            border-radius: 8px;
            overflow: hidden;
            transition: opacity 0.3s;
        }}
        
        .vendor-section.hidden {{
            display: none;
        }}
        
        .vendor-header {{
            background: #f9fafb;
            padding: 24px;
            border-bottom: 2px solid #e5e7eb;
            display: flex;
            justify-content: space-between;
            align-items: center;
            flex-wrap: wrap;
            gap: 20px;
        }}
        
        .vendor-name {{
            font-size: 1.6em;
            font-weight: 600;
            color: #1e40af;
        }}
        
        .vendor-stats {{
            display: flex;
            gap: 20px;
            flex-wrap: wrap;
        }}
        
        .stat-item {{
            text-align: center;
            padding: 12px 18px;
            background: white;
            border-radius: 6px;
            border: 1px solid #e5e7eb;
            min-width: 80px;
        }}
        
        .stat-value {{
            font-size: 1.8em;
            font-weight: 600;
            color: #1e40af;
        }}
        
        .stat-label {{
            font-size: 0.85em;
            color: #6b7280;
            margin-top: 5px;
            font-weight: 500;
        }}
        
        .vendor-content {{
            padding: 24px;
        }}
        
        .section {{
            margin-bottom: 30px;
        }}
        
        .section-title {{
            font-size: 1.25em;
            font-weight: 600;
            color: #374151;
            margin-bottom: 15px;
            padding-bottom: 10px;
            border-bottom: 2px solid #e5e7eb;
        }}
        
        .updates-grid {{
            display: grid;
            grid-template-columns: repeat(auto-fit, minmax(320px, 1fr));
            gap: 20px;
            margin-bottom: 20px;
        }}
        
        .update-box {{
            border: 1px solid #e5e7eb;
            border-radius: 6px;
            padding: 20px;
            background: #f9fafb;
        }}
        
        .update-box h4 {{
            color: #1e40af;
            margin-bottom: 12px;
            font-size: 1.05em;
            font-weight: 600;
        }}
        
        .item-list {{
            list-style: none;
        }}
        
        .item-list li {{
            padding: 14px;
            margin-bottom: 12px;
            background: white;
            border-left: 4px solid #2563eb;
            border-radius: 4px;
            box-shadow: 0 1px 3px rgba(0,0,0,0.08);
            transition: box-shadow 0.2s;
        }}
        
        .item-list li:hover {{
            box-shadow: 0 2px 6px rgba(0,0,0,0.12);
        }}
        
        .item-list li.empty {{
            color: #9ca3af;
            font-style: italic;
            border-left-color: #d1d5db;
            background: #f9fafb;
        }}
        
        .item-header {{
            display: flex;
            justify-content: space-between;
            align-items: flex-start;
            margin-bottom: 10px;
            flex-wrap: wrap;
            gap: 12px;
        }}
        
        .item-name {{
            font-weight: 600;
            color: #1e40af;
            flex: 1;
            font-size: 1.05em;
        }}
        
        .badges {{
            display: flex;
            gap: 8px;
            flex-wrap: wrap;
        }}
        
        .badge {{
            padding: 5px 12px;
            border-radius: 4px;
            font-size: 0.75em;
            font-weight: 600;
            text-transform: uppercase;
            letter-spacing: 0.5px;
        }}
        
        .badge-success {{
            background: #d1fae5;
            color: #065f46;
        }}
        
        .badge-warning {{
            background: #fef3c7;
            color: #92400e;
        }}
        
        .badge-danger {{
            background: #dc2626;
            color: white;
        }}
        
        .badge-secondary {{
            background: #e5e7eb;
            color: #374151;
        }}
        
        .badge-critical {{
            background: #fee2e2;
            color: #991b1b;
            font-weight: 700;
        }}
        
        .badge-high {{
            background: #fed7aa;
            color: #9a3412;
        }}
        
        .badge-medium {{
            background: #fef3c7;
            color: #92400e;
        }}
        
        .badge-low {{
            background: #dbeafe;
            color: #1e40af;
        }}
        
        .item-details {{
            margin-top: 10px;
            font-size: 0.9em;
            color: #6b7280;
        }}
        
        .item-details p {{
            margin-bottom: 6px;
            line-height: 1.5;
        }}
        
        .item-details strong {{
            color: #374151;
            font-weight: 600;
        }}
        
        .item-description {{
            margin-top: 8px;
            color: #4b5563;
            line-height: 1.6;
        }}
        
        .age-days {{
            color: #dc2626;
            font-weight: 600;
            font-size: 0.9em;
        }}
        
        .tabs-container {{
            margin-bottom: 30px;
            border-bottom: 2px solid #e5e7eb;
        }}
        
        .tabs {{
            display: flex;
            gap: 0;
            flex-wrap: wrap;
            margin-bottom: 0;
        }}
        
        .tab {{
            padding: 12px 24px;
            background: #f3f4f6;
            border: none;
            border-bottom: 3px solid transparent;
            cursor: pointer;
            font-size: 0.95em;
            font-weight: 500;
            color: #6b7280;
            transition: all 0.2s;
            white-space: nowrap;
        }}
        
        .tab:hover {{
            background: #e5e7eb;
            color: #374151;
        }}
        
        .tab.active {{
            background: white;
            color: #1e40af;
            border-bottom-color: #2563eb;
            font-weight: 600;
        }}
        
        .tab-content {{
            display: none;
        }}
        
        .tab-content.active {{
            display: block;
        }}
        
        .status-tabs {{
            display: flex;
            gap: 0;
            margin-bottom: 20px;
            border-bottom: 2px solid #e5e7eb;
        }}
        
        .status-tab {{
            padding: 10px 20px;
            background: transparent;
            border: none;
            border-bottom: 3px solid transparent;
            cursor: pointer;
            font-size: 0.9em;
            font-weight: 500;
            color: #6b7280;
            transition: all 0.2s;
        }}
        
        .status-tab:hover {{
            color: #374151;
            background: #f9fafb;
        }}
        
        .status-tab.active {{
            color: #1e40af;
            border-bottom-color: #2563eb;
            font-weight: 600;
        }}
        
        .status-tab-content {{
            display: none;
        }}
        
        .status-tab-content.active {{
            display: block;
        }}
        
        .updates-sub-tabs {{
            display: flex;
            gap: 0;
            margin-bottom: 20px;
            border-bottom: 2px solid #e5e7eb;
        }}
        
        .update-tab-content {{
            display: none;
        }}
        
        .update-tab-content.active {{
            display: block;
        }}
        
        .footer {{
            margin-top: 50px;
            padding-top: 25px;
            border-top: 2px solid #e5e7eb;
            text-align: center;
            color: #6b7280;
            font-size: 0.9em;
        }}
        
        @media print {{
            body {{
                background: white;
                padding: 0;
            }}
            
            .container {{
                box-shadow: none;
            }}
            
            .filters-bar {{
                display: none;
            }}
            
            .vendor-section {{
                page-break-inside: avoid;
            }}
        }}
    </style>
</head>
<body>
    <div class="container">
        <header>
            <h1>Vendor Punchlist Report</h1>
            <div class="meta">
                Generated: {gen_time_str} | 
                Total Vendors: {summary.get('total_vendors', 0)} | 
                Total Items: {summary.get('total_items', 0)}
            </div>
        </header>
        
        <div class="filters-bar">
            <div class="filters-title">Filters & Search</div>
            <div class="filters-grid">
                <div class="filter-group">
                    <label class="filter-label">Search Items</label>
                    <input type="text" id="search-input" class="filter-input" placeholder="Search by name or description...">
                </div>
                <div class="filter-group">
                    <label class="filter-label">Vendor</label>
                    <select id="vendor-filter" class="filter-select">
                        <option value="">All Vendors</option>
                        {''.join([f'<option value="{vn}">{vn}</option>' for vn in vendor_names])}
                    </select>
                </div>
                <div class="filter-group">
                    <label class="filter-label">Status</label>
                    <select id="status-filter" class="filter-select">
                        <option value="">All Statuses</option>
                        <option value="Complete">Complete</option>
                        <option value="Monitor">Monitor</option>
                        <option value="Incomplete">Incomplete</option>
                    </select>
                </div>
                <div class="filter-group">
                    <label class="filter-label">Priority</label>
                    <select id="priority-filter" class="filter-select">
                        <option value="">All Priorities</option>
                        <option value="very_high">Very High</option>
                        <option value="high">High</option>
                        <option value="medium">Medium</option>
                        <option value="low">Low</option>
                    </select>
                </div>
            </div>
            <div class="filter-actions">
                <button class="btn btn-primary" onclick="applyFilters()">Apply Filters</button>
                <button class="btn btn-secondary" onclick="clearFilters()">Clear All</button>
            </div>
            <div class="results-count" id="results-count"></div>
        </div>
        
        <div class="quick-filters-bar">
            <div class="quick-filters-title">Quick Filters</div>
            <div class="quick-filters">
                <button class="quick-filter-btn" onclick="showOnly24hUpdates()" id="filter-24h-updates">Show Only Vendors with Yesterday's Updates</button>
                <button class="quick-filter-btn" onclick="showOnlyOldestUnaddressed()" id="filter-oldest-unaddressed">Show Only Vendors with Oldest Unaddressed</button>
                <button class="quick-filter-btn" onclick="showAllVendors()" id="filter-all-vendors">Show All Vendors</button>
            </div>
        </div>
        
        <div class="summary-cards">
            <div class="summary-card">
                <h3>{summary.get('total_vendors', 0)}</h3>
                <p>Vendors</p>
            </div>
            <div class="summary-card">
                <h3>{summary.get('total_items', 0)}</h3>
                <p>Total Items</p>
            </div>
            <div class="summary-card success">
                <h3>{summary.get('total_closed', 0)}</h3>
                <p>Closed</p>
            </div>
            <div class="summary-card warning">
                <h3>{summary.get('total_monitor', 0)}</h3>
                <p>Monitor</p>
            </div>
            <div class="summary-card warning">
                <h3>{summary.get('total_incomplete', 0)}</h3>
                <p>Incomplete</p>
            </div>
        </div>
        
        <div class="tabs-container">
            <div class="tabs" id="vendor-tabs">
                <button class="tab active" onclick="switchVendorTab('all')" data-vendor="all">All Vendors</button>
                {''.join(['<button class="tab" onclick="switchVendorTab(' + "'" + escape_js_string(vn) + "'" + ')" data-vendor="' + vn + '">' + vn + '</button>' for vn in vendor_names])}
            </div>
        </div>
        
        <div id="vendor-sections">
            {generate_vendor_sections(vendors)}
        </div>
        
        <div class="footer">
            <p>Report generated automatically from Excel punchlist data</p>
        </div>
    </div>
    
    <script>
        let currentVendorTab = 'all';
        
        function switchVendorTab(vendorName) {{
            currentVendorTab = vendorName;
            
            // Update tab buttons
            document.querySelectorAll('#vendor-tabs .tab').forEach(tab => {{
                if (tab.dataset.vendor === vendorName) {{
                    tab.classList.add('active');
                }} else {{
                    tab.classList.remove('active');
                }}
            }});
            
            // Show/hide vendor sections
            document.querySelectorAll('.vendor-section').forEach(section => {{
                const sectionVendor = section.dataset.vendor;
                if (vendorName === 'all' || sectionVendor === vendorName) {{
                    section.style.display = '';
                }} else {{
                    section.style.display = 'none';
                }}
            }});
            
            // Reapply filters after switching tabs
            applyFilters();
        }}
        
        function applyFilters() {{
            const searchText = document.getElementById('search-input').value.toLowerCase();
            const vendorFilter = document.getElementById('vendor-filter').value;
            const statusFilter = document.getElementById('status-filter').value;
            const priorityFilter = document.getElementById('priority-filter').value;
            
            const vendorSections = document.querySelectorAll('.vendor-section');
            let visibleCount = 0;
            
            vendorSections.forEach(section => {{
                const vendorName = section.querySelector('.vendor-name').textContent.trim();
                const items = section.querySelectorAll('.item-list li');
                let hasVisibleItems = false;
                
                // Check vendor tab (currentVendorTab)
                if (currentVendorTab !== 'all' && vendorName !== currentVendorTab) {{
                    section.style.display = 'none';
                    return;
                }}
                
                // Check vendor filter
                if (vendorFilter && vendorName !== vendorFilter) {{
                    section.style.display = 'none';
                    return;
                }}
                
                // Filter items within section
                items.forEach(item => {{
                    const itemName = item.querySelector('.item-name')?.textContent.toLowerCase() || '';
                    const itemDescription = item.querySelector('.item-description')?.textContent.toLowerCase() || '';
                    const itemDetails = item.querySelector('.item-details')?.textContent.toLowerCase() || '';
                    const itemText = (itemName + ' ' + itemDescription + ' ' + itemDetails).toLowerCase();
                    
                    const statusBadge = item.querySelector('.badge-success, .badge-warning, .badge-danger');
                    const status = statusBadge ? statusBadge.textContent.trim() : '';
                    
                    const priorityBadge = item.querySelector('.badge-critical, .badge-high, .badge-medium, .badge-low');
                    const priority = priorityBadge ? priorityBadge.textContent.toLowerCase() : '';
                    let priorityMatch = priorityFilter === '';
                    if (priorityFilter === 'very_high' && (priority.includes('very high') || priority.includes('critical'))) {{
                        priorityMatch = true;
                    }} else if (priorityFilter === 'high' && priority.includes('high') && !priority.includes('very')) {{
                        priorityMatch = true;
                    }} else if (priorityFilter === 'medium' && priority.includes('medium')) {{
                        priorityMatch = true;
                    }} else if (priorityFilter === 'low' && priority.includes('low')) {{
                        priorityMatch = true;
                    }}
                    
                    const matchesSearch = !searchText || itemText.includes(searchText);
                    const matchesStatus = !statusFilter || status === statusFilter;
                    const matchesPriority = priorityMatch;
                    
                    if (matchesSearch && matchesStatus && matchesPriority) {{
                        item.style.display = '';
                        hasVisibleItems = true;
                    }} else {{
                        item.style.display = 'none';
                    }}
                }});
                
                // Show/hide empty sections
                const visibleItems = section.querySelectorAll('.item-list li[style=""], .item-list li:not([style*="display: none"])');
                if (visibleItems.length > 0 || (!searchText && !statusFilter && !priorityFilter)) {{
                    section.style.display = '';
                    visibleCount++;
                }} else {{
                    section.style.display = 'none';
                }}
            }});
            
            // Update results count
            document.getElementById('results-count').textContent = 
                `Showing ${{visibleCount}} vendor section(s) matching filters`;
        }}
        
        function clearFilters() {{
            document.getElementById('search-input').value = '';
            document.getElementById('vendor-filter').value = '';
            document.getElementById('status-filter').value = '';
            document.getElementById('priority-filter').value = '';
            
            // Reset to "All Vendors" tab
            switchVendorTab('all');
            
            // Show all sections and items
            document.querySelectorAll('.vendor-section').forEach(section => {{
                section.style.display = '';
            }});
            
            document.querySelectorAll('.item-list li').forEach(item => {{
                item.style.display = '';
            }});
            
            // Reset status tabs in each vendor section
            document.querySelectorAll('.status-tab').forEach(tab => {{
                tab.classList.remove('active');
            }});
            document.querySelectorAll('.status-tab-content').forEach(content => {{
                content.classList.remove('active');
            }});
            
            // Activate "All" status tabs
            document.querySelectorAll('.status-tab[data-status="all"]').forEach(tab => {{
                tab.classList.add('active');
            }});
            document.querySelectorAll('.status-tab-content[data-status="all"]').forEach(content => {{
                content.classList.add('active');
            }});
            
            document.getElementById('results-count').textContent = '';
        }}
        
        // Apply filters on Enter key in search
        document.addEventListener('DOMContentLoaded', function() {{
            document.getElementById('search-input').addEventListener('keypress', function(e) {{
                if (e.key === 'Enter') {{
                    applyFilters();
                }}
            }});
            
            // Auto-apply on filter change
            document.getElementById('vendor-filter').addEventListener('change', applyFilters);
            document.getElementById('status-filter').addEventListener('change', applyFilters);
            document.getElementById('priority-filter').addEventListener('change', applyFilters);
        }});
        
        function switchStatusTab(tabElement, vendorName) {{
            const status = tabElement.dataset.status;
            
            // Update tabs for this vendor
            const vendorSection = document.querySelector(`.vendor-section[data-vendor="${{vendorName}}"]`);
            if (!vendorSection) return;
            
            vendorSection.querySelectorAll('.status-tab').forEach(t => {{
                if (t.dataset.status === status) {{
                    t.classList.add('active');
                }} else {{
                    t.classList.remove('active');
                }}
            }});
            
            // Update content for this vendor
            vendorSection.querySelectorAll('.status-tab-content').forEach(content => {{
                if (content.dataset.status === status && content.dataset.vendor === vendorName) {{
                    content.classList.add('active');
                }} else {{
                    content.classList.remove('active');
                }}
            }});
        }}
        
        function switchUpdateTab(tabElement, vendorNameSafe) {{
            const updateType = tabElement.dataset.updateType;
            
            // Find the parent updates section
            const updatesSection = tabElement.closest('.section');
            if (!updatesSection) return;
            
            // Update sub-tabs
            updatesSection.querySelectorAll('.updates-sub-tabs .status-tab').forEach(t => {{
                if (t.dataset.updateType === updateType) {{
                    t.classList.add('active');
                }} else {{
                    t.classList.remove('active');
                }}
            }});
            
            // Update content
            updatesSection.querySelectorAll('.update-tab-content').forEach(content => {{
                if (content.dataset.updateType === updateType && content.dataset.vendorUpdate === vendorNameSafe) {{
                    content.classList.add('active');
                }} else {{
                    content.classList.remove('active');
                }}
            }});
        }}
        
        function showOnly24hUpdates() {{
            // Remove active class from all quick filter buttons
            document.querySelectorAll('.quick-filter-btn').forEach(btn => {{
                btn.classList.remove('active');
            }});
            document.getElementById('filter-24h-updates').classList.add('active');
            
            // Show only vendors with 24h updates, and switch to updates tab
            let visibleCount = 0;
            document.querySelectorAll('.vendor-section').forEach(section => {{
                const vendorName = section.dataset.vendor;
                const updates24hTab = section.querySelector('.status-tab[data-status="updates_24h"]');
                
                if (updates24hTab) {{
                    // Check the tab text for count - format is "Yesterday's Updates (X)"
                    const tabText = updates24hTab.textContent.trim();
                    const match = tabText.match(/\((\d+)\)/);
                    const count = match ? parseInt(match[1]) : 0;
                    
                    if (count > 0) {{
                        section.style.display = '';
                        visibleCount++;
                        
                        // Switch to updates_24h tab for this vendor
                        switchStatusTab(updates24hTab, vendorName);
                        
                        // Hide all other tab content except updates_24h
                        section.querySelectorAll('.status-tab-content').forEach(content => {{
                            if (content.dataset.status === 'updates_24h' && content.dataset.vendor === vendorName) {{
                                content.classList.add('active');
                            }} else {{
                                content.classList.remove('active');
                            }}
                        }});
                    }} else {{
                        section.style.display = 'none';
                    }}
                }} else {{
                    section.style.display = 'none';
                }}
            }});
            
            // Update results count
            document.getElementById('results-count').textContent = 
                `Showing yesterday's update items from ${{visibleCount}} vendor(s)`;
        }}
        
        function showOnlyOldestUnaddressed() {{
            // Remove active class from all quick filter buttons
            document.querySelectorAll('.quick-filter-btn').forEach(btn => {{
                btn.classList.remove('active');
            }});
            document.getElementById('filter-oldest-unaddressed').classList.add('active');
            
            // Switch to "All Vendors" tab first
            switchVendorTab('all');
            
            // Show only vendors with oldest unaddressed items, and switch to oldest tab
            let visibleCount = 0;
            document.querySelectorAll('.vendor-section').forEach(section => {{
                const vendorName = section.dataset.vendor;
                const oldestTab = section.querySelector('.status-tab[data-status="oldest_unaddressed"]');
                const oldestContent = section.querySelector('.status-tab-content[data-status="oldest_unaddressed"]');
                
                if (oldestTab && oldestContent) {{
                    // Check the tab text for count - format is "Oldest Unaddressed (X)"
                    const tabText = oldestTab.textContent.trim();
                    // Use a simpler regex pattern that works reliably
                    const match = tabText.match(/\((\d+)\)/);
                    const count = match ? parseInt(match[1]) : 0;
                    
                    // Also check if there are actual items in the content
                    const items = oldestContent.querySelectorAll('.item-list li:not(.empty)');
                    const hasItems = items.length > 0;
                    
                    if (count > 0 && hasItems) {{
                        section.style.display = '';
                        visibleCount++;
                        
                        // Switch to oldest_unaddressed tab for this vendor
                        switchStatusTab(oldestTab, vendorName);
                        
                        // Hide all other tab content except oldest_unaddressed
                        section.querySelectorAll('.status-tab-content').forEach(content => {{
                            if (content.dataset.status === 'oldest_unaddressed' && content.dataset.vendor === vendorName) {{
                                content.classList.add('active');
                            }} else {{
                                content.classList.remove('active');
                            }}
                        }});
                    }} else {{
                        section.style.display = 'none';
                    }}
                }} else {{
                    section.style.display = 'none';
                }}
            }});
            
            // Update results count
            document.getElementById('results-count').textContent = 
                `Showing oldest unaddressed items from ${{visibleCount}} vendor(s)`;
        }}
        
        function showAllVendors() {{
            // Remove active class from all quick filter buttons
            document.querySelectorAll('.quick-filter-btn').forEach(btn => {{
                btn.classList.remove('active');
            }});
            document.getElementById('filter-all-vendors').classList.add('active');
            
            // Show all vendor sections
            document.querySelectorAll('.vendor-section').forEach(section => {{
                section.style.display = '';
                
                // Reset all tabs to "All" tab for each vendor
                const vendorName = section.dataset.vendor;
                const allTab = section.querySelector('.status-tab[data-status="all"]');
                if (allTab) {{
                    switchStatusTab(allTab, vendorName);
                }}
            }});
            
            // Clear results count or reapply filters if any are set
            const searchText = document.getElementById('search-input').value;
            const vendorFilter = document.getElementById('vendor-filter').value;
            const statusFilter = document.getElementById('status-filter').value;
            const priorityFilter = document.getElementById('priority-filter').value;
            
            if (searchText || vendorFilter || statusFilter || priorityFilter) {{
                applyFilters();
            }} else {{
                document.getElementById('results-count').textContent = '';
            }}
        }}
    </script>
</body>
</html>"""
    
    return html


def generate_vendor_sections(vendors: List[Dict]) -> str:
    """Generate HTML for all vendor sections."""
    sections = []
    
    for vendor in vendors:
        sections.append(generate_vendor_section(vendor))
    
    return "\n".join(sections)


def generate_vendor_section(vendor: Dict) -> str:
    """Generate HTML for a single vendor section."""
    vendor_name = vendor.get('vendor_name', 'Unknown')
    total_items = vendor.get('total_items', 0)
    closed_count = vendor.get('closed_count', 0)
    monitor_count = vendor.get('monitor_count', 0)
    incomplete_count = vendor.get('incomplete_count', 0)
    
    updates_24h = vendor.get('updates_24h', {})
    oldest_unaddressed = vendor.get('oldest_unaddressed', [])
    very_high_items = vendor.get('very_high_priority_items', [])
    high_items = vendor.get('high_priority_items', [])
    
    # Use the pre-populated status-grouped items from report_generator
    # These contain ALL items, not just priority/oldest subsets
    closed_items = vendor.get('closed_items', [])
    monitor_items = vendor.get('monitor_items', [])
    incomplete_items = vendor.get('incomplete_items', [])
    
    # Convert to lists if needed (they should already be lists)
    if not isinstance(closed_items, list):
        closed_items = []
    if not isinstance(monitor_items, list):
        monitor_items = []
    if not isinstance(incomplete_items, list):
        incomplete_items = []
    
    # Group all items by priority for the "All" tab
    # Combine all items first with deduplication
    # Since we're already within a vendor section, deduplicate by punchlist_name only
    all_items_combined = []
    seen_names = set()  # Track by normalized punchlist_name for deduplication
    
    # Add all closed items
    for item in closed_items:
        name = item.get('punchlist_name', '').strip().lower()
        if name and name not in seen_names:
            seen_names.add(name)
            all_items_combined.append(item)
    
    # Add all monitor items
    for item in monitor_items:
        name = item.get('punchlist_name', '').strip().lower()
        if name and name not in seen_names:
            seen_names.add(name)
            all_items_combined.append(item)
    
    # Add all incomplete items
    for item in incomplete_items:
        name = item.get('punchlist_name', '').strip().lower()
        if name and name not in seen_names:
            seen_names.add(name)
            all_items_combined.append(item)
    
    # Group items by priority level
    very_high_all = []
    high_all = []
    medium_all = []
    low_all = []
    other_priority_all = []
    no_priority_all = []
    
    for item in all_items_combined:
        priority = item.get('priority', '') or ''
        priority_lower = priority.lower()
        
        if 'very high' in priority_lower or '(1)' in priority_lower or 'very hgh' in priority_lower:
            very_high_all.append(item)
        elif ('high' in priority_lower and 'very' not in priority_lower) or '(2)' in priority_lower:
            high_all.append(item)
        elif 'medium' in priority_lower or '(3)' in priority_lower:
            medium_all.append(item)
        elif 'low' in priority_lower or '(4)' in priority_lower:
            low_all.append(item)
        elif priority.strip():
            other_priority_all.append(item)
        else:
            no_priority_all.append(item)
    
    html = f"""
        <div class="vendor-section" data-vendor="{vendor_name}">
            <div class="vendor-header">
                <div class="vendor-name">{vendor_name}</div>
                <div class="vendor-stats">
                    <div class="stat-item">
                        <div class="stat-value">{total_items}</div>
                        <div class="stat-label">Total</div>
                    </div>
                    <div class="stat-item">
                        <div class="stat-value" style="color: #10b981;">{closed_count}</div>
                        <div class="stat-label">Closed</div>
                    </div>
                    <div class="stat-item">
                        <div class="stat-value" style="color: #f59e0b;">{monitor_count}</div>
                        <div class="stat-label">Monitor</div>
                    </div>
                    <div class="stat-item">
                        <div class="stat-value" style="color: #f59e0b;">{incomplete_count}</div>
                        <div class="stat-label">Incomplete</div>
                    </div>
                </div>
            </div>
            
            <div class="vendor-content">
                <div class="status-tabs">
                    <button class="status-tab active" onclick="switchStatusTab(this, '{vendor_name}')" data-status="all">All ({total_items})</button>
                    <button class="status-tab" onclick="switchStatusTab(this, '{vendor_name}')" data-status="updates_24h">Yesterday's Updates ({len(updates_24h.get('added', [])) + len(updates_24h.get('closed', [])) + len(updates_24h.get('changed_to_monitor', []))})</button>
                    <button class="status-tab" onclick="switchStatusTab(this, '{vendor_name}')" data-status="oldest_unaddressed">Oldest Unaddressed ({len(oldest_unaddressed)})</button>
                    <button class="status-tab" onclick="switchStatusTab(this, '{vendor_name}')" data-status="closed">Closed ({closed_count})</button>
                    <button class="status-tab" onclick="switchStatusTab(this, '{vendor_name}')" data-status="monitor">Monitor ({monitor_count})</button>
                    <button class="status-tab" onclick="switchStatusTab(this, '{vendor_name}')" data-status="incomplete">Incomplete ({incomplete_count})</button>
                </div>
                
                <div class="status-tab-content active" data-status="all" data-vendor="{vendor_name}">
                    {generate_priority_items_section('Very High Priority', very_high_all)}
                    {generate_priority_items_section('High Priority', high_all)}
                    {generate_priority_items_section('Medium Priority', medium_all)}
                    {generate_priority_items_section('Low Priority', low_all)}
                    {generate_priority_items_section('Other Priority', other_priority_all) if other_priority_all else ''}
                    {generate_priority_items_section('No Priority', no_priority_all) if no_priority_all else ''}
                    {'' if (very_high_all or high_all or medium_all or low_all or other_priority_all or no_priority_all) else '<div class="section"><div class="section-title">All Items</div><ul class="item-list"><li class="empty">No items</li></ul></div>'}
                </div>
                
                <div class="status-tab-content" data-status="updates_24h" data-vendor="{vendor_name}">
                    {generate_24h_updates_section(updates_24h, vendor_name)}
                </div>
                
                <div class="status-tab-content" data-status="oldest_unaddressed" data-vendor="{vendor_name}">
                    {generate_oldest_unaddressed_section(oldest_unaddressed)}
                </div>
                
                <div class="status-tab-content" data-status="closed" data-vendor="{vendor_name}">
                    <div class="section">
                        <div class="section-title">Closed Items ({len(closed_items)})</div>
                        <ul class="item-list">
                            {''.join([generate_item_html(item) for item in closed_items]) if closed_items else '<li class="empty">No closed items</li>'}
                        </ul>
                    </div>
                </div>
                
                <div class="status-tab-content" data-status="monitor" data-vendor="{vendor_name}">
                    <div class="section">
                        <div class="section-title">Monitor Items ({len(monitor_items)})</div>
                        <ul class="item-list">
                            {''.join([generate_item_html(item) for item in monitor_items]) if monitor_items else '<li class="empty">No monitor items</li>'}
                        </ul>
                    </div>
                </div>
                
                <div class="status-tab-content" data-status="incomplete" data-vendor="{vendor_name}">
                    <div class="section">
                        <div class="section-title">Incomplete Items ({len(incomplete_items)})</div>
                        <ul class="item-list">
                            {''.join([generate_item_html(item) for item in incomplete_items]) if incomplete_items else '<li class="empty">No incomplete items</li>'}
                        </ul>
                    </div>
                </div>
            </div>
        </div>
    """
    
    return html


def generate_24h_updates_section(updates_24h: Dict, vendor_name: str = '') -> str:
    """Generate HTML for yesterday's updates section with sub-tabs."""
    added = updates_24h.get('added', [])
    closed = updates_24h.get('closed', [])
    changed_to_monitor = updates_24h.get('changed_to_monitor', [])
    
    total_updates = len(added) + len(closed) + len(changed_to_monitor)
    
    if total_updates == 0:
        return """
                        <div class="section">
                            <div class="section-title">Yesterday's Updates</div>
                            <ul class="item-list">
                                <li class="empty">No updates from yesterday</li>
                            </ul>
                        </div>
                """
    
    # Generate unique ID for this vendor's update tabs
    vendor_name_safe = vendor_name.replace('/', '_').replace(' ', '_').replace('(', '').replace(')', '')
    
    html = f"""
                        <div class="section">
                            <div class="section-title">Yesterday's Updates ({total_updates})</div>
                            <div class="updates-sub-tabs" style="margin-bottom: 20px;">
                                <button class="status-tab {'active' if added or (not added and not closed and not changed_to_monitor) else ''}" onclick="switchUpdateTab(this, '{vendor_name_safe}')" data-update-type="added">Added ({len(added)})</button>
                                <button class="status-tab {'active' if not added and closed else ''}" onclick="switchUpdateTab(this, '{vendor_name_safe}')" data-update-type="closed">Closed ({len(closed)})</button>
                                <button class="status-tab {'active' if not added and not closed and changed_to_monitor else ''}" onclick="switchUpdateTab(this, '{vendor_name_safe}')" data-update-type="monitor">Changed to Monitor ({len(changed_to_monitor)})</button>
                            </div>
                            
                            <div class="update-tab-content {'active' if added or (not added and not closed and not changed_to_monitor) else ''}" data-update-type="added" data-vendor-update="{vendor_name_safe}">
                                <div class="section">
                                    <div class="section-title">Items Added Yesterday ({len(added)})</div>
                                    <ul class="item-list">
                                        {''.join([generate_item_html(item) for item in added]) if added else '<li class="empty">No items added yesterday</li>'}
                                    </ul>
                                </div>
                            </div>
                            
                            <div class="update-tab-content" data-update-type="closed" data-vendor-update="{vendor_name_safe}">
                                <div class="section">
                                    <div class="section-title">Items Closed Yesterday ({len(closed)})</div>
                                    <ul class="item-list">
                                        {''.join([generate_item_html(item) for item in closed]) if closed else '<li class="empty">No items closed yesterday</li>'}
                                    </ul>
                                </div>
                            </div>
                            
                            <div class="update-tab-content" data-update-type="monitor" data-vendor-update="{vendor_name_safe}">
                                <div class="section">
                                    <div class="section-title">Items Changed to Monitor Yesterday ({len(changed_to_monitor)})</div>
                                    <ul class="item-list">
                                        {''.join([generate_item_html(item) for item in changed_to_monitor]) if changed_to_monitor else '<li class="empty">No items changed to monitor yesterday</li>'}
                                    </ul>
                                </div>
                            </div>
                        </div>
            """
    
    return html


def generate_oldest_unaddressed_section(items: List[Dict]) -> str:
    """Generate HTML for oldest unaddressed items section."""
    if not items:
        return """
                <div class="section">
                    <div class="section-title">Oldest 3 Unaddressed Items</div>
                    <ul class="item-list">
                        <li class="empty">No unaddressed items</li>
                    </ul>
                </div>
        """
    
    html = f"""
                <div class="section">
                    <div class="section-title">Oldest 3 Unaddressed Items ({len(items)})</div>
                    <ul class="item-list">
    """
    
    for item in items:
        html += generate_item_html(item, show_age=True)
    
    html += """
                    </ul>
                </div>
    """
    
    return html


def generate_priority_items_section(title: str, items: List[Dict]) -> str:
    """Generate HTML for priority items section."""
    if not items:
        return ""
    
    html = f"""
                <div class="section">
                    <div class="section-title">{title} ({len(items)} items)</div>
                    <ul class="item-list">
    """
    
    for item in items:
        html += generate_item_html(item)
    
    html += """
                    </ul>
                </div>
    """
    
    return html


def generate_item_html(item: Dict, show_age: bool = False) -> str:
    """Generate HTML for a single item."""
    name = item.get('punchlist_name', 'Unknown')
    description = item.get('description', '')
    priority = item.get('priority', '')
    status = item.get('status', 'Unknown')
    date_identified = item.get('date_identified', '')
    date_completed = item.get('date_completed', '')
    status_updates = item.get('status_updates', '')
    issue_image = item.get('issue_image', '')
    age_days = item.get('age_days')
    
    status_class = get_status_badge_class(status)
    priority_class = get_priority_badge_class(priority)
    
    html = f"""
                        <li>
                            <div class="item-header">
                                <div class="item-name">{name}</div>
                                <div class="badges">
                                    <span class="badge {status_class}">{status}</span>
                                    {f'<span class="badge {priority_class}">{priority}</span>' if priority else ''}
                                    {f'<span class="age-days">{age_days} days</span>' if show_age and age_days is not None else ''}
                                </div>
                            </div>
                            <div class="item-details">
                                {f'<p class="item-description"><strong>Description:</strong> {description}</p>' if description else ''}
                                {f'<p><strong>Date Identified:</strong> {format_date(date_identified)}</p>' if date_identified else ''}
                                {f'<p><strong>Date Completed:</strong> {format_date(date_completed)}</p>' if date_completed else ''}
                                {f'<p><strong>Status Updates:</strong> {status_updates}</p>' if status_updates else ''}
                                {f'<p><strong>Image:</strong> {issue_image}</p>' if issue_image else ''}
                            </div>
                        </li>
    """
    
    return html


if __name__ == "__main__":
    import argparse
    
    parser = argparse.ArgumentParser(description="Generate HTML report from JSON")
    parser.add_argument(
        "--json",
        type=str,
        required=True,
        help="Path to JSON report file"
    )
    parser.add_argument(
        "--output",
        type=str,
        default=None,
        help="Output HTML file path (defaults to same location as JSON with .html extension)"
    )
    
    args = parser.parse_args()
    
    output_path = generate_html_report(args.json, args.output)
    print(f"✓ HTML report generated: {output_path}")
