<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    {% if domain %}<meta name="fs-domain" content="{{ domain }}">{% endif %}
    <title>Scan Quality Report - Finite State Report</title>
    <script src="https://cdn.jsdelivr.net/npm/chart.js@4.4.1/dist/chart.umd.min.js"></script>
    <script src="https://cdn.jsdelivr.net/npm/chartjs-plugin-datalabels@2"></script>

    <style>
        * { margin: 0; padding: 0; box-sizing: border-box; }
        body {
            font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Oxygen, Ubuntu, Cantarell, sans-serif;
            line-height: 1.6; color: #333; background-color: #f8f9fa;
        }
        .container { margin: 0 auto; padding: 20px; background-color: white; border: 1px solid #dee2e6; min-height: 100%; }

        /* Header */
        .header { text-align: center; margin-bottom: 30px; padding-bottom: 20px; border-bottom: 2px solid #e9ecef; }
        .logo-container { margin-bottom: 20px; }
        .company-logo { max-height: 50px; width: auto; margin: 0 auto; display: block; }
        .header h1 { color: #2c3e50; font-size: 2.5em; margin-bottom: 10px; }
        .header .subtitle { color: #6c757d; font-size: 1.1em; }

        /* Metadata bar */
        .metadata { background-color: #f8f9fa; padding: 15px; border-radius: 8px; margin-bottom: 30px; font-size: 0.9em; color: #6c757d; }

        /* KPI Cards */
        .kpi-row { display: grid; grid-template-columns: repeat(auto-fit, minmax(160px, 1fr)); gap: 15px; margin-bottom: 30px; }
        .kpi-card {
            background: white; border: 1px solid #dee2e6; border-radius: 8px;
            padding: 20px; text-align: center;
        }
        .kpi-card .kpi-title { font-size: 0.85em; color: #6c757d; text-transform: uppercase; letter-spacing: 0.5px; margin-bottom: 8px; }
        .kpi-card .kpi-value { font-size: 2.2em; font-weight: 700; color: #2c3e50; line-height: 1; }
        .kpi-card .kpi-sub { font-size: 0.8em; color: #6c757d; margin-top: 4px; }

        /* Two-column layout */
        .two-col { display: grid; grid-template-columns: 1fr 1fr; gap: 20px; margin-bottom: 30px; }
        @media (max-width: 900px) { .two-col { grid-template-columns: 1fr; } }

        /* Charts */
        .chart-container { background-color: white; border-radius: 8px; padding: 20px; margin-bottom: 30px; border: 1px solid #dee2e6; }
        .chart-wrapper { position: relative; height: 350px; margin: 20px 0; }
        .chart-title { color: #2c3e50; font-size: 1.5em; margin-bottom: 10px; }
        .chart-description { color: #6c757d; font-size: 0.95em; margin-bottom: 20px; }

        /* Tables */
        .table-container { background-color: white; border-radius: 8px; padding: 20px; margin-bottom: 30px; border: 1px solid #dee2e6; overflow-x: auto; }
        .table-container h2 { color: #2c3e50; font-size: 1.5em; margin-bottom: 10px; }
        .table-description { color: #6c757d; font-size: 0.95em; margin-bottom: 15px; }
        table { width: 100%; border-collapse: collapse; margin-top: 15px; }
        th, td { padding: 10px 12px; text-align: left; border-bottom: 1px solid #dee2e6; }
        th { background-color: #f8f9fa; font-weight: 600; color: #495057; position: sticky; top: 0; z-index: 10; cursor: pointer; white-space: nowrap; }
        th:hover { background-color: #e9ecef; }
        tr:hover { background-color: #f8f9fa; }
        td.num { text-align: right; font-variant-numeric: tabular-nums; }
        td.center, th.center { text-align: center; }
        .auto-w { width: 1%; white-space: nowrap; }

        /* Staleness badges */
        .staleness-fresh   { display: inline-block; padding: 2px 8px; border-radius: 4px; font-size: 0.8em; font-weight: 600; background-color: #d4edda; color: #155724; }
        .staleness-aging   { display: inline-block; padding: 2px 8px; border-radius: 4px; font-size: 0.8em; font-weight: 600; background-color: #fff3cd; color: #856404; }
        .staleness-stale   { display: inline-block; padding: 2px 8px; border-radius: 4px; font-size: 0.8em; font-weight: 600; background-color: #ffe0b2; color: #6d3300; }
        .staleness-dormant { display: inline-block; padding: 2px 8px; border-radius: 4px; font-size: 0.8em; font-weight: 600; background-color: #f8d7da; color: #721c24; }

        /* Coverage score */
        .score-good { color: #22c55e; font-weight: 600; }
        .score-mid  { color: #f59e0b; font-weight: 600; }
        .score-low  { color: #ef4444; font-weight: 600; }

        /* Reachability */
        .reach-yes { color: #22c55e; font-weight: 600; }
        .reach-no  { color: #ef4444; font-weight: 600; }
        .reach-na  { color: #9ca3af; }

        /* Unpack rating */
        .unpack-excellent { display: inline-block; padding: 2px 8px; border-radius: 4px; font-size: 0.8em; font-weight: 600; background-color: #d4edda; color: #155724; }
        .unpack-good      { display: inline-block; padding: 2px 8px; border-radius: 4px; font-size: 0.8em; font-weight: 600; background-color: #cfe2ff; color: #084298; }
        .unpack-fair      { display: inline-block; padding: 2px 8px; border-radius: 4px; font-size: 0.8em; font-weight: 600; background-color: #fff3cd; color: #856404; }
        .unpack-poor      { display: inline-block; padding: 2px 8px; border-radius: 4px; font-size: 0.8em; font-weight: 600; background-color: #f8d7da; color: #721c24; }

        /* Misc */
        .no-data { text-align: center; color: #6c757d; font-style: italic; padding: 40px; }
        .tooltip-cell { position: relative; }
        .tooltip-cell .unpack-summary { display: none; position: absolute; left: 0; top: 100%; z-index: 100; background: #fff; border: 1px solid #dee2e6; border-radius: 6px; padding: 8px 12px; font-size: 0.85em; white-space: nowrap; box-shadow: 0 2px 8px rgba(0,0,0,0.12); }
        .tooltip-cell:hover .unpack-summary { display: block; }

        /* Footer */
        .footer { text-align: center; margin-top: 40px; padding-top: 20px; border-top: 1px solid #e9ecef; color: #6c757d; font-size: 0.9em; }
        .finite-state-logo { color: #007bff; font-weight: bold; }

        @media print {
            body { background-color: white; }
            .container { max-width: none; }
        }
    </style>
</head>
<body>
    <span id="fsConnectionBadge"></span>
    <div class="container">

        <!-- Header -->
        <div class="header">
            {% if logo_path %}
            <div class="logo-container">
                <img src="{{ logo_path }}" alt="Company Logo" class="company-logo">
            </div>
            {% else %}
            <div class="logo-container">
                <img src="data:image/webp;base64,UklGRogLAABXRUJQVlA4WAoAAAAQAAAA/wAAMAAAQUxQSJsHAAAB8EZt/zql/v9dNDjCYPdgd7cLRnfZsdgg2N0KdmF3d7did3d3dxe1ckut7YzCmNeNeb6e8xzeMe+4ExETgP/zzTe0okPn0ieRlhm5HLcm95m+4CUTejk7ZpUOkKuLQjfWxDt/OGD5Fv7gqVqAE5BsHbmvgoPlNiiFzwOBXFVRvARQ5yy/z8vrSLV6wvShHkBw7CKEmIZ7AEEv+dcAV0ep+jFyaUGg5mlyLgLJ520Az+EZfNTcISq0nDxaDSiwjLwneJbFY1WBwivII1UdHs9hGXzUAnALS+WjX+twHgIZXvIouSgfUOM4uaSAY9PmBT8MdAOaPWJauBtqcRECOQJo9Ywf+rsArZ8wdbC7A6NL4oJ8QIX95PKCADpxuQgeQzN4vzHgHpbBev9WOLn9c8mZ/ADIPesbT9cE4LeJDEMrAVB4Fbm3HLCQDf71VNqxTXNPT8HY3dt2VBR4nWmhVWLrtl1TRXV2bdsdLojYtU12T6hV8J5tmrsDFNyH01W+CQagizDzZiOgJUfArX9RALXPMaUwFrG+GvfQyOt3zyxs6i5qvWiu7MKeMoWnOMnUXjRXdv5oN0GnRXM15xUXNaHkZsE1ko1F8T87adQh+dRJEEryqOAG5RdazaZkLyVuUUm5AYS+ZXwPQOT8Kj3cHcAJllFW5g7FN30FKyl/SWYc/WX6UD7RS3CYkkbRHzIbBOdJ/i56T44Q1fpJ3hMFk9wvuGLDPKtpMt3VvHvnipJn+XWmL9C1s+gh+aQVsIXlVPm+pOYLN8ESG85I6OO4X6anDdGiPTL+Mpb4hISEhPS5SjjfHntTExLiP5HMiE9ISI/Q+hifkJCQkBZik0+KVZQ7evNsGaDOGc4UuLz4sPInj5ZZx4qqhpH8ejry9jcuhHDOd7PZZCH51WQ2fz0oEUZ+qyHR+ZvZbMok+d1kNmc9lckymc1m86f6Mhd1Pnq93tdLDbe5q9Pp9Xr3SJJh7nq9r6fWDDe9Xq/3dbctVaMHO6DIapLT0ZJj4PLqPaoc5ZekH1WwmHVVHCI5CkD13X+IcvkZDPnGk4zMZzD45dPyek1yi4TOz2AoEELyVpFiBkNhJ4kB+Q3WHjJnIG0bz+ZSJlxHsge0rSKgWKI7wwf8zeuTOAMtORaub/4qCLR6QlbHYtZWcYxkGKydRMJ+JJdBvjtJZpbXEgaQvAhZqz8hb3XaTnzoh7pUt55kLxsW5DMYDH75Fb1/747O/MTkvqitgTNM6O0Mt8FJ9VRNJfl5YgHYOpDkCjnXR1ZcYUMjkpds6urq7e3t7Sn1NKR9+/ad66ljbJXcidnpi8lsNn89qsYjRmCZlweoKxgBeI818V4ToHBuVX6pJJm2qoK92pJZd8iPfvZLjY2Li0uZIyXepibzKUlmNPJ7k43E5+3Q8WQlAIZdXIDmfNQAQLE15IFKgCr8lkLrrAl2ukFerfGVnGM/8UYFm9WYKkWS5Jdg3wcvstkVO+gA6Cd95u3ayLuN3OgHoPZpfpvroQyG9R9pPd8uzUn2xGkypWA2iZT6YbFYLFyrJtOABbQOyznRPbscaN+tW7eejVXcEwEuPeMY280ZABrd5KcIHYDAZJZUBxSbkEryRzV7nCNjcyKY5AS77RwZERExsbnUjVJly5UrX1DN55LACCvOgTgbjIFin9RbGk3u0jzBB0BdT8CpezzfhToDO3+WsAdQOorkIDs0JJlyabzLGzI+l73aQN7qDKRVoIOFJFf80wgl1xoA1DzJ+40B+M60MALYzdJYpub3X62wnmSEHQ7T2uQ7muQQewUqOGs3/JZG8rFTdtkf2qVLly7dS6kLZxiAoqvJ2z+5rwKAFlxuVQYr1Bzn4Y4VizSOJ9lBXe0fAo7K95F8p7PT9IaNrX2zFaq8I+9lG82e6gaxLVxHpfN+U9Q6S8ssT1TnUnsUTCX51USSqQXUbSc5tOEfTWpgC8ledtIMkDmnLIrMFKHIbWUb1HVT4pUkCEZpMgzWgR9ZHbW4EtijrAUl+0BZJQv5BEJ/kk/ds4W/zHm5CzLRZFYpEbxPv5Q5ILPRhuky3ZW4XIrzwCAGoVAiLzYCUHozLeVRjauAHYJaCnL0uvtdkNAN0uEk12ptITlYhBsku2n9SvKG1EEZo8g3wN9YSa6S0T9AL3CuFeDfwFMDOUKcBXmM/sbyMqWN/sYCEgajv6Yxv0361DuAro1VK8BvA7m92kQLL9QFynENsE1QQwHgVK3vglWzQnJDvmRIUGh1DZdmbYODfDQqhgaF1tXKGxwU0lCqbkiQZnAe0b9Q77+4ohAAjOBBA4D6F0lGtQegm8MtorWsrMRhbPqQGcM8gco3+GlCTgAdH0/zBtAxinEtgS0sg8EdnRwZuA34wBeBgFP3OEZ1BOAMIOAKLdP0QEAUy8LxzbvgB0/VAvRTs3glAEDJSHJbaaDkVnJDDgcIqHSAXF0EKLWN3FxlQhavGQGfyVm8GgBHucl9/j3SCzBeIxndGUCXWMZ0ggPt0jeZr4MBdH0yxRswXmPmJG841nnmfOPZuoALUGorGVkCjnf5veS6YvCZksUrAXDM/7jDjMXvGN0JDrtzrwR+nugNRz5veFn8vy8AVlA4IMYDAAAQGgCdASoAATEAPkkgjUUioiESyu5UKASEsQQ4BkBmgLwBnkth/5WF+V/YBdQxT/QOuI4n3f8p+g27T8McrbSnnPdAf8D+ifkz2zPzT7AH6f9LvzAfx7/F+qf/mP1d9xnoAf3P0a/9V7GX7h+wx5c/7gfBZ+6H7pe0z//9aUQkk833U3/010TMZyNMJOh7BVPMaj385fqmxA57PseAo3OPAykt9bpJCWjkQopiYBocscHNNUKYIfiMw7n03MLowQrd4fwQ/M41Oz7l12lGBmcFpssA3NB7Dl8QAP7neK3fUwYp5YF+1PcER/+ufcR8oQYI6yXqgZ+T/3zLtzRKtMovH89ZN9GXVqgzBcNHzJeYGOpIi7+2dnE17hzWGcltXA9cOe//TdQCvR4RL1iBIHjF8qNyV2wnQ6OCx+IX++c1e1TBr9EkT2PvApXIL9ciPLLrFBk5WVBOd786zot/vI636pgA4rWfrPPePmbxeee2YaoxxnLiKfOVoIveCdjHuba3z/T9RSrbgBChtZy3o6VRTL9gYHas6vJL1DckHBPdUqpt/6hucimiN+4TAUeGk6Co18dNdz41fb9Xhwe7JVcG4CZ5vuyXOq1hCOX77L3meHa5gQp+8Kh1gBsRC3cHuTsPn4J4Rc/kZ+n/2vThrh//Ydy/oDH6aBMPjhx5xExdz3bIvdTdLp6nCZ278QP+HUSxdmcv3yJD1J86O2WsoYU2KhLU/t35z6VQNZMM2NkWnCAdNyW47zng1wQZYQLHY+5daCiFuhQ/xM3oVPdwEgxgAQk6owVnSSkMxe11YGvOfg/yAgwbUfvX+ggiHIbLrjZgVq+grhS9U3M3HtmKFz/kgwKRM7n8kk8LRYGK/9MYvArjTeoBsBiLk2I6tNAOI1BicVGLb008DuWG9RV0oqasjqcyxMuTd7CCLkWzXD//BS6oW/94CEbS3Pg7qi7eJwCT93iHAPhPuHcWx1dF7z+RLcx6bRqlnrqqinGaW5oYozyKstInug4w3eu9ypoHaLLwJb5D3/iADFjNPd10L2dbh9CFGP+rEjdupInLy2nUngp3wP/Z7iSiaO+SV6MF1J2ZAPsxJtXUFwVlgHcmwyqujWazTJ367dp6zib3FnY/7dHbxbZXzHEV37AnCuCiruTi/zm/9g8tnTfblrGDrDGRAl8ThBs5HWPgY8x0bDxP35ITV6015+SLai8QkDVLevEnQPXMgZadvkfPYUY22Bz1HFZj3iNRhFfL05MpXr1IKdBy07hvaFxL1IAAAAAAAAAAAAAAAAA="
                     alt="Finite State Logo" class="company-logo">
            </div>
            {% endif %}
            <h1>Scan Quality Report</h1>
            <div class="subtitle">
                {{ scope_label | default('All Projects') }} &mdash; Scan Coverage &amp; Quality Analysis
            </div>
        </div>

        <!-- Metadata bar -->
        <div class="metadata">
            <strong>Report:</strong> Scan Quality |
            <strong>Generated:</strong> {{ generated_at }} |
            <strong>Scope:</strong> {{ scope_label | default('All Projects') }} |
            <strong>Projects Scanned:</strong> {{ summary.total_projects | default(0) }}
        </div>

        <!-- KPI Cards -->
        <div class="kpi-row">
            <!-- Projects Scanned -->
            <div class="kpi-card">
                <div class="kpi-title">Projects Scanned</div>
                <div class="kpi-value">{{ summary.total_projects | default(0) }}</div>
            </div>

            <!-- Avg Coverage Score -->
            <div class="kpi-card">
                <div class="kpi-title">Avg Coverage Score</div>
                <div class="kpi-value
                    {%- if summary.avg_coverage_score | default(0) >= 3 %} score-good
                    {%- elif summary.avg_coverage_score | default(0) >= 2 %} score-mid
                    {%- else %} score-low{% endif %}">
                    {{ '%.1f' | format(summary.avg_coverage_score | default(0)) }}
                </div>
                <div class="kpi-sub">out of 4</div>
            </div>

            <!-- Reachability Coverage -->
            {% set rc = summary.reachability_coverage | default({'with_reachability': 0, 'binary_projects': 0}) %}
            {% set rc_total = rc.with_reachability + rc.binary_projects %}
            <div class="kpi-card">
                <div class="kpi-title">Reachability Coverage</div>
                <div class="kpi-value">{{ rc.with_reachability }} <span style="font-size:0.5em;color:#6c757d;">of {{ rc_total }}</span></div>
                <div class="kpi-sub">binary projects with reachability</div>
            </div>

            <!-- Stale Projects -->
            <div class="kpi-card">
                <div class="kpi-title">Stale Projects</div>
                <div class="kpi-value {% if summary.stale_project_count | default(0) > 0 %}score-low{% endif %}">
                    {{ summary.stale_project_count | default(0) }}
                </div>
                <div class="kpi-sub">no scan in 90+ days</div>
            </div>

            <!-- Unpack Issues (only if unpack data exists) -->
            {% set unpack_issue_count = namespace(val=0) %}
            {% if summary_table %}
                {% for row in summary_table %}
                    {% if row.unpack_rating is defined and row.unpack_rating in ('Fair', 'Poor') %}
                        {% set unpack_issue_count.val = unpack_issue_count.val + 1 %}
                    {% endif %}
                {% endfor %}
            {% endif %}
            {% if charts and charts.unpack_rating_distribution is defined %}
            <div class="kpi-card">
                <div class="kpi-title">Unpack Issues</div>
                <div class="kpi-value {% if unpack_issue_count.val > 0 %}score-low{% endif %}">
                    {{ unpack_issue_count.val }}
                </div>
                <div class="kpi-sub">Fair or Poor rating</div>
            </div>
            {% endif %}
        </div>

        <!-- Staleness Legend -->
        {% if thresholds %}
        <div class="metadata" style="margin-top: 15px;">
            <strong>Staleness Legend:</strong>
            <span class="staleness-fresh">FRESH</span> = scanned within {{ thresholds.fresh }} days |
            <span class="staleness-aging">AGING</span> = {{ thresholds.fresh + 1 }}&ndash;{{ thresholds.aging }} days |
            <span class="staleness-stale">STALE</span> = {{ thresholds.aging + 1 }}&ndash;{{ thresholds.stale }} days |
            <span class="staleness-dormant">DORMANT</span> = over {{ thresholds.stale }} days
        </div>
        {% endif %}

        <!-- Charts -->
        {% if charts %}
        <div class="two-col">
            {% if charts.staleness_distribution and charts.staleness_distribution.labels | default([]) | length > 0 %}
            <div class="chart-container">
                <h2 class="chart-title">Staleness Distribution</h2>
                <p class="chart-description">Project staleness based on days since last scan.</p>
                <div class="chart-wrapper">
                    <canvas id="stalenessChart"></canvas>
                </div>
            </div>
            {% endif %}

            {% if charts.scan_type_coverage and charts.scan_type_coverage.labels | default([]) | length > 0 %}
            <div class="chart-container">
                <h2 class="chart-title">Scan Type Coverage</h2>
                <p class="chart-description">Number of projects with each scan type present in their latest version.</p>
                <div class="chart-wrapper">
                    <canvas id="scanTypeCoverageChart"></canvas>
                </div>
            </div>
            {% endif %}
        </div>

        {% if charts.unpack_rating_distribution is defined and charts.unpack_rating_distribution.labels | default([]) | length > 0 %}
        <div class="chart-container">
            <h2 class="chart-title">Unpack Rating Distribution</h2>
            <p class="chart-description">Distribution of firmware unpack quality ratings across evaluated versions.</p>
            <div class="chart-wrapper" style="max-width: 600px; margin: 20px auto;">
                <canvas id="unpackRatingChart"></canvas>
            </div>
        </div>
        {% endif %}
        {% endif %}

        <!-- Summary Table -->
        <div class="table-container">
            <h2>Project Summary</h2>
            <p class="table-description">One row per project, showing the latest version's scan coverage and quality indicators.</p>
            {% if summary_table and summary_table | length > 0 %}
            <table id="summaryTable">
                <thead>
                    <tr>
                        {% set ns = namespace(has_unpack=false) %}
                        {% for row in summary_table %}
                            {% if row.unpack_rating is defined and row.unpack_rating %}
                                {% set ns.has_unpack = true %}
                            {% endif %}
                        {% endfor %}
                        <th onclick="sortTable('summaryTable', 0)">Project</th>
                        <th onclick="sortTable('summaryTable', 1)">Folder</th>
                        <th onclick="sortTable('summaryTable', 2)" class="center auto-w">Versions</th>
                        <th onclick="sortTable('summaryTable', 3)">Latest Version</th>
                        <th onclick="sortTable('summaryTable', 4)">Last Scan</th>
                        {% if ns.has_unpack %}
                        <th onclick="sortTable('summaryTable', 5)">Unpack Rating</th>
                        {% endif %}
                        <th onclick="sortTable('summaryTable', {{ 5 + (1 if ns.has_unpack else 0) }})">Staleness</th>
                        <th onclick="sortTable('summaryTable', {{ 6 + (1 if ns.has_unpack else 0) }})" class="center auto-w">Coverage</th>
                        <th onclick="sortTable('summaryTable', {{ 7 + (1 if ns.has_unpack else 0) }})" class="center">Reachability</th>
                        <th onclick="sortTable('summaryTable', {{ 8 + (1 if ns.has_unpack else 0) }})" class="num">Critical</th>
                        <th onclick="sortTable('summaryTable', {{ 9 + (1 if ns.has_unpack else 0) }})" class="num">High</th>
                        <th onclick="sortTable('summaryTable', {{ 10 + (1 if ns.has_unpack else 0) }})" class="num">Total</th>
                    </tr>
                </thead>
                <tbody>
                    {% for row in summary_table %}
                    {% set staleness_lc = (row.staleness | default('') | lower) %}
                    <tr>
                        <td>{{ row.project_name | default('') }}</td>
                        <td>{{ row.folder_name | default('') }}</td>
                        <td class="center auto-w">{{ row.version_count | default(0) }}</td>
                        <td>{{ row.latest_version | default('') }}</td>
                        <td>{{ row.last_scan_date | default('') }}</td>
                        {% if ns.has_unpack %}
                        <td class="tooltip-cell">
                            {% set ur = row.unpack_rating | default('') %}
                            {% if ur == 'Excellent' %}<span class="unpack-excellent">Excellent</span>
                            {% elif ur == 'Good' %}<span class="unpack-good">Good</span>
                            {% elif ur == 'Fair' %}<span class="unpack-fair">Fair</span>
                            {% elif ur == 'Poor' %}<span class="unpack-poor">Poor</span>
                            {% else %}<span style="color:#9ca3af;">&mdash;</span>{% endif %}
                            {% if row.unpack_short_summary is defined and row.unpack_short_summary %}
                            <div class="unpack-summary">{{ row.unpack_short_summary }}</div>
                            {% endif %}
                        </td>
                        {% endif %}
                        <td>
                            {% if staleness_lc %}
                            <span class="staleness-{{ staleness_lc }}">{{ row.staleness }}</span>
                            {% else %}&mdash;{% endif %}
                        </td>
                        <td class="center auto-w">
                            {% set cs = row.coverage_score | default(0) %}
                            <span class="{% if cs >= 4 %}score-good{% elif cs >= 3 %}score-mid{% else %}score-low{% endif %}">
                                {{ cs }}
                            </span>
                        </td>
                        <td class="center">
                            {% set reach = row.has_reachability | default('') %}
                            {% if reach == 'Yes' %}<span class="reach-yes">Yes</span>
                            {% elif reach == 'No' %}<span class="reach-no">No</span>
                            {% else %}<span class="reach-na">N/A</span>{% endif %}
                        </td>
                        <td class="num">{{ row.critical_findings | default(0) }}</td>
                        <td class="num">{{ row.high_findings | default(0) }}</td>
                        <td class="num">{{ row.total_findings | default(0) }}</td>
                    </tr>
                    {% endfor %}
                </tbody>
            </table>
            {% else %}
            <div class="no-data">No project data available.</div>
            {% endif %}
        </div>

        <!-- Detail Table -->
        <div class="table-container">
            <h2>Version Detail</h2>
            <p class="table-description">One row per project-version. Hover over Unpack Rating to see the short summary.</p>
            {% if detail_table and detail_table | length > 0 %}
            {% set dns = namespace(has_unpack=false) %}
            {% for row in detail_table %}
                {% if row.unpack_rating is defined and row.unpack_rating %}
                    {% set dns.has_unpack = true %}
                {% endif %}
            {% endfor %}
            <table id="detailTable">
                <thead>
                    <tr>
                        <th onclick="sortTable('detailTable', 0)">Project</th>
                        <th onclick="sortTable('detailTable', 1)">Folder</th>
                        <th onclick="sortTable('detailTable', 2)">Version</th>
                        <th onclick="sortTable('detailTable', 3)" class="center auto-w">Scans</th>
                        <th onclick="sortTable('detailTable', 4)">Last Scan</th>
                        {% if dns.has_unpack %}
                        <th onclick="sortTable('detailTable', 5)">Unpack Rating</th>
                        {% endif %}
                        <th onclick="sortTable('detailTable', {{ 5 + (1 if dns.has_unpack else 0) }})">Staleness</th>
                        <th onclick="sortTable('detailTable', {{ 6 + (1 if dns.has_unpack else 0) }})" class="center auto-w">Coverage</th>
                        <th onclick="sortTable('detailTable', {{ 7 + (1 if dns.has_unpack else 0) }})" class="center">Reachability</th>
                        <th onclick="sortTable('detailTable', {{ 8 + (1 if dns.has_unpack else 0) }})" class="num">Critical</th>
                        <th onclick="sortTable('detailTable', {{ 9 + (1 if dns.has_unpack else 0) }})" class="num">High</th>
                        <th onclick="sortTable('detailTable', {{ 10 + (1 if dns.has_unpack else 0) }})" class="num">Total</th>
                    </tr>
                </thead>
                <tbody>
                    {% for row in detail_table %}
                    {% set staleness_lc = (row.staleness | default('') | lower) %}
                    <tr>
                        <td>{{ row.project_name | default('') }}</td>
                        <td>{{ row.folder_name | default('') }}</td>
                        <td>{{ row.version_name | default('') }}</td>
                        <td class="center auto-w">{{ row.scan_count | default(0) }}</td>
                        <td>{{ row.last_scan_date | default('') }}</td>
                        {% if dns.has_unpack %}
                        <td class="tooltip-cell">
                            {% set ur = row.unpack_rating | default('') %}
                            {% if ur == 'Excellent' %}<span class="unpack-excellent">Excellent</span>
                            {% elif ur == 'Good' %}<span class="unpack-good">Good</span>
                            {% elif ur == 'Fair' %}<span class="unpack-fair">Fair</span>
                            {% elif ur == 'Poor' %}<span class="unpack-poor">Poor</span>
                            {% else %}<span style="color:#9ca3af;">&mdash;</span>{% endif %}
                            {% if row.unpack_short_summary is defined and row.unpack_short_summary %}
                            <div class="unpack-summary">{{ row.unpack_short_summary }}</div>
                            {% endif %}
                        </td>
                        {% endif %}
                        <td>
                            {% if staleness_lc %}
                            <span class="staleness-{{ staleness_lc }}">{{ row.staleness }}</span>
                            {% else %}&mdash;{% endif %}
                        </td>
                        <td class="center auto-w">
                            {% set cs = row.coverage_score | default(0) %}
                            <span class="{% if cs >= 4 %}score-good{% elif cs >= 3 %}score-mid{% else %}score-low{% endif %}">
                                {{ cs }}
                            </span>
                        </td>
                        <td class="center">
                            {% set reach = row.has_reachability | default('') %}
                            {% if reach == 'Yes' %}<span class="reach-yes">Yes</span>
                            {% elif reach == 'No' %}<span class="reach-no">No</span>
                            {% else %}<span class="reach-na">N/A</span>{% endif %}
                        </td>
                        <td class="num">{{ row.critical_findings | default(0) }}</td>
                        <td class="num">{{ row.high_findings | default(0) }}</td>
                        <td class="num">{{ row.total_findings | default(0) }}</td>
                    </tr>
                    {% endfor %}
                </tbody>
            </table>
            {% else %}
            <div class="no-data">No version detail data available.</div>
            {% endif %}
        </div>

        <!-- Footer -->
        <div class="footer">
            <p>Generated by <span class="finite-state-logo">Finite State</span> | {{ generated_at }}</p>
            <p style="font-size: 0.8em; margin-top: 4px;">Copyright &copy; 2026 Finite State, Inc.</p>
        </div>
    </div>

    <script>
    // Table sort helper
    function sortTable(tableId, colIdx) {
        var table = document.getElementById(tableId);
        if (!table) return;
        var tbody = table.querySelector('tbody');
        var rows = Array.from(tbody.querySelectorAll('tr'));
        var asc = table.dataset.sortCol === String(colIdx) && table.dataset.sortDir !== 'asc';
        table.dataset.sortCol = colIdx;
        table.dataset.sortDir = asc ? 'asc' : 'desc';
        rows.sort(function(a, b) {
            var av = a.cells[colIdx] ? a.cells[colIdx].innerText.trim() : '';
            var bv = b.cells[colIdx] ? b.cells[colIdx].innerText.trim() : '';
            var an = parseFloat(av.replace(/[^0-9.\-]/g, ''));
            var bn = parseFloat(bv.replace(/[^0-9.\-]/g, ''));
            if (!isNaN(an) && !isNaN(bn)) return asc ? an - bn : bn - an;
            return asc ? av.localeCompare(bv) : bv.localeCompare(av);
        });
        rows.forEach(function(r) { tbody.appendChild(r); });
    }

    document.addEventListener('DOMContentLoaded', function() {
        Chart.register(ChartDataLabels);

        // ---- Staleness Doughnut Chart ----
        {% if charts and charts.staleness_distribution and charts.staleness_distribution.labels | default([]) | length > 0 %}
        (function() {
            var ctx = document.getElementById('stalenessChart');
            if (!ctx) return;
            var data = {{ charts.staleness_distribution | tojson }};
            if (!data.labels || data.labels.length === 0) return;

            var colorMap = {
                'FRESH':   '#22c55e',
                'AGING':   '#f59e0b',
                'STALE':   '#f97316',
                'DORMANT': '#ef4444'
            };
            var bgColors = data.labels.map(function(l) { return colorMap[l] || '#9ca3af'; });

            new Chart(ctx.getContext('2d'), {
                type: 'doughnut',
                data: {
                    labels: data.labels,
                    datasets: [{
                        data: data.values,
                        backgroundColor: bgColors,
                        borderWidth: 2,
                        borderColor: '#fff'
                    }]
                },
                options: {
                    responsive: true,
                    maintainAspectRatio: false,
                    plugins: {
                        legend: { position: 'bottom' },
                        datalabels: {
                            color: '#fff',
                            font: { weight: 'bold', size: 13 },
                            formatter: function(value, ctx) {
                                if (value === 0) return '';
                                var total = ctx.dataset.data.reduce(function(a, b) { return a + b; }, 0);
                                var pct = ((value / total) * 100).toFixed(1);
                                return value + '\n(' + pct + '%)';
                            }
                        }
                    }
                },
                plugins: [ChartDataLabels]
            });
        })();
        {% endif %}

        // ---- Scan Type Coverage Bar Chart ----
        {% if charts and charts.scan_type_coverage and charts.scan_type_coverage.labels | default([]) | length > 0 %}
        (function() {
            var ctx = document.getElementById('scanTypeCoverageChart');
            if (!ctx) return;
            var data = {{ charts.scan_type_coverage | tojson }};
            if (!data.labels || data.labels.length === 0) return;

            new Chart(ctx.getContext('2d'), {
                type: 'bar',
                data: {
                    labels: data.labels,
                    datasets: [{
                        label: 'Projects',
                        data: data.values,
                        backgroundColor: '#3b82f6',
                        borderColor: '#2563eb',
                        borderWidth: 1,
                        borderRadius: 4
                    }]
                },
                options: {
                    responsive: true,
                    maintainAspectRatio: false,
                    plugins: {
                        legend: { display: false },
                        datalabels: {
                            anchor: 'end',
                            align: 'top',
                            color: '#333',
                            font: { weight: 'bold', size: 12 },
                            formatter: function(value) { return value; }
                        }
                    },
                    scales: {
                        y: {
                            beginAtZero: true,
                            ticks: { stepSize: 1 },
                            title: { display: true, text: 'Number of Projects' }
                        }
                    }
                },
                plugins: [ChartDataLabels]
            });
        })();
        {% endif %}

        // ---- Unpack Rating Bar Chart (conditional) ----
        {% if charts and charts.unpack_rating_distribution is defined and charts.unpack_rating_distribution.labels | default([]) | length > 0 %}
        (function() {
            var ctx = document.getElementById('unpackRatingChart');
            if (!ctx) return;
            var data = {{ charts.unpack_rating_distribution | tojson }};
            if (!data.labels || data.labels.length === 0) return;

            var colorMap = {
                'Excellent': '#22c55e',
                'Good':      '#3b82f6',
                'Fair':      '#f59e0b',
                'Poor':      '#ef4444'
            };
            var bgColors = data.labels.map(function(l) { return colorMap[l] || '#9ca3af'; });

            new Chart(ctx.getContext('2d'), {
                type: 'bar',
                data: {
                    labels: data.labels,
                    datasets: [{
                        label: 'Versions',
                        data: data.values,
                        backgroundColor: bgColors,
                        borderWidth: 1,
                        borderRadius: 4
                    }]
                },
                options: {
                    responsive: true,
                    maintainAspectRatio: false,
                    plugins: {
                        legend: { display: false },
                        datalabels: {
                            anchor: 'end',
                            align: 'top',
                            color: '#333',
                            font: { weight: 'bold', size: 12 },
                            formatter: function(value) { return value; }
                        }
                    },
                    scales: {
                        y: {
                            beginAtZero: true,
                            ticks: { stepSize: 1 },
                            title: { display: true, text: 'Number of Versions' }
                        }
                    }
                },
                plugins: [ChartDataLabels]
            });
        })();
        {% endif %}
    });
    </script>

    {% include '_action_buttons.html' %}
</body>
</html>
