<?php
$page_title  = 'Dashboard';
$page_active = 'dashboard';

// ----- TEMP DEBUG LOGGER --------------------------------------------------
// Append to /debug_trace.log at the panel root. .log is denied by .htaccess
// so it's not web-readable — pull it via FTP. Remove once the 500 is diagnosed.
(function () {
    $log_path = __DIR__ . '/debug_trace.log';
    // bootstrap.php hasn't run yet at this point (page_header.php pulls it),
    // so session may not be started. Best-effort snapshot.
    $sess = (session_status() === PHP_SESSION_ACTIVE) ? $_SESSION : null;
    $line = [
        'ts'      => date('c'),
        'page'    => 'dashboard.php',
        'method'  => $_SERVER['REQUEST_METHOD'] ?? '?',
        'ip'      => $_SERVER['HTTP_CF_CONNECTING_IP'] ?? $_SERVER['REMOTE_ADDR'] ?? '?',
        'session_status'   => session_status(),
        'sess_admin_id'    => $sess['admin_id'] ?? null,
        'sess_pending_2fa' => $sess['pending_totp_admin_id'] ?? null,
        'cookie_mpanel'    => isset($_COOKIE['MPANEL']) ? substr($_COOKIE['MPANEL'], 0, 8) . '…' : null,
        'referer'          => $_SERVER['HTTP_REFERER'] ?? null,
        'cf_ray'           => $_SERVER['HTTP_CF_RAY'] ?? null,
    ];
    @file_put_contents($log_path,
        json_encode($line, JSON_UNESCAPED_SLASHES) . "\n",
        FILE_APPEND | LOCK_EX);
    register_shutdown_function(function () use ($log_path) {
        $e = error_get_last();
        $tail = [
            'ts'       => date('c'),
            'page'     => 'dashboard.php-end',
            'php_err'  => $e,
            'http_code'=> http_response_code(),
        ];
        @file_put_contents($log_path,
            json_encode($tail, JSON_UNESCAPED_SLASHES) . "\n",
            FILE_APPEND | LOCK_EX);
    });
})();
// ----- END TEMP DEBUG LOGGER ----------------------------------------------

require __DIR__ . '/includes/page_header.php';
?>

<!-- Dashboard Header (IBO GLASS style — full-bleed top band) -->
<div class="-mx-6 -mt-6 px-6 py-5 mb-6 border-b border-dark-700" style="background:#111;">
    <div class="flex items-center justify-between">
        <div>
            <p class="text-xs font-semibold text-primary-400 uppercase tracking-wider mb-1">
                <span class="text-dark-400">Master Panel</span> / Dashboard
            </p>
            <h2 class="text-2xl font-bold text-white flex items-center gap-3">
                <i class="ph ph-hand-waving text-primary-400"></i> Welcome Back
            </h2>
        </div>
    </div>
</div>

