<?php
/**
 * AI Monitor — Traffic Panel partial.
 *
 * Renders a per-subscription Traffic block inside the AI Monitor customer
 * dashboard: yesterday's totals, a 14-day human-views sparkline, the top 10
 * URLs / bandwidth consumers (collapsed), and an "Analyze traffic" button
 * that enqueues a traffic-type review via the existing review worker.
 *
 * Required variables in the includer's scope:
 *   $site_id          (int)    — site row id
 *   $username         (string) — owner of the site (filesystem account)
 *   $primary_domain   (string) — display label
 *   $subscription_id  (int)    — AI monitor subscription id (used by enqueue)
 *   $csrf_token       (string) — passed through to JS for the AJAX call
 *
 * The TrafficAnalytics library reads the per-user monthly SQLite at
 * /docker/users/<username>/whp-analytics/<YYYY-MM>.sqlite3. The aggregator
 * cron writes those files at 1 AM, so today's row generally won't exist
 * mid-day — we surface yesterday's snapshot to keep the UI honest.
 */

require_once('/docker/whp/web/libs/traffic_analytics.php');

if (!isset($site_id, $username, $primary_domain, $subscription_id, $csrf_token)) {
    return;
}

$ta = new TrafficAnalytics();
$yesterdayDate = date('Y-m-d', strtotime('-1 day'));

try {
    $yesterday = $ta->getDailyTotals($username, (int)$site_id, $yesterdayDate);
    $last14    = $ta->getRecentDailyTotals($username, (int)$site_id, 14);
    $topUrls   = $ta->getTopUrls($username, (int)$site_id, $yesterdayDate);
    $topBw     = $ta->getTopBandwidth($username, (int)$site_id, $yesterdayDate);
} catch (Throwable $e) {
    error_log('ai-monitor-traffic-panel: ' . $e->getMessage());
    $yesterday = null;
    $last14    = [];
    $topUrls   = [];
    $topBw     = [];
}

if (!function_exists('whp_traffic_human_filesize')) {
    function whp_traffic_human_filesize(int $bytes): string {
        if ($bytes < 1024)               return $bytes . ' B';
        if ($bytes < 1024 * 1024)        return number_format($bytes / 1024, 1) . ' KB';
        if ($bytes < 1024 * 1024 * 1024) return number_format($bytes / 1048576, 1) . ' MB';
        return number_format($bytes / 1073741824, 2) . ' GB';
    }
}

$canvasId = 'trafficSparkline_' . (int)$site_id;
?>
<div class="card mt-3 traffic-panel" data-site-id="<?php echo (int)$site_id; ?>" data-subscription-id="<?php echo (int)$subscription_id; ?>">
    <div class="card-header">
        <strong><i class="fa fa-bar-chart"></i> Traffic <span class="text-muted small ms-1">— <?php echo htmlspecialchars($primary_domain, ENT_QUOTES, 'UTF-8'); ?></span></strong>
    </div>
    <div class="card-body">
<?php if (empty($last14)): ?>
        <p class="text-muted mb-0">No traffic data collected yet — the nightly aggregator runs at 1 AM. Check back tomorrow.</p>
<?php else:
    $reqs   = (int)($yesterday['total_requests'] ?? 0);
    $human  = (int)($yesterday['human_views']    ?? 0);
    $bytes  = (int)($yesterday['bytes_sent']     ?? 0);
?>
        <div class="row g-3 mb-3">
            <div class="col-md-4">
                <div class="border rounded p-3 text-center h-100">
                    <div class="text-muted small text-uppercase fw-semibold">Total Requests</div>
                    <div style="font-size: 1.75rem; font-weight: 600;"><?php echo number_format($reqs); ?></div>
                    <div class="text-muted small">yesterday</div>
                </div>
            </div>
            <div class="col-md-4">
                <div class="border rounded p-3 text-center h-100">
                    <div class="text-muted small text-uppercase fw-semibold">Human Views</div>
                    <div style="font-size: 1.75rem; font-weight: 600;"><?php echo number_format($human); ?></div>
                    <div class="text-muted small">excl. bots &amp; assets</div>
                </div>
            </div>
            <div class="col-md-4">
                <div class="border rounded p-3 text-center h-100">
                    <div class="text-muted small text-uppercase fw-semibold">Bandwidth Served</div>
                    <div style="font-size: 1.75rem; font-weight: 600;"><?php echo htmlspecialchars(whp_traffic_human_filesize($bytes), ENT_QUOTES, 'UTF-8'); ?></div>
                    <div class="text-muted small">yesterday</div>
                </div>
            </div>
        </div>

        <div class="mb-3">
            <div class="text-muted small text-uppercase fw-semibold mb-1">Human views — last 14 days</div>
            <div style="position: relative; height: 120px;">
                <canvas id="<?php echo htmlspecialchars($canvasId, ENT_QUOTES, 'UTF-8'); ?>"></canvas>
            </div>
        </div>

        <details class="mb-2">
            <summary class="fw-semibold" style="cursor: pointer;">Top 10 URLs (yesterday)</summary>
            <div class="table-responsive mt-2">
                <table class="table table-sm table-hover mb-0">
                    <thead><tr><th style="width: 60px;">#</th><th>Path</th><th class="text-end" style="width: 100px;">Hits</th></tr></thead>
                    <tbody>
