<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>{{.AppName}} — Felhom Hub</title>
    <link rel="stylesheet" href="/style.css?v={{hubVersion}}">
    <script src="/static/chart.min.js"></script>
    {{template "inline_confirm_js"}}
</head>
<body>
    {{template "icon_sprite"}}
    <div class="container">
        <header>
            <h1>Felhom <span>Hub</span></h1>
            <nav class="nav-links">
                <a href="/" class="nav-link">Dashboard</a>
                <a href="/configs" class="nav-link">Customers</a>
                <a href="/apps" class="nav-link active">Apps</a>
                <a href="/hosts" class="nav-link">Hosts</a>
                <a href="/offsite" class="nav-link">Offsite</a>
                <a href="/configuration" class="nav-link">Configuration</a>
            </nav>
        </header>

        <a href="/apps{{if .Period}}?period={{.Period}}{{end}}" class="back-link">&larr; Apps</a>

        <!-- Period selector (carries the customer filter + show-dismissed state) -->
        <div class="period-selector" style="margin-top: 1rem;">
            <a href="?period=24h{{if .CustomerFilter}}&amp;customer={{.CustomerFilter}}{{end}}{{if .ShowDismissed}}&amp;show_dismissed=1{{end}}" class="period-btn{{if eq .Period "24h"}} active{{end}}">24h</a>
            <a href="?period=7d{{if .CustomerFilter}}&amp;customer={{.CustomerFilter}}{{end}}{{if .ShowDismissed}}&amp;show_dismissed=1{{end}}"  class="period-btn{{if or (eq .Period "7d") (eq .Period "")}} active{{end}}">7d</a>
            <a href="?period=30d{{if .CustomerFilter}}&amp;customer={{.CustomerFilter}}{{end}}{{if .ShowDismissed}}&amp;show_dismissed=1{{end}}" class="period-btn{{if eq .Period "30d"}} active{{end}}">30d</a>
        </div>

        {{if eq .Flash "telemetry_reset"}}
        <div class="flash flash-success" style="margin-top: 1rem;">Telemetry data deleted successfully.</div>
        {{end}}
        {{if eq .Flash "issues_dismissed"}}
        <div class="flash flash-success" style="margin-top: 1rem;">Issues dismissed — they stay hidden until a NEW occurrence resurfaces them.</div>
        {{end}}
        {{if eq .Flash "no_issues_selected"}}
        <div class="flash flash-error" style="margin-top: 1rem;">No issues were selected.</div>
        {{end}}

        <!-- Overview card -->
        <section class="card">
            <div style="display: flex; justify-content: space-between; align-items: center; flex-wrap: wrap; gap: 0.5rem;">
                <h2 style="margin: 0;">{{if .Summary}}{{if .Summary.DisplayName}}{{.Summary.DisplayName}}{{else}}{{.AppName}}{{end}}{{else}}{{.AppName}}{{end}}</h2>
                <form method="POST" action="/apps/{{.AppName}}/reset-telemetry{{if .Period}}?period={{.Period}}{{end}}">
                    <input type="hidden" name="_csrf" value="{{.CSRFToken}}">
                    <button type="submit" class="btn btn-sm btn-danger" data-confirm="Delete all telemetry data for {{.AppName}}? This cannot be undone.">Reset Telemetry</button>
                </form>
            </div>
            <div class="info-grid">
                <div class="info-item">
                    <span class="label">App Name</span>
                    <span class="value" style="font-family: var(--font-mono)">{{.AppName}}</span>
                </div>
                {{if .Summary}}
                <div class="info-item">
                    <span class="label">Deployments</span>
                    <span class="value">{{.Summary.DeploymentCount}}</span>
                </div>
                <div class="info-item">
                    <span class="label">Catalog Estimate</span>
                    <span class="value">{{if .Summary.CatalogEstimate}}{{.Summary.CatalogEstimate}}{{else}}—{{end}}</span>
                </div>
                <div class="info-item">
                    <span class="label">Catalog Limit</span>
                    <span class="value">{{if .Summary.CatalogLimit}}{{.Summary.CatalogLimit}}{{else}}—{{end}}</span>
                </div>
                {{if .SuggestedLimit}}
                <div class="info-item">
                    <span class="label">Suggested Limit (P95×1.2)</span>
                    <span class="value" style="color: var(--yellow)">{{.SuggestedLimit}} MB</span>
                </div>
                {{end}}
                <div class="info-item">
                    <span class="label">Avg Memory</span>
                    <span class="value">{{formatFloat .Summary.AvgMemoryMB}} MB</span>
                </div>
                <div class="info-item">
                    <span class="label">P95 Memory</span>
                    <span class="value {{accuracyClass .Summary.P95MemoryMB .Summary.CatalogLimit}}">{{formatFloat .Summary.P95MemoryMB}} MB</span>
                </div>
                <div class="info-item">
                    <span class="label">Avg CPU</span>
                    <span class="value">{{formatFloat .Summary.AvgCPU}}%</span>
                </div>
                {{end}}
            </div>
        </section>

        <!-- Memory trend chart -->
        <section class="card">
            <h2>Memory Trend</h2>
            <div class="chart-container">
                <canvas id="memoryChart"></canvas>
            </div>
            <script>
            (function() {
                var chartData = {{json .ChartData}};
                if (!chartData || !chartData.labels || chartData.labels.length === 0) {
                    document.getElementById('memoryChart').parentElement.innerHTML = '<p class="text-muted">Not enough data for the chart.</p>';
                    return;
                }
                var ctx = document.getElementById('memoryChart').getContext('2d');
                var datasets = [
                    {
                        label: 'Avg Memory (MB)',
                        data: chartData.avg_memory,
                        borderColor: '#2EA8F5',
                        backgroundColor: 'rgba(46,168,245,0.1)',
                        fill: true,
                        tension: 0.3,
                        pointRadius: 2
                    },
                    {
                        label: 'Peak Memory (MB)',
                        data: chartData.peak_memory,
                        borderColor: '#8E7CE8',
                        backgroundColor: 'transparent',
                        fill: false,
                        tension: 0.3,
                        pointRadius: 2,
                        borderDash: [4, 2]
                    }
                ];
                if (chartData.catalog_limit > 0) {
                    datasets.push({
                        label: 'Catalog Limit',
                        data: chartData.labels.map(function() { return chartData.catalog_limit; }),
                        borderColor: '#E0A93E',
                        backgroundColor: 'transparent',
                        fill: false,
                        pointRadius: 0,
                        borderWidth: 1,
                        borderDash: [6, 4]
                    });
                }
                new Chart(ctx, {
                    type: 'line',
                    data: { labels: chartData.labels, datasets: datasets },
                    options: {
                        responsive: true,
                        maintainAspectRatio: false,
                        plugins: {
                            legend: { labels: { color: '#94A6BF', font: { size: 11 } } }
                        },
                        scales: {
                            x: { ticks: { color: '#5E7392', font: { size: 10 }, maxTicksLimit: 10 }, grid: { color: 'rgba(34,52,79,.5)' } },
                            y: { ticks: { color: '#5E7392', font: { size: 10 } }, grid: { color: 'rgba(34,52,79,.5)' }, title: { display: true, text: 'MB', color: '#5E7392' } }
                        }
                    }
                });
            })();
            </script>
        </section>

        <!-- Customer breakdown -->
        {{if .Customers}}
        <section class="card">
            <h2>Customer Breakdown</h2>
            <table class="data-table">
                <thead>
                    <tr>
                        <th>Customer</th>
                        <th>Avg Memory</th>
                        <th>Peak Memory</th>
                        <th>Avg CPU</th>
                        <th>Total Errors</th>
                        <th>Last Report</th>
                    </tr>
                </thead>
                <tbody>
                    {{range .Customers}}
                    <tr>
                        <td><a href="/customers/{{.CustomerID}}">{{.CustomerID}}</a></td>
                        <td>{{formatFloat .AvgMemoryMB}} MB</td>
                        <td>{{formatFloat .PeakMemoryMB}} MB</td>
                        <td>{{formatFloat .AvgCPU}}%</td>
                        <td>{{if gt .TotalErrors 0}}<span class="badge badge-error">{{.TotalErrors}}</span>{{else}}0{{end}}</td>
                        <td>{{timeAgo .LastReport}}</td>
                    </tr>
                    {{end}}
                </tbody>
            </table>
        </section>
        {{end}}

        <!-- Known issues -->
        <section class="card">
            <div style="display: flex; justify-content: space-between; align-items: center; flex-wrap: wrap; gap: 0.5rem;">
                <h2 style="margin: 0;">Known Issues{{if .CustomerFilter}} <span class="text-muted" style="font-size: 0.85em; font-weight: normal;">— filtered: {{.CustomerFilter}}</span>{{end}}</h2>
                <div style="display: flex; gap: 0.75rem; align-items: center;">
                    {{if .CustomerFilter}}
                    <a href="?period={{.Period}}{{if .ShowDismissed}}&amp;show_dismissed=1{{end}}" style="font-size: 0.85rem;">Clear filter (fleet view)</a>
                    {{end}}
                    {{if .ShowDismissed}}
                    <a href="?period={{.Period}}{{if .CustomerFilter}}&amp;customer={{.CustomerFilter}}{{end}}" style="font-size: 0.85rem;">Hide dismissed</a>
                    {{else}}
                    <a href="?period={{.Period}}{{if .CustomerFilter}}&amp;customer={{.CustomerFilter}}{{end}}&amp;show_dismissed=1" style="font-size: 0.85rem;">Show dismissed</a>
                    {{end}}
                </div>
            </div>
            {{if .Issues}}
            <form method="POST" action="/apps/{{.AppName}}/dismiss-issues{{if .Period}}?period={{.Period}}{{end}}" id="issueForm">
                <input type="hidden" name="_csrf" value="{{.CSRFToken}}">
                <input type="hidden" name="action" value="selected" id="issueAction">
                <table class="data-table">
                    <thead>
                        <tr>
                            <th style="width: 2rem;"><input type="checkbox" id="selectAll" title="Select all"></th>
                            <th>Severity</th>
                            <th>Message</th>
                            <th>Occurrences (all customers)</th>
                            <th>Affected Customers</th>
                            <th>First Seen</th>
                            <th>Last Seen</th>
                            <th></th>
                        </tr>
                    </thead>
                    <tbody>
                        {{range .Issues}}
                        <tr{{if .DismissedAt}} style="opacity: 0.55;"{{end}}>
                            <td><input type="checkbox" name="issue_ids" value="{{.ID}}" class="issue-cb"></td>
                            <td>
                                {{if eq .Severity "error"}}<span class="badge badge-error">error</span>
                                {{else}}<span class="badge badge-warn">warn</span>{{end}}
                                {{if .DismissedAt}}<span class="badge badge-neutral">dismissed</span>{{end}}
                            </td>
                            <td style="font-family: var(--font-mono); font-size: 0.8rem; max-width: 40ch; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; cursor: pointer;" onclick="toggleIssue({{.ID}})">{{.Message}}</td>
                            <td>{{.OccurrenceCount}}</td>
                            <td>{{len .AffectedCustomers}}</td>
                            <td>{{timeAgo .FirstSeen}}</td>
                            <td>{{timeAgo .LastSeen}}</td>
                            <td><button type="button" class="btn btn-sm" onclick="toggleIssue({{.ID}})">Details</button></td>
                        </tr>
                        <tr id="issue-detail-{{.ID}}" style="display: none;">
                            <td colspan="8" style="background: var(--bg-1); border: 1px solid var(--line-soft); padding: 0.75rem;">
                                <div class="text-muted" style="font-size: 0.8rem; margin-bottom: 0.5rem;">
                                    fingerprint: <span style="font-family: var(--font-mono);">{{.Fingerprint}}</span>
                                    &middot; severity: {{.Severity}}
                                    &middot; first seen: {{.FirstSeen.Format "2006-01-02 15:04:05"}}
                                    &middot; last seen: {{.LastSeen.Format "2006-01-02 15:04:05"}}
                                    {{if .DismissedAt}}&middot; dismissed: {{.DismissedAt.Format "2006-01-02 15:04:05"}}{{end}}
                                </div>
                                <div class="text-muted" style="font-size: 0.8rem; margin-bottom: 0.5rem;">
                                    affected customers:
                                    {{range $i, $c := .AffectedCustomers}}{{if $i}}, {{end}}<a href="/customers/{{$c}}">{{$c}}</a>{{else}}—{{end}}
                                </div>
                                <div style="display: flex; justify-content: space-between; align-items: center; gap: 0.5rem;">
                                    <span class="text-muted" style="font-size: 0.8rem;">Full message:</span>
                                    <button type="button" class="btn btn-sm" onclick="copyText('issue-msg-{{.ID}}', this)">Copy</button>
                                </div>
                                <pre id="issue-msg-{{.ID}}" style="font-family: var(--font-mono); font-size: 0.8rem; white-space: pre-wrap; word-break: break-word; background: var(--bg-0); border: 1px solid var(--line-soft); border-radius: var(--radius); padding: 0.5rem; margin: 0.25rem 0 0.75rem;">{{.Message}}</pre>
                                {{if .Context}}
                                <div style="display: flex; justify-content: space-between; align-items: center; gap: 0.5rem;">
                                    <span class="text-muted" style="font-size: 0.8rem;">Context around first occurrence{{if .ContextCustomer}} — from <a href="/customers/{{.ContextCustomer}}">{{.ContextCustomer}}</a>{{end}}:</span>
                                    <button type="button" class="btn btn-sm" onclick="copyText('issue-ctx-{{.ID}}', this)">Copy</button>
                                </div>
                                <pre id="issue-ctx-{{.ID}}" style="font-family: var(--font-mono); font-size: 0.8rem; white-space: pre-wrap; word-break: break-word; background: var(--bg-0); border: 1px solid var(--line-soft); border-radius: var(--radius); padding: 0.5rem; margin: 0.25rem 0 0;">{{joinStrings .Context "\n"}}</pre>
                                {{else}}
                                <span class="text-muted" style="font-size: 0.8rem;">No context captured (pre-v0.111 report or warn-severity issue).</span>
                                {{end}}
                            </td>
                        </tr>
                        {{end}}
                    </tbody>
                </table>
                <div style="display: flex; gap: 0.5rem; margin-top: 0.75rem;">
                    <button type="submit" class="btn btn-sm btn-danger" onclick="document.getElementById('issueAction').value='selected';">Dismiss Selected</button>
                    <button type="submit" class="btn btn-sm btn-danger" onclick="document.getElementById('issueAction').value='all';" data-confirm="Dismiss ALL issues for {{.AppName}}? They resurface on a new occurrence.">Dismiss All Issues</button>
                </div>
            </form>
            <script>
            document.getElementById('selectAll').addEventListener('change', function() {
                var cbs = document.querySelectorAll('.issue-cb');
                for (var i = 0; i < cbs.length; i++) cbs[i].checked = this.checked;
            });
            function toggleIssue(id) {
                var el = document.getElementById('issue-detail-' + id);
                if (el) el.style.display = (el.style.display === 'none') ? '' : 'none';
            }
            function copyText(id, btn) {
                var el = document.getElementById(id);
                if (!el) return;
                var text = el.textContent;
                var done = function() {
                    var old = btn.textContent;
                    btn.textContent = 'Copied';
                    setTimeout(function() { btn.textContent = old; }, 1200);
                };
                if (navigator.clipboard && navigator.clipboard.writeText) {
                    navigator.clipboard.writeText(text).then(done, function() { fallbackCopy(text, done); });
                } else {
                    fallbackCopy(text, done);
                }
            }
            function fallbackCopy(text, done) {
                var ta = document.createElement('textarea');
                ta.value = text;
                ta.style.position = 'fixed';
                ta.style.opacity = '0';
                document.body.appendChild(ta);
                ta.select();
                try { document.execCommand('copy'); done(); } catch (e) {}
                document.body.removeChild(ta);
            }
            </script>
            {{else}}
            <p class="text-muted">No issues in this period{{if .CustomerFilter}} for this customer{{end}}.</p>
            {{end}}
        </section>

        <footer style="margin-top: 2rem; color: var(--text-muted); font-size: 0.8rem; text-align: center;">
            Felhom Hub <span style="font-family: var(--font-mono)">{{hubVersion}}</span>
        </footer>
    </div>
</body>
</html>