<!-- Stats Row -->
<div class="grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-4 gap-5 mb-6" id="statsRow">
    <div class="stat-card" id="statHits">
        <div class="flex items-center justify-between mb-3">
            <p class="text-xs font-semibold text-dark-400 uppercase tracking-wide">Total API Hits</p>
            <div class="h-10 w-10 bg-primary-500/10 rounded-lg flex items-center justify-center">
                <i class="ph ph-chart-line-up text-xl text-primary-400"></i>
            </div>
        </div>
        <p class="text-3xl font-bold text-white">—</p>
        <p class="text-xs text-dark-400 mt-2">Tracked from panel and module activity.</p>
    </div>
    <div class="stat-card" id="statEndpoints">
        <div class="flex items-center justify-between mb-3">
            <p class="text-xs font-semibold text-dark-400 uppercase tracking-wide">Tracked Endpoints</p>
            <div class="h-10 w-10 bg-emerald-500/10 rounded-lg flex items-center justify-center">
                <i class="ph ph-fingerprint text-xl text-emerald-400"></i>
            </div>
        </div>
        <p class="text-3xl font-bold text-white">—</p>
        <p class="text-xs text-dark-400 mt-2">Unique active IPs observed.</p>
    </div>
    <div class="stat-card" id="statTop">
        <div class="flex items-center justify-between mb-3">
            <p class="text-xs font-semibold text-dark-400 uppercase tracking-wide">Top Endpoint</p>
            <div class="h-10 w-10 bg-amber-500/10 rounded-lg flex items-center justify-center">
                <i class="ph ph-crown text-xl text-amber-400"></i>
            </div>
        </div>
        <p class="text-xl font-bold text-primary-400 truncate">—</p>
        <p class="text-xs text-dark-400 mt-2">requests captured.</p>
    </div>
    <div class="stat-card" id="statDb">
        <div class="flex items-center justify-between mb-3">
            <p class="text-xs font-semibold text-dark-400 uppercase tracking-wide">Database Footprint</p>
            <div class="h-10 w-10 bg-blue-500/10 rounded-lg flex items-center justify-center">
                <i class="ph ph-database text-xl text-blue-400"></i>
            </div>
        </div>
        <p class="text-3xl font-bold text-white">—</p>
        <p class="text-xs text-dark-400 mt-2">Total storage used by your panel data.</p>
    </div>
</div>

<!-- Map + Traffic Distribution -->
<div class="grid grid-cols-1 xl:grid-cols-3 gap-6 mb-6">
    <div class="xl:col-span-2 card">
        <div class="px-6 py-4 border-b border-dark-700 flex items-center justify-between">
            <h3 class="text-sm font-semibold text-primary-400 uppercase tracking-wide flex items-center gap-2">
                <i class="ph ph-map-trifold"></i> Active Client Map
            </h3>
            <span class="text-xs text-dark-500">Geographic activity from recent client requests</span>
        </div>
        <div id="dashboardMap" style="width: 100%; height: 380px; background-color: transparent;"></div>
        <div id="topCountries" class="px-6 py-3 border-t border-dark-700 hidden"></div>
    </div>
    <div class="card">
        <div class="px-6 py-4 border-b border-dark-700 flex items-center justify-between">
            <h3 class="text-sm font-semibold text-primary-400 uppercase tracking-wide flex items-center gap-2">
                <i class="ph ph-chart-pie"></i> Traffic Distribution
            </h3>
            <span class="text-xs text-dark-500">Share of requests by endpoint</span>
        </div>
        <div class="p-5 flex items-center justify-center" style="height:240px;">
            <div style="position:relative;width:220px;height:220px;">
                <canvas id="trafficPieChart"></canvas>
            </div>
        </div>
        <div id="trafficLegend" class="px-5 pb-5 space-y-1.5"></div>
    </div>
</div>

<!-- Recent Client Activity -->
<div class="card mb-6">
    <div class="px-6 py-4 border-b border-dark-700 flex items-center justify-between">
        <h3 class="text-sm font-semibold text-primary-400 uppercase tracking-wide flex items-center gap-2">
            <i class="ph ph-clock-counter-clockwise"></i> Recent Client Activity
        </h3>
        <a href="logs.php" class="text-xs text-primary-400 hover:text-primary-300">View all <i class="ph ph-arrow-right"></i></a>
    </div>
    <div id="recentActivity" class="dash-loading"><div class="px-6 py-8 text-center text-sm text-dark-500">Loading…</div></div>
</div>

<!-- Top Endpoints (bar chart) -->
<div class="card mb-6">
    <div class="px-6 py-4 border-b border-dark-700">
        <h3 class="text-sm font-semibold text-primary-400 uppercase tracking-wide flex items-center gap-2">
            <i class="ph ph-chart-bar"></i> Top Endpoints
        </h3>
    </div>
    <div id="topEndpointsChart" class="p-5 dash-loading"><p class="text-xs text-dark-500">Loading…</p></div>
</div>