<?php if (empty($topUrls)): ?>
                        <tr><td colspan="3" class="text-muted text-center">No data for yesterday.</td></tr>
<?php else: foreach ($topUrls as $row): ?>
                        <tr>
                            <td><?php echo (int)$row['rank']; ?></td>
                            <td class="text-truncate" style="max-width: 480px;" title="<?php echo htmlspecialchars((string)$row['url'], ENT_QUOTES, 'UTF-8'); ?>"><?php echo htmlspecialchars((string)$row['url'], ENT_QUOTES, 'UTF-8'); ?></td>
                            <td class="text-end"><?php echo number_format((int)$row['hits']); ?></td>
                        </tr>
<?php endforeach; endif; ?>
                    </tbody>
                </table>
            </div>
        </details>

        <details class="mb-3">
            <summary class="fw-semibold" style="cursor: pointer;">Top 10 Bandwidth Consumers (yesterday)</summary>
            <div class="table-responsive mt-2">
                <table class="table table-sm table-hover mb-0">
                    <thead><tr><th style="width: 60px;">#</th><th>Path</th><th class="text-end" style="width: 110px;">Bytes</th><th class="text-end" style="width: 90px;">Hits</th></tr></thead>
                    <tbody>
<?php if (empty($topBw)): ?>
                        <tr><td colspan="4" class="text-muted text-center">No data for yesterday.</td></tr>
<?php else: foreach ($topBw as $row): ?>
                        <tr>
                            <td><?php echo (int)$row['rank']; ?></td>
                            <td class="text-truncate" style="max-width: 440px;" title="<?php echo htmlspecialchars((string)$row['url'], ENT_QUOTES, 'UTF-8'); ?>"><?php echo htmlspecialchars((string)$row['url'], ENT_QUOTES, 'UTF-8'); ?></td>
                            <td class="text-end"><?php echo htmlspecialchars(whp_traffic_human_filesize((int)$row['bytes_total']), ENT_QUOTES, 'UTF-8'); ?></td>
                            <td class="text-end"><?php echo number_format((int)$row['hits']); ?></td>
                        </tr>
<?php endforeach; endif; ?>
                    </tbody>
                </table>
            </div>
        </details>

        <div class="d-flex align-items-center gap-2 flex-wrap">
            <button type="button" class="btn btn-sm btn-primary btn-analyze-traffic"
                    data-subscription-id="<?php echo (int)$subscription_id; ?>"
                    data-site-id="<?php echo (int)$site_id; ?>">
                <i class="fa fa-magic"></i> Analyze traffic
            </button>
            <span class="analyze-traffic-status text-muted small" data-subscription-id="<?php echo (int)$subscription_id; ?>"></span>
        </div>

        <script>
        (function() {
            // The page may include this partial multiple times (one per
            // subscription). Render each sparkline only after Chart.js and
            // the DOM are both ready.
            var canvasId = <?php echo json_encode($canvasId); ?>;
            var labels   = <?php echo json_encode(array_map(static fn($r) => substr((string)$r['date'], 5), $last14)); ?>;
            var values   = <?php echo json_encode(array_map(static fn($r) => (int)$r['human_views'], $last14)); ?>;

            function render() {
                if (typeof Chart === 'undefined' || !Chart.Bar && !Chart.register) {
                    // Modern Chart.js (>=3) exposes Chart as a constructor;
                    // legacy 1.x exposes Chart.Bar etc. Wait if neither
                    // looks usable yet.
                    return setTimeout(render, 100);
                }
                var canvas = document.getElementById(canvasId);
                if (!canvas) return;
                // Highlight the latest bar (today / most recent day in window).
                var bgColors = values.map(function(_, i) {
                    return i === values.length - 1 ? '#0d6efd' : 'rgba(13, 110, 253, 0.35)';
                });
                try {
                    new Chart(canvas.getContext('2d'), {
                        type: 'bar',
                        data: {
                            labels: labels,
                            datasets: [{
                                label: 'Human views',
                                data: values,
                                backgroundColor: bgColors,
                                borderWidth: 0
                            }]
                        },
                        options: {
                            responsive: true,
                            maintainAspectRatio: false,
                            plugins: { legend: { display: false } },
                            scales: {
                                x: { grid: { display: false }, ticks: { font: { size: 10 } } },
                                y: { beginAtZero: true, ticks: { font: { size: 10 }, precision: 0 } }
                            }
                        }
                    });
                } catch (e) {
                    // Old Chart.js 1.x can't construct from `new Chart(ctx, config)`.
                    // Fall back to its classic API so the panel still draws.
                    if (canvas.__legacyDrawn) return;
                    canvas.__legacyDrawn = true;
                    var c = new Chart(canvas.getContext('2d'));
                    if (typeof c.Bar === 'function') {
                        c.Bar({
                            labels: labels,
                            datasets: [{
                                fillColor: 'rgba(13, 110, 253, 0.35)',
                                strokeColor: '#0d6efd',
                                data: values
                            }]
                        }, { responsive: true, scaleBeginAtZero: true });
                    }
                }
            }
            if (document.readyState === 'loading') {
                document.addEventListener('DOMContentLoaded', render);
            } else {
                render();
            }
        })();
        </script>
<?php endif; ?>
    </div>
</div>