<!-- Long tail (hidden until data) -->
<div class="card mb-6" id="longTailCard" style="display:none">
    <div class="px-6 py-4 border-b border-dark-700">
        <h3 class="text-sm font-semibold text-primary-400 uppercase tracking-wide flex items-center gap-2">
            <i class="ph ph-list-numbers"></i> Long-Tail Endpoints
        </h3>
    </div>
    <div id="longTailBody"></div>
</div>

<!-- Vendor libs (chart + map, locally hosted) -->
<link rel="stylesheet" href="assets/vendor/jsvectormap.min.css">
<script src="assets/vendor/jsvectormap.min.js"></script>
<script src="assets/vendor/world.js"></script>
<script src="assets/vendor/chart.umd.min.js"></script>

<script>
(function () {
    var period       = '14d';
    var mapInstance  = null;
    var trafficChart = null;
    var chartColors  = ['#f39c12','#3b82f6','#10b981','#8b5cf6','#ef4444','#06b6d4','#f97316','#ec4899','#6b7280'];

    function esc(s) { var d = document.createElement('div'); d.textContent = s == null ? '' : s; return d.innerHTML; }
    function num(n) { return (n || 0).toLocaleString(); }
    function timeAgo(ts) {
        var d = Math.floor((Date.now() / 1000) - (new Date((ts || '').replace(' ', 'T') + 'Z').getTime() / 1000));
        if (isNaN(d) || d < 0) d = 0;
        if (d < 60)   return d + 's ago';
        if (d < 3600) return Math.floor(d / 60) + 'm ago';
        if (d < 86400)return Math.floor(d / 3600) + 'h ago';
        return Math.floor(d / 86400) + 'd ago';
    }
    function flag(code) {
        if (!code || code.length !== 2 || code.toLowerCase() === 'xx') return '<i class="ph ph-globe text-sm text-dark-400"></i>';
        code = code.toUpperCase();
        return '<span class="text-lg">' + String.fromCodePoint(0x1F1E6 + code.charCodeAt(0) - 65) + String.fromCodePoint(0x1F1E6 + code.charCodeAt(1) - 65) + '</span>';
    }
    var APP_NAMES = {
        xciptv: 'XCIPTV', smarters: 'Smarters Pro', sparkle: 'Sparkle TV', tivimate: 'TiviMate',
        stremio: 'Stremio', purple: 'Purple Player', nio: 'NIO Player', cockpit: 'Cockpit',
        dalvik: 'Android App', okhttp: 'Android App', 'go-http-client': 'Go Client',
        ibo: 'IBO Sol.', flextv: 'IBO Ultra', glass: 'IBO Ultra',
    };
    function detectApp(ua) {
        var l = (ua || '').toLowerCase();
        for (var k in APP_NAMES) { if (l.indexOf(k) !== -1) return APP_NAMES[k]; }
        if (l.indexOf('mozilla') !== -1 || l.indexOf('chrome') !== -1) return 'Browser';
        return ua ? 'Unknown' : '—';
    }

    function load() {
        fetch('api/stats.php?period=' + period, { credentials: 'same-origin' })
            .then(function (r) { return r.json(); })
            .then(function (s) {
                renderStats(s);
                renderMap(s.country_counts || {});
                renderChart(s.endpoint_dist || []);
                renderMarkers(s.markers || []);
                renderActivity(s.recent_clients || []);
                renderTopEndpoints(s.top_endpoints || []);
                renderLongTail(s.long_tail || [], s.total_hits || 0);
            })
            .catch(function (e) {
                document.querySelectorAll('.dash-loading').forEach(function (el) {
                    el.innerHTML = '<div class="px-6 py-8 text-center text-sm text-red-400">Failed to load.</div>';
                });
                console.error('Dashboard stats error', e);
            });
    }

    function renderStats(s) {
        var labels = { '24h':'24 Hours','7d':'7 Days','14d':'14 Days','30d':'30 Days' };
        var pl = labels[period] || period;
        var topName = s.top_endpoint || '—';
        document.querySelector('#statHits p.text-3xl').textContent  = num(s.total_hits);
        document.querySelector('#statHits p.mt-2').textContent      = 'Tracked from panel and module activity across the last ' + pl + '.';
        document.querySelector('#statEndpoints p.text-3xl').textContent = num(s.unique_ips);
        document.querySelector('#statEndpoints p.mt-2').textContent     = 'Unique active IPs observed across the last ' + pl + '.';
        var topEl = document.querySelector('#statTop p.text-xl');
        topEl.textContent = topName; topEl.title = topName;
        document.querySelector('#statTop p.mt-2').textContent = num(s.top_ep_count) + ' requests across the last ' + pl + '.';
        document.querySelector('#statDb p.text-3xl').textContent = s.db_size || '—';
    }

    function renderMap(cc) {
        var el = document.getElementById('dashboardMap');
        var attempts = 0;
        function init() {
            if (typeof jsVectorMap === 'undefined') {
                if (++attempts > 30) { el.innerHTML = '<div class="flex items-center justify-center h-full text-dark-500 text-sm">Map library not available</div>'; return; }
                setTimeout(init, 300); return;
            }
            el.innerHTML = '';
            try {
                mapInstance = new jsVectorMap({
                    selector: '#dashboardMap', map: 'world',
                    backgroundColor: 'transparent', zoomButtons: true, zoomOnScroll: true, draggable: true, showTooltip: true,
                    regionStyle: {
                        initial:  { fill: '#1e1e1e', stroke: '#3a3a3a', strokeWidth: 0.8 },
                        hover:    { fill: '#f39c12', fillOpacity: 0.7, cursor: 'pointer' },
                        selected: { fill: '#f39c12' }
                    },
                    selectedRegions: Object.keys(cc),
                    onRegionTooltipShow: function (ev, tooltip, code) {
                        var n = cc[code] || 0;
                        if (n > 0) tooltip.text(tooltip.text() + ' — <span style="color:#f39c12;font-weight:700;">' + n + ' requests</span>', true);
                    }
                });
            } catch (e) {
                el.innerHTML = '<div class="flex items-center justify-center h-full text-dark-500 text-sm">Map failed to load</div>';
            }
        }
        init();
    }

    function renderMarkers(markers) {
        if (!markers.length || !mapInstance) return;
        try {
            mapInstance.addMarkers(markers.map(function (m) {
                return { coords: [m.lat, m.lng], name: m.name + ' — ' + num(m.count) + ' requests',
                         style: { initial: { fill: '#f39c12', r: Math.min(3 + Math.log2(m.count + 1) * 2, 12) } } };
            }));
        } catch (e) {}
    }

    function renderChart(dist) {
        var legend = document.getElementById('trafficLegend');
        if (!dist.length) { legend.innerHTML = '<div class="text-center py-4 text-dark-500 text-xs">No traffic data yet.</div>'; return; }
        function init() {
            if (typeof Chart === 'undefined') { setTimeout(init, 300); return; }
            var ctx = document.getElementById('trafficPieChart');
            if (trafficChart) trafficChart.destroy();
            trafficChart = new Chart(ctx, {
                type: 'doughnut',
                data: {
                    labels: dist.map(function (e) { return e.name; }),
                    datasets: [{
                        data: dist.map(function (e) { return e.count; }),
                        backgroundColor: chartColors.slice(0, dist.length),
                        borderColor: '#161616', borderWidth: 2,
                    }],
                },
                options: { responsive: true, cutout: '60%',
                    plugins: { legend: { display: false },
                               tooltip: { backgroundColor: '#1a1a1a', titleColor: '#f39c12', bodyColor: '#ccc', borderColor: '#2a2a2a', borderWidth: 1 } } }
            });
            var total = dist.reduce(function (s, e) { return s + e.count; }, 0);
            legend.innerHTML = dist.map(function (e, i) {
                var pct = total > 0 ? ((e.count / total) * 100).toFixed(1) : 0;
                return '<div class="flex items-center gap-2 text-xs">' +
                       '<span class="w-2.5 h-2.5 rounded-full flex-shrink-0" style="background:' + chartColors[i % chartColors.length] + '"></span>' +
                       '<span class="text-dark-300 flex-1 truncate">' + esc(e.name) + '</span>' +
                       '<span class="text-dark-500">(' + num(e.count) + ')</span>' +
                       '<span class="text-dark-400 font-semibold">' + pct + '%</span></div>';
            }).join('');
        }
        init();
    }

    function renderActivity(clients) {
        var el = document.getElementById('recentActivity');
        el.classList.remove('dash-loading');
        if (!clients.length) { el.innerHTML = '<div class="px-6 py-8 text-center text-sm text-dark-500">No connections recorded yet.</div>'; return; }
        var html = '<div class="overflow-x-auto"><table class="compact"><thead><tr>' +
                   '<th class="w-32">Endpoint</th><th class="w-10"></th><th>Time</th><th>Details</th></tr></thead><tbody>';
        clients.slice(0, 15).forEach(function (c) {
            html += '<tr>' +
                '<td><span class="inline-block px-2 py-0.5 text-xs font-semibold rounded bg-primary-500/20 text-primary-400">' + esc(detectApp(c.user_agent)) + '</span></td>' +
                '<td class="text-center">' + flag(c.country_code || 'xx') + '</td>' +
                '<td class="text-xs text-dark-400 whitespace-nowrap">' + timeAgo(c.latest) + '</td>' +
                '<td class="text-xs text-dark-500 truncate max-w-[420px]" title="' + esc(c.user_agent || '') + '">' +
                    '<span class="mono text-dark-300">' + esc(c.endpoint || '') + '</span> · ' +
                    esc((c.user_agent || '').substring(0, 80)) + '</td></tr>';
        });
        html += '</tbody></table></div>';
        el.innerHTML = html;
    }

    function renderTopEndpoints(eps) {
        var el = document.getElementById('topEndpointsChart');
        el.classList.remove('dash-loading');
        if (!eps.length) { el.innerHTML = '<div class="text-center py-8 text-dark-500 text-sm">No endpoint data yet.</div>'; return; }
        var max = eps[0].count || 1;
        el.innerHTML = eps.map(function (ep, i) {
            var pct = Math.max(8, (ep.count / max) * 100);
            return '<div class="flex items-center gap-3 mb-3">' +
                   '<span class="text-xs text-dark-300 w-28 truncate text-right" title="' + esc(ep.name) + '">' + esc(ep.name) + '</span>' +
                   '<div class="flex-1 bg-dark-800 rounded-full h-5 overflow-hidden">' +
                       '<div class="h-full rounded-full flex items-center justify-end px-2 text-[10px] font-bold text-black" style="width:' + pct + '%;background:' + chartColors[i % chartColors.length] + ';">' + num(ep.count) + '</div>' +
                   '</div></div>';
        }).join('');
    }

    function renderLongTail(lt, total) {
        if (!lt.length) return;
        document.getElementById('longTailCard').style.display = '';
        var html = '<div class="overflow-x-auto"><table class="compact"><thead><tr><th>Endpoint</th><th class="text-right">Req</th><th class="text-right">Share</th></tr></thead><tbody>';
        lt.forEach(function (e) {
            var share = total > 0 ? ((e.count / total) * 100).toFixed(2) : '0.00';
            html += '<tr><td class="text-sm text-dark-300 mono">' + esc(e.name) + '</td>' +
                    '<td class="text-sm text-right">' + num(e.count) + '</td>' +
                    '<td class="text-right"><span class="text-xs bg-primary-500/20 text-primary-400 px-2 py-0.5 rounded-full font-semibold">' + share + '%</span></td></tr>';
        });
        html += '</tbody></table></div>';
        document.getElementById('longTailBody').innerHTML = html;
    }

    load();
})();
</script>

<?php require __DIR__ . '/includes/page_footer.php'; ?>
