<?php
// Buka session dalam mode read-only agar tidak mengunci session saat file ini berjalan
session_start(['read_and_close' => true]);
require('routeros_api.class.php');

// ===== CEK LOGIN =====
if (!isset($_SESSION['ip'], $_SESSION['user'], $_SESSION['pass'])) {
    header('Location: index.php');
    exit;
}

// ===== FOLDER CACHE =====
$cacheDir = __DIR__ . '/cache';
if (!is_dir($cacheDir)) {
    @mkdir($cacheDir, 0755, true);
}

// ===== FILE CACHE BERDASARKAN IP MIKROTIK (AMAN) =====
$mikrotikIpRaw = $_SESSION['ip'] ?? '';
$mikrotikIp = preg_replace('/[^0-9\.]/', '', $mikrotikIpRaw);
$cacheFile = $cacheDir . '/cache_comment_' . ($mikrotikIp ?: 'unknown') . '.json';
$dedicatedFile = $cacheDir . '/dedicated_comments_' . ($mikrotikIp ?: 'unknown') . '.json';

// ===== HELPERS: BACA / TULIS DENGAN LOCK =====
function read_json_file_lock(string $path): array {
    if (!file_exists($path)) return [];
    $fp = @fopen($path, 'r');
    if (!$fp) return [];
    $contents = '';
    if (flock($fp, LOCK_SH)) {
        $contents = stream_get_contents($fp);
        flock($fp, LOCK_UN);
    }
    fclose($fp);
    $data = json_decode($contents, true);
    return is_array($data) ? $data : [];
}

function atomic_write_json(string $path, $data): bool {
    $dir = dirname($path);
    if (!is_dir($dir) && !@mkdir($dir, 0755, true)) {
        return false;
    }
    $tmp = $path . '.tmp';
    $json = json_encode($data, JSON_PRETTY_PRINT | JSON_UNESCAPED_SLASHES | JSON_UNESCAPED_UNICODE);
    if ($json === false) return false;
    $fp = @fopen($tmp, 'c');
    if (!$fp) return false;
    $ok = false;
    if (flock($fp, LOCK_EX)) {
        ftruncate($fp, 0);
        rewind($fp);
        $written = fwrite($fp, $json);
        fflush($fp);
        flock($fp, LOCK_UN);
        fclose($fp);
        if ($written !== false && @rename($tmp, $path)) {
            @chmod($path, 0644);
            $ok = true;
        } else {
            @unlink($tmp);
            $ok = false;
        }
    } else {
        fclose($fp);
        @unlink($tmp);
        $ok = false;
    }
    return $ok;
}

// ===== FUNCTION EKSTRAK PREFIX (HANYA HURUF) =====
function extractPrefix(string $comment): string {
    if (preg_match('/\d{2}\.\d{2}\.\d{2}-\d*([A-Za-z]+)/', $comment, $match)) {
        return strtoupper($match[1]);
    }
    return '-';
}

// ===== HANDLE RELOAD PARAM (AMAN) =====
$reload = filter_input(INPUT_GET, 'reload', FILTER_SANITIZE_STRING);
if ($reload === '1' && file_exists($cacheFile)) {
    @unlink($cacheFile);
}

// ===== HANDLE PREFIX FILTER =====
$prefixFilter = filter_input(INPUT_GET, 'prefix', FILTER_SANITIZE_STRING);

// Function untuk hapus comment dari dedicated file
function removeExpiredComment(string $dedicatedFile, string $comment): bool {
    $data = read_json_file_lock($dedicatedFile);
    if (isset($data['comments'][$comment])) {
        unset($data['comments'][$comment]);
        return atomic_write_json($dedicatedFile, $data);
    }
    return true;
}

// ===== CONNECT MIKROTIK =====
$API = new RouterosAPI();
$API->debug = false;
$API->connect_timeout = 4;
$API->read_timeout = 7;

$errorMsg = '';
$filtered = [];
$expiredComments = [];
$cacheValid = false;
$allPrefixes = [];

// ===== LOAD CACHE JIKA ADA & VALID =====
$cacheData = read_json_file_lock($cacheFile);
if (!empty($cacheData['timestamp']) && (time() - (int)$cacheData['timestamp'] < 3600) && is_array($cacheData['data'])) {
    $filtered = $cacheData['data'];
    // Load expired dari cache jika ada
    if (isset($cacheData['expired']) && is_array($cacheData['expired'])) {
        $expiredComments = $cacheData['expired'];
        $filtered = array_merge($filtered, $expiredComments);
    }
    $cacheValid = true;
}

if (!$cacheValid) {
    $connected = false;
    try {
        if ($API->connect($_SESSION['ip'], $_SESSION['user'], $_SESSION['pass'])) {
            $connected = true;
            $API->write('/ip/hotspot/user/print');
            $users = $API->parseResponse($API->read(false));
            if (!is_array($users)) $users = [];

            $dedicatedData = read_json_file_lock($dedicatedFile);
            $previousComments = isset($dedicatedData['comments']) ? array_keys($dedicatedData['comments']) : [];
            
            $grouped = [];
            $currentComments = [];
            
            foreach ($users as $u) {
                $comment = $u['comment'] ?? '';
                if ($comment === '') continue;
                
                $currentComments[] = $comment;
                
                if (preg_match('/^([a-zA-Z0-9\-]+)-(\d{2}\.\d{2}\.\d{2})/', $comment, $match)) {
                    $prefixTanggal = $match[1] . '-' . $match[2];
                    $grouped[$prefixTanggal][] = $u;
                }
            }

            $filtered = [];
            foreach ($grouped as $key => $listUser) {
                $jumlah = count($listUser);
                if ($jumlah >= 1 && $jumlah <= 10) {
                    $filtered[] = [
                        'jumlah' => $jumlah,
                        'user' => $listUser[0],
                        'status' => 'active',
                        'prefix' => extractPrefix($listUser[0]['comment'] ?? '')
                    ];
                }
            }

            foreach ($previousComments as $oldComment) {
                if (!in_array($oldComment, $currentComments)) {
                    $expiredComments[] = [
                        'jumlah' => $dedicatedData['comments'][$oldComment]['jumlah'] ?? 0,
                        'user' => $dedicatedData['comments'][$oldComment]['user'] ?? [],
                        'status' => 'expired',
                        'deleted_at' => $dedicatedData['comments'][$oldComment]['deleted_at'] ?? date('Y-m-d H:i:s'),
                        'prefix' => extractPrefix($dedicatedData['comments'][$oldComment]['user']['comment'] ?? '')
                    ];
                }
            }

            $sortFunction = function($a, $b) {
                $getDate = function($item) {
                    $c = $item['user']['comment'] ?? '';
                    if (preg_match('/\d{2}\.\d{2}\.\d{2}/', $c, $m)) {
                        $dt = DateTime::createFromFormat('m.d.y', $m[0]);
                        if ($dt instanceof DateTime) {
                            return $dt->getTimestamp();
                        }
                    }
                    return 0;
                };
                return $getDate($b) <=> $getDate($a);
            };
            
            usort($filtered, $sortFunction);
            usort($expiredComments, $sortFunction);

            $allComments = array_merge($filtered, $expiredComments);

            // ← UBAH BAGIAN INI: Simpan kedua data ke cache
            atomic_write_json($cacheFile, [
                'timestamp' => time(),
                'data' => $filtered,
                'expired' => $expiredComments  // ← TAMBAH INI
            ]);

            $dedicatedStore = ['comments' => []];
            foreach ($allComments as $item) {
                $comment = $item['user']['comment'] ?? 'unknown';
                $dedicatedStore['comments'][$comment] = [
                    'jumlah' => $item['jumlah'],
                    'user' => $item['user'],
                    'status' => $item['status'],
                    'deleted_at' => $item['deleted_at'] ?? null,
                    'tracked_at' => date('Y-m-d H:i:s')
                ];
            }
            atomic_write_json($dedicatedFile, $dedicatedStore);

            $filtered = $allComments;

        } else {
            $errorMsg = '❌ Gagal koneksi ke Mikrotik.';
        }
    } catch (Exception $e) {
        $errorMsg = '❌ Terjadi kesalahan saat mengambil data: ' . $e->getMessage();
    } finally {
        if (!empty($connected) && $API->connected) {
            $API->disconnect();
        }
    }
}


// ===== COLLECT ALL PREFIXES & APPLY FILTER =====
$prefixList = [];
$displayData = [];
$totalActive = 0;
$totalExpired = 0;

foreach ($filtered as $item) {
    $prefix = $item['prefix'] ?? '-';
    if (!in_array($prefix, $prefixList)) {
        $prefixList[] = $prefix;
    }
    
    if ($item['status'] === 'active') {
        $totalActive++;
    } else {
        $totalExpired++;
    }
    
    // Apply prefix filter jika ada
    if (empty($prefixFilter) || $prefix === $prefixFilter) {
        $displayData[] = $item;
    }
}

sort($prefixList);

?>
<!DOCTYPE html>
<html lang="id">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Monitoring VCR - Comment</title>
    <link rel="icon" href="favicon.png" />
    <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.0/css/all.min.css">
    <style>
* {
    margin: 0;
    padding: 0;
    box-sizing: border-box;
}

body {
    font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
    background: linear-gradient(135deg, #f5f7fa 0%, #c3cfe2 100%);
    min-height: 100vh;
    padding: 20px;
}

/* ===== HEADER ===== */
header {
    background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
    color: white;
    padding: 25px 30px;
    border-radius: 15px;
    margin-bottom: 30px;
    box-shadow: 0 10px 30px rgba(102, 126, 234, 0.3);
    display: flex;
    justify-content: space-between;
    align-items: center;
    flex-wrap: wrap;
    gap: 20px;
    animation: slideDown 0.5s ease;
}

@keyframes slideDown {
    from {
        opacity: 0;
        transform: translateY(-20px);
    }
    to {
        opacity: 1;
        transform: translateY(0);
    }
}

.header-left {
    display: flex;
    align-items: center;
    gap: 15px;
}

.header-logo {
    font-size: 2.5em;
}

.header-info h1 {
    font-size: 28px;
    font-weight: 700;
    margin-bottom: 5px;
}

.header-info p {
    font-size: 14px;
    opacity: 0.9;
}

.header-stats {
    display: flex;
    gap: 15px;
    flex-wrap: wrap;
}

.stat-item {
    display: flex;
    flex-direction: column;
    align-items: center;
    background: rgba(255, 255, 255, 0.15);
    padding: 12px 18px;
    border-radius: 8px;
    backdrop-filter: blur(10px);
}

.stat-number {
    font-size: 24px;
    font-weight: 700;
}

.stat-label {
    font-size: 12px;
    opacity: 0.9;
}

/* ===== MAIN ===== */
main {
    max-width: 1200px;
    margin: 0 auto;
}

/* ===== ACTION BAR ===== */
.action-bar {
    display: flex;
    justify-content: space-between;
    align-items: center;
    gap: 15px;
    margin-bottom: 25px;
    flex-wrap: wrap;
}

.btn-group {
    display: flex;
    gap: 10px;
    flex-wrap: wrap;
}

.btn {
    padding: 12px 20px;
    border-radius: 8px;
    border: none;
    cursor: pointer;
    font-size: 14px;
    font-weight: 600;
    transition: all 0.3s ease;
    display: inline-flex;
    align-items: center;
    gap: 8px;
    text-decoration: none;
    background: white;
    color: #333;
    box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);
}

.btn:hover {
    transform: translateY(-2px);
    box-shadow: 0 5px 15px rgba(0, 0, 0, 0.15);
}

.btn-primary {
    background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
    color: white;
}

.btn-primary:hover {
    box-shadow: 0 5px 20px rgba(102, 126, 234, 0.4);
}

.btn-success {
    background: linear-gradient(135deg, #28a745 0%, #20c997 100%);
    color: white;
}

.btn-success:hover {
    box-shadow: 0 5px 20px rgba(40, 167, 69, 0.4);
}

.btn-info {
    background: linear-gradient(135deg, #17a2b8 0%, #00a8b5 100%);
    color: white;
}

.btn-info:hover {
    box-shadow: 0 5px 20px rgba(23, 162, 184, 0.4);
}

.btn-print {
    background: linear-gradient(135deg, #6c757d 0%, #5a6268 100%);
    color: white;
}

.btn-print:hover {
    box-shadow: 0 5px 20px rgba(108, 117, 125, 0.4);
}

/* ===== PREFIX FILTER ===== */
.prefix-filter-section {
    background: white;
    padding: 20px;
    border-radius: 12px;
    margin-bottom: 25px;
    box-shadow: 0 2px 8px rgba(0, 0, 0, 0.08);
}

.filter-label {
    font-weight: 700;
    color: #333;
    margin-bottom: 12px;
    display: flex;
    align-items: center;
    gap: 8px;
    font-size: 15px;
}

.prefix-buttons {
    display: flex;
    flex-wrap: wrap;
    gap: 8px;
}

.prefix-btn {
    padding: 8px 14px;
    border-radius: 6px;
    border: 2px solid #dee2e6;
    background: white;
    color: #333;
    cursor: pointer;
    font-size: 13px;
    font-weight: 600;
    text-decoration:none;
    transition: all 0.2s ease;
}

.prefix-btn:hover {
    border-color: #667eea;
    background: #f8f9fa;
}

.prefix-btn.active {
    background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
    color: white;
    border-color: #667eea;
}

.prefix-btn-clear {
    background: #e9ecef;
    border-color: #dee2e6;
}

.prefix-btn-clear:hover {
    background: #dee2e6;
}

/* ===== ALERT ===== */
.alert {
    padding: 15px 20px;
    border-radius: 8px;
    margin-bottom: 20px;
    display: flex;
    align-items: center;
    gap: 12px;
    animation: slideIn 0.3s ease;
}

.alert-error {
    background: #fee;
    border: 1px solid #fcc;
    color: #c33;
    border-left: 4px solid #dc3545;
}

@keyframes slideIn {
    from {
        opacity: 0;
        transform: translateX(-20px);
    }
    to {
        opacity: 1;
        transform: translateX(0);
    }
}

/* ===== TABLE ===== */
.table-responsive {
    background: white;
    border-radius: 12px;
    box-shadow: 0 2px 12px rgba(0, 0, 0, 0.08);
    overflow: hidden;
}

table {
    width: 100%;
    border-collapse: collapse;
}

thead {
    background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
    color: white;
    position: sticky;
    top: 0;
}

th {
    padding: 16px;
    text-align: left;
    font-weight: 700;
    font-size: 13px;
    text-transform: uppercase;
    letter-spacing: 0.5px;
    user-select: none;
    cursor: pointer;
    transition: all 0.2s ease;
}

th:hover {
    background: rgba(0, 0, 0, 0.1);
}

tbody tr {
    border-bottom: 1px solid #f0f0f0;
    transition: all 0.2s ease;
}

tbody tr:hover {
    background: #fafbfc;
    box-shadow: 0 2px 4px rgba(0, 0, 0, 0.05);
}

tbody tr.expired {
    background: #fffbf0;
    opacity: 0.9;
}

tbody tr.expired:hover {
    background: #fff8e6;
    opacity: 1;
}

td {
    padding: 14px 16px;
    font-size: 14px;
}

td.no-urut {
    text-align: center;
    font-weight: 700;
    color: #667eea;
    width: 50px;
    min-width: 50px;
}

/* PFX/JUM DIPERKECIL */
td.prefix-jumlah {
    text-align: center;
    width: 90px;
    min-width: 90px;
}

.prefix-jumlah-wrapper {
    display: flex;
    align-items: center;
    justify-content: center;
    gap: 6px;
}

.prefix-badge {
    background: linear-gradient(135deg, #28a745 0%, #20c997 100%);
    color: white;
    padding: 5px 9px;
    border-radius: 5px;
    font-weight: 700;
    font-size: 12px;
    cursor: pointer;
    transition: all 0.2s ease;
    min-width: 38px;
    text-align: center;
    user-select: none;
}

.prefix-badge:hover {
    transform: translateY(-2px);
    box-shadow: 0 3px 10px rgba(40, 167, 69, 0.3);
}

.jumlah-badge {
    background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
    color: white;
    padding: 5px 8px;
    border-radius: 5px;
    font-weight: 700;
    font-size: 11px;
    cursor: pointer;
    transition: all 0.2s ease;
    min-width: 30px;
    text-align: center;
    user-select: none;
}

.jumlah-badge:hover {
    transform: translateY(-2px);
    box-shadow: 0 3px 10px rgba(102, 126, 234, 0.3);
}

/* COMM DIPERLEBAR */
td.comment {
    font-family: 'Courier New', monospace;
    font-weight: 600;
    color: #0d1823;
    word-break: break-all;
    flex: 1;
    min-width: 200px;
}

td.profile {
    color: #666;
    font-size: 13px;
    width: 120px;
    min-width: 120px;
}

/* STATUS DIPERKECIL */
td.status-badge {
    text-align: center;
    width: 80px;
    min-width: 80px;
}

.badge {
    display: inline-block;
    padding: 5px 9px;
    border-radius: 5px;
    font-size: 11px;
    font-weight: 600;
    text-transform: uppercase;
}

.badge-active {
    background: linear-gradient(135deg, #d4edda 0%, #c3e6cb 100%);
    color: #155724;
}

.badge-expired {
    background: linear-gradient(135deg, #f8d7da 0%, #f5c6cb 100%);
    color: #721c24;
}

td.action {
    text-align: center;
    width: 90px;
    min-width: 90px;
}

.btn-delete {
    background: linear-gradient(135deg, #dc3545 0%, #ff6b6b 100%);
    color: white;
    border: none;
    padding: 8px 12px;
    border-radius: 6px;
    cursor: pointer;
    font-size: 12px;
    font-weight: 600;
    transition: all 0.2s ease;
    display: inline-flex;
    align-items: center;
    gap: 5px;
}

.btn-delete:hover {
    transform: translateY(-1px);
    box-shadow: 0 4px 8px rgba(220, 53, 69, 0.3);
}

.btn-delete:disabled {
    opacity: 0.6;
    cursor: not-allowed;
    transform: none;
}

.btn-expired {
    background: linear-gradient(135deg, #ff9800 0%, #ffb74d 100%);
}

.btn-expired:hover {
    box-shadow: 0 4px 8px rgba(255, 152, 0, 0.3);
}

/* ===== EMPTY STATE ===== */
.empty-state {
    text-align: center;
    padding: 40px 20px;
    color: #999;
}

.empty-state-icon {
    font-size: 48px;
    margin-bottom: 15px;
    opacity: 0.3;
}

/* ===== PROGRESS OVERLAY ===== */
#overlay {
    display: none;
    position: fixed;
    top: 0;
    left: 0;
    width: 100%;
    height: 100%;
    background: rgba(0, 0, 0, 0.9);
    color: white;
    text-align: center;
    z-index: 9999;
    animation: fadeIn 0.3s ease;
}

#overlayContent {
    position: absolute;
    top: 50%;
    left: 50%;
    transform: translate(-50%, -50%);
    background: rgba(0, 0, 0, 0.95);
    padding: 40px;
    border-radius: 12px;
    max-width: 400px;
    box-shadow: 0 20px 60px rgba(0, 0, 0, 0.3);
}

#overlayContent h3 {
    margin-bottom: 20px;
    font-size: 18px;
}

#percent {
    font-size: 36px;
    font-weight: 700;
    margin: 15px 0;
}

#progressContainer {
    width: 100%;
    background: #444;
    border-radius: 10px;
    overflow: hidden;
    margin: 20px 0;
    height: 28px;
}

#progressBar {
    width: 0%;
    height: 100%;
    background: linear-gradient(90deg, #667eea 0%, #764ba2 100%);
    transition: width 0.3s ease;
    display: flex;
    align-items: center;
    justify-content: center;
    color: white;
    font-size: 12px;
    font-weight: bold;
    border-radius: 10px;
}

#progressText {
    font-size: 13px;
    margin-top: 12px;
    opacity: 0.9;
}

@keyframes fadeIn {
    from { opacity: 0; }
    to { opacity: 1; }
}

/* ===== PRINT STYLES ===== */
@media print {
    body {
        background: white;
        padding: 0;
    }

    header {
        box-shadow: none;
        border-bottom: 2px solid #667eea;
    }

    .action-bar,
    .prefix-filter-section,
    .btn-delete,
    td.action {
        display: none;
    }

    table {
        width: 100%;
        font-size: 12px;
    }

    th, td {
        padding: 8px;
        border: 1px solid #ddd;
    }

    tbody tr:hover {
        background: white;
    }

    .badge {
        padding: 3px 6px;
        font-size: 10px;
    }

    @page {
        margin: 0.5cm;
        size: A4 landscape;
    }
}

/* ===== RESPONSIVE ===== */
@media (max-width: 1024px) {
    header {
        flex-direction: column;
        align-items: flex-start;
    }

    .header-stats {
        width: 100%;
        justify-content: space-around;
    }

    th, td {
        padding: 12px;
        font-size: 13px;
    }
}

/* ===== RESPONSIVE TABLE ===== */
@media (max-width: 768px) {
    /* Container tabel dengan scroll horizontal */
    .table-responsive {
        overflow-x: auto;
        -webkit-overflow-scrolling: touch;
        overflow-y: visible;
    }

    /* Tabel tetap full width, tapi ada scroll */
    table {
        min-width: 800px;  /* ← PENTING: Minimum width untuk semua kolom */
        width: 100%;
    }

    thead {
        position: sticky;
        top: 0;
        z-index: 10;
    }

    th, td {
        padding: 12px 10px;
        font-size: 13px;
        white-space: nowrap;  /* ← Cegah text wrapping */
    }

    /* Tetap tampilkan semua kolom tanpa hidden */
    td.no-urut {
        width: 45px;
        min-width: 45px;
        text-align: center;
    }

    td.prefix-jumlah {
        width: 100px;
        min-width: 100px;
    }

    .prefix-jumlah-wrapper {
        flex-direction: row;  /* ← Horizontal, bukan column */
        gap: 8px;
        justify-content: center;
        cursor: pointer;  /* ← TAMBAH: Tunjukkan clickable */
    }

    .prefix-badge {
        padding: 6px 10px;
        font-size: 12px;
        min-width: 40px;
        cursor: pointer;  /* ← TAMBAH: Clickable indicator */
        transition: all 0.2s ease;
    }

    .prefix-badge:active {  /* ← TAMBAH: Click feedback */
        transform: scale(0.95);
    }

    .jumlah-badge {
        padding: 5px 8px;
        font-size: 11px;
        min-width: 32px;
        cursor: pointer;  /* ← TAMBAH: Clickable indicator */
        transition: all 0.2s ease;
    }

    .jumlah-badge:active {  /* ← TAMBAH: Click feedback */
        transform: scale(0.95);
    }

    td.comment {
        width: 200px;
        min-width: 200px;
        font-family: 'Courier New', monospace;
        font-size: 12px;
        word-break: break-word;
        cursor: pointer;  /* ← TAMBAH: Clickable area */
    }

    /* JANGAN HIDDEN, tetap tampil */
    td.profile {
        width: 120px;
        min-width: 120px;
        display: table-cell;  /* ← Tetap visible */
        font-size: 12px;
    }

    td.status-badge {
        width: 80px;
        min-width: 80px;
        text-align: center;
    }

    .badge {
        padding: 6px 10px;
        font-size: 11px;
    }

    td.action {
        width: 90px;
        min-width: 90px;
        text-align: center;
        padding: 8px 4px;  /* ← Kurangi padding biar button fit */
    }

    .btn-delete {
        padding: 8px 10px;  /* ← Sesuaikan padding */
        font-size: 12px;
        gap: 4px;
        cursor: pointer;  /* ← TETAP: Clickable */
        transition: all 0.2s ease;
    }

    .btn-delete:active {  /* ← TAMBAH: Click feedback */
        transform: scale(0.95);
    }

    /* Header */
    header {
        padding: 15px;
    }

    .header-info h1 {
        font-size: 24px;
    }

    /* Action bar */
    .action-bar {
        flex-direction: column;
    }

    .btn {
        width: 100%;
        justify-content: center;
        padding: 12px 15px;
        cursor: pointer;  /* ← TETAP: Clickable */
    }

    /* Prefix filter */
    .prefix-filter-section {
        overflow-x: auto;
        -webkit-overflow-scrolling: touch;
    }

    .prefix-buttons {
        flex-wrap: nowrap;
        gap: 8px;
        overflow-x: auto;
        -webkit-overflow-scrolling: touch;
        padding-bottom: 8px;
    }

    .prefix-btn {
        flex-shrink: 0;
        white-space: nowrap;
        cursor: pointer;  /* ← TETAP: Clickable */
        transition: all 0.2s ease;
    }

    .prefix-btn:active {  /* ← TAMBAH: Click feedback */
        transform: scale(0.98);
    }
}

/* ===== MOBILE KECIL (480px) ===== */
@media (max-width: 480px) {
    .table-responsive {
        overflow-x: auto;
        -webkit-overflow-scrolling: touch;
    }

    table {
        min-width: 750px;  /* ← Lebih kecil di HP ultra small */
    }

    th, td {
        padding: 10px 8px;
        font-size: 12px;
        text-align:center;
    }

th[data-label="No"] {
    width: 10px; /* Atur angka sesuai kebutuhan */
    min-width: 10px; /* Agar tidak terhimpit */
}

    td.no-urut {
        width: 10px;
        min-width: 10px;
    }

    td.prefix-jumlah {
        width: 90px;
        min-width: 90px;
    }

    .prefix-jumlah-wrapper {
        cursor: pointer;  /* ← TAMBAH */
    }

    .prefix-badge {
        padding: 5px 8px;
        font-size: 11px;
        min-width: 35px;
        cursor: pointer;  /* ← TAMBAH */
        transition: all 0.2s ease;
    }

    .prefix-badge:active {  /* ← TAMBAH */
        transform: scale(0.95);
    }

    .jumlah-badge {
        padding: 4px 6px;
        font-size: 10px;
        min-width: 30px;
        cursor: pointer;  /* ← TAMBAH */
        transition: all 0.2s ease;
    }

    .jumlah-badge:active {  /* ← TAMBAH */
        transform: scale(0.95);
    }

    td.comment {
        width: 180px;
        min-width: 180px;
        font-size: 11px;
        text-align:left;
        cursor: pointer;  /* ← TAMBAH */
    }

    td.profile {
        width: 100px;
        min-width: 100px;
        font-size: 11px;
        text-align:center;
    }

    td.status-badge {
        width: 75px;
        min-width: 75px;
    }

    .badge {
        padding: 5px 8px;
        font-size: 10px;
    }

    td.action {
        width: 75px;
        min-width: 75px;
        padding: 6px 2px;  /* ← Kurangi padding */
    }

    .btn-delete {
        padding: 6px 8px;  /* ← Lebih kecil */
        font-size: 11px;
        gap: 3px;
        cursor: pointer;  /* ← TETAP */
        transition: all 0.2s ease;
    }

    .btn-delete:active {  /* ← TAMBAH */
        transform: scale(0.95);
    }

    header {
        padding: 12px;
    }

    .header-info h1 {
        font-size: 20px;
    }
}

/* ===== ULTRA KECIL (360px) ===== */
@media (max-width: 360px) {
    table {
        min-width: 700px;
    }

    th, td {
        padding: 8px 6px;
        font-size: 11px;
    }

    .prefix-badge {
        padding: 4px 6px;
        font-size: 10px;
        cursor: pointer;  /* ← TAMBAH */
        transition: all 0.2s ease;
    }

    .prefix-badge:active {  /* ← TAMBAH */
        transform: scale(0.95);
    }

    .jumlah-badge {
        padding: 3px 5px;
        font-size: 9px;
        cursor: pointer;  /* ← TAMBAH */
        transition: all 0.2s ease;
    }

    .jumlah-badge:active {  /* ← TAMBAH */
        transform: scale(0.95);
    }

    td.comment {
        width: 160px;
        min-width: 160px;
        font-size: 10px;
        cursor: pointer;  /* ← TAMBAH */
    }

    td.profile {
        width: 90px;
        min-width: 90px;
        font-size: 10px;
    }

    td.action {
        width: 70px;
        min-width: 70px;
        padding: 4px 0;  /* ← Minimal padding */
    }

    .btn-delete {
        padding: 4px 6px;
        font-size: 10px;
        gap: 2px;
        cursor: pointer;  /* ← TETAP */
        transition: all 0.2s ease;
    }

    .btn-delete:active {  /* ← TAMBAH */
        transform: scale(0.95);
    }
}
    </style>
</head>
<body>

<header>
    <div class="header-left">
        <div class="header-logo">📊</div>
        <div class="header-info">
            <h1>Monitoring VCR</h1>
            <p>Comment Management System</p>
        </div>
    </div>
    <div class="header-stats">
        <div class="stat-item">
            <div class="stat-number"><?= $totalActive ?></div>
            <div class="stat-label">Aktif</div>
        </div>
        <div class="stat-item">
            <div class="stat-number"><?= $totalExpired ?></div>
            <div class="stat-label">Expired</div>
        </div>
        <div class="stat-item">
            <div class="stat-number"><?= count($prefixList) ?></div>
            <div class="stat-label">Prefix</div>
        </div>
    </div>
</header>

<main>
    <div class="action-bar">
        <div class="btn-group">
            <a href="index.php" class="btn btn-primary">
                <i class="fas fa-arrow-left"></i> Kembali
            </a>
            <a href="?reload=1" class="btn btn-success">
                <i class="fas fa-sync-alt"></i> Refresh
            </a>
            <a href="comment_all.php" class="btn btn-info">
                <i class="fas fa-list"></i> All Comment
            </a>
            <button class="btn btn-print" onclick="printTable()">
                <i class="fas fa-print"></i> Print
            </button>
        </div>
    </div>

    <?php if ($errorMsg): ?>
    <div class="alert alert-error">
        <i class="fas fa-exclamation-circle"></i> <?= htmlspecialchars($errorMsg) ?>
    </div>
    <?php endif; ?>

    <!-- PREFIX FILTER SECTION -->
    <?php if (!empty($prefixList)): ?>
    <div class="prefix-filter-section">
        <div class="filter-label">
            <i class="fas fa-filter"></i> Filter Prefix
        </div>
        <div class="prefix-buttons">
            <?php foreach ($prefixList as $p): ?>
                <?php $isActive = ($p === $prefixFilter) ? 'active' : ''; ?>
                <a href="?prefix=<?= urlencode($p) ?>" class="prefix-btn <?= $isActive ?>">
                    <?= htmlspecialchars($p) ?>
                </a>
            <?php endforeach; ?>
            <?php if (!empty($prefixFilter)): ?>
                <a href="?" class="prefix-btn prefix-btn-clear">
                    <i class="fas fa-times"></i> Clear
                </a>
            <?php endif; ?>
        </div>
    </div>
    <?php endif; ?>

    <!-- TABLE -->
    <div class="table-responsive">
        <table id="commentTable">
            <thead>
                <tr>
                    <th data-label="No">No</th>
                    <th data-label="Pfx/Jum" onclick="sortTable(1)" style="width:90px;">Pfx/Jum</th>
                    <th data-label="Comm" onclick="sortTable(2)" style="flex:1;">Comment</th>
                    <th data-label="Prof" onclick="sortTable(3)" style="width:120px;">Profile</th>
                    <th data-label="Sts" style="width:80px;">Status</th>
                    <th data-label="Aksi" style="width:90px;">Aksi</th>
                </tr>
            </thead>
            <tbody id="commentTbody">
                <?php $no = 1;
                if (!empty($displayData)) {
                    foreach ($displayData as $item):
                        $dataComment = htmlspecialchars($item['user']['comment'] ?? '', ENT_QUOTES | ENT_SUBSTITUTE, 'UTF-8');
                        $jumlah = (int)($item['jumlah'] ?? 0);
                        $profile = htmlspecialchars($item['user']['profile'] ?? '', ENT_QUOTES | ENT_SUBSTITUTE, 'UTF-8');
                        $status = htmlspecialchars($item['status'] ?? 'active', ENT_QUOTES | ENT_SUBSTITUTE, 'UTF-8');
                        $prefix = htmlspecialchars($item['prefix'] ?? '-', ENT_QUOTES | ENT_SUBSTITUTE, 'UTF-8');
                        $rowClass = ($status === 'expired') ? 'expired' : '';
                ?>
                <tr data-comment="<?= $dataComment ?>" class="<?= $rowClass ?>" data-status="<?= $status ?>" data-prefix="<?= $prefix ?>" data-jumlah="<?= $jumlah ?>">
                    <td class="no-urut"><?= $no++ ?></td>
                    <td class="prefix-jumlah">
                        <div class="prefix-jumlah-wrapper">
                            <span class="prefix-badge" data-prefix="<?= $prefix ?>" onclick="filterByPrefix(event)" title="Klik untuk filter">
                                <?= $prefix ?>
                            </span>
                            <span class="jumlah-badge" onclick="filterByJumlah(event)" title="Lihat jumlah user">
                                <?= $jumlah ?>
                            </span>
                        </div>
                    </td>
                    <td class="comment" title="<?= $dataComment ?>"><?= $dataComment ?></td>
                    <td class="profile"><?= $profile ?></td>
                    <td class="status-badge">
                        <span class="badge badge-<?= $status ?>">
                            <?= $status === 'expired' ? '⏱️' : '✓' ?>
                        </span>
                    </td>
                    <td class="action">
                        <button class="btn-delete <?= $status === 'expired' ? 'btn-expired' : '' ?>" 
                                onclick="deleteComment(this)" 
                                title="<?= $status === 'expired' ? 'Hapus dari riwayat' : 'Hapus semua user' ?>">
                            <i class="fas fa-trash"></i>
                        </button>
                    </td>
                </tr>
                <?php endforeach;
                } else {
                    echo '<tr><td colspan="6" style="text-align:center;padding:40px;"><div class="empty-state"><div class="empty-state-icon">📭</div><p>Tidak ada data voucher</p></div></td></tr>';
                }
                ?>
            </tbody>
        </table>
    </div>

</main>

<div id="overlay">
    <div id="overlayContent">
        <h3><i class="fas fa-hourglass-half"></i> Sedang memproses...</h3>
        <div id="percent">0%</div>
        <div id="progressContainer">
            <div id="progressBar"></div>
        </div>
        <p id="progressText" style="font-size:13px; margin-top:10px;">Menghapus user...</p>
    </div>
</div>

<script>
// Helper: update nomor urut setelah hapus
function renumberRows(){
    const rows = document.querySelectorAll('#commentTbody tr');
    rows.forEach((r, i) => {
        const noCell = r.querySelector('.no-urut');
        if(noCell) noCell.textContent = i + 1;
    });
}

// Filter by prefix
function filterByPrefix(event) {
    event.stopPropagation();
    const prefix = event.target.getAttribute('data-prefix');
    const url = new URL(window.location);
    
    if (url.searchParams.get('prefix') === prefix) {
        url.searchParams.delete('prefix');
    } else {
        url.searchParams.set('prefix', prefix);
    }
    window.location.href = url.toString();
}

// Filter by jumlah (opsional)
function filterByJumlah(event) {
    event.stopPropagation();
    // Bisa dikembangkan untuk fitur filter jumlah di masa depan
}

// FUNGSI PRINT
function printTable() {
    const printWindow = window.open('', '', 'width=1200,height=800');
    const table = document.getElementById('commentTable');
    const style = `
        <style>
            * {
                margin: 0;
                padding: 0;
                box-sizing: border-box;
            }
            body {
                font-family: 'Segoe UI', Arial, sans-serif;
                padding: 20px;
                background: white;
            }
            h2 {
                text-align: center;
                margin-bottom: 20px;
                color: #333;
                font-size: 24px;
            }
            .print-info {
                text-align: right;
                margin-bottom: 15px;
                font-size: 12px;
                color: #666;
            }
            table {
                width: 100%;
                border-collapse: collapse;
                margin-top: 10px;
            }
            th {
                background: #667eea;
                color: white;
                padding: 12px;
                text-align: left;
                font-weight: 700;
                border: 1px solid #ddd;
                font-size: 13px;
            }
            td {
                padding: 10px 12px;
                border: 1px solid #ddd;
                font-size: 12px;
            }
            tr:nth-child(even) {
                background: #f9f9f9;
            }
            .badge {
                display: inline-block;
                padding: 3px 8px;
                border-radius: 4px;
                font-weight: 600;
                font-size: 11px;
            }
            .badge-active {
                background: #d4edda;
                color: #155724;
            }
            .badge-expired {
                background: #f8d7da;
                color: #721c24;
            }
            .page-break {
                page-break-after: always;
            }
        </style>
    `;
    
    let html = style + '<h2>📊 Laporan MONSEL</h2>';
    html += '<div class="print-info">Tanggal: ' + new Date().toLocaleString('id-ID') + '</div>';
    html += '<table>';
    html += '<thead><tr>';
    html += '<th style="width:40px;">No</th>';
    html += '<th style="width:70px;">Prefix</th>';
    html += '<th style="flex:1;">Comment</th>';
    html += '<th style="width:100px;">Profile</th>';
    html += '<th style="width:70px;">Jumlah</th>';
    html += '<th style="width:70px;">Status</th>';
    html += '</tr></thead>';
    html += '<tbody>';
    
    const rows = document.querySelectorAll('#commentTbody tr');
    let no = 1;
    rows.forEach(row => {
        if(row.textContent.includes('Tidak ada data')) return;
        
        const cells = row.querySelectorAll('td');
        const prefix = cells[1].querySelector('.prefix-badge')?.textContent || '-';
        const jumlah = cells[1].querySelector('.jumlah-badge')?.textContent || '0';
        const comment = cells[2].textContent;
        const profile = cells[3].textContent;
        const status = cells[4].querySelector('.badge')?.textContent || '-';
        const statusClass = cells[4].querySelector('.badge')?.classList[1] || 'badge-active';
        
        html += '<tr>';
        html += '<td>' + no + '</td>';
        html += '<td>' + prefix + '</td>';
        html += '<td><strong>' + comment + '</strong></td>';
        html += '<td>' + profile + '</td>';
        html += '<td style="text-align:center;">' + jumlah + '</td>';
        html += '<td style="text-align:center;"><span class="badge ' + statusClass + '">' + status + '</span></td>';
        html += '</tr>';
        no++;
    });
    
    html += '</tbody></table>';
    
    printWindow.document.write(html);
    printWindow.document.close();
    printWindow.focus();
    
    // Delay untuk memastikan document selesai loading
    setTimeout(() => {
        printWindow.print();
    }, 250);
}

function deleteComment(btn){
    const row = btn.closest('tr');
    if(!row) return;
    
    const comment = row.getAttribute('data-comment') || row.querySelector('.comment').innerText.trim();
    const status = row.getAttribute('data-status') || 'active';
    
    const confirmMsg = status === 'expired' 
        ? `Hapus "${comment}" dari riwayat?` 
        : `Hapus semua user dengan comment "${comment}"?`;
    
    if(!confirm(confirmMsg)) return;

    // Disable button saat proses
    btn.disabled = true;

    // Tampilkan overlay
    document.getElementById('overlay').style.display = 'block';
    document.getElementById('percent').innerText = '0%';
    document.getElementById('progressBar').style.width = '0%';
    
    if (status === 'expired') {
        document.getElementById('progressText').innerText = 'Menghapus dari riwayat...';
    } else {
        document.getElementById('progressText').innerText = 'Menghapus user dari Mikrotik...';
    }

    const progressUrl = 'cache/progress_<?= $mikrotikIp ?>.json?rand=' + Math.random();

    // Untuk expired, langsung hapus tanpa polling
    if (status === 'expired') {
        fetch('delete_expired_comment.php?comment=' + encodeURIComponent(comment))
        .then(r => r.json())
        .then(data => {
            if(!data.success){
                alert('Gagal hapus: ' + (data.error || 'unknown error'));
                document.getElementById('overlay').style.display = 'none';
                btn.disabled = false;
                return;
            }
            // Langsung hapus row
            document.getElementById('percent').innerText = '100%';
            document.getElementById('progressBar').style.width = '100%';
            setTimeout(() => {
                if(row) row.remove();
                renumberRows();
                document.getElementById('overlay').style.display = 'none';
                btn.disabled = false;
            }, 500);
        })
        .catch(err => {
            alert('Error: ' + err.message);
            document.getElementById('overlay').style.display = 'none';
            btn.disabled = false;
        });
        return;
    }

    // Untuk active, gunakan polling seperti sebelumnya
    let polling = true;
    const interval = setInterval(() => {
        fetch(progressUrl).then(r => {
            if(!r.ok) throw new Error('no-progress');
            return r.json();
        }).then(p => {
            const pct = parseInt(p.percent) || 0;
            document.getElementById('percent').innerText = pct + '%';
            document.getElementById('progressBar').style.width = pct + '%';
            if(pct >= 100){
                clearInterval(interval);
                polling = false;
                setTimeout(() => {
                    if(row) row.remove();
                    renumberRows();
                    document.getElementById('overlay').style.display = 'none';
                    btn.disabled = false;
                }, 500);
            }
        }).catch(e => {
            // Progress file belum tersedia
        });
    }, 350);

    // Kirim request hapus ke server
    fetch('delete_comment.php?comment=' + encodeURIComponent(comment))
    .then(r => r.json())
    .then(data => {
        if(!data.success){
            clearInterval(interval);
            alert('Gagal hapus user: ' + (data.error || 'unknown error'));
            document.getElementById('overlay').style.display = 'none';
            btn.disabled = false;
            return;
        }
        if(polling){
            clearInterval(interval);
            document.getElementById('percent').innerText = '100%';
            document.getElementById('progressBar').style.width = '100%';
            setTimeout(() => {
                if(row) row.remove();
                renumberRows();
                document.getElementById('overlay').style.display = 'none';
                btn.disabled = false;
            }, 500);
        }
    })
    .catch(err => {
        clearInterval(interval);
        alert('Terjadi error komunikasi dengan server');
        document.getElementById('overlay').style.display = 'none';
        btn.disabled = false;
    });
}

// Fungsi sortir aman dengan kolom yang benar (sekarang kolom 1 adalah Pfx/Jum)
function sortTable(colIndex) {
    const tbody = document.getElementById("commentTbody");
    const rows = Array.from(tbody.querySelectorAll("tr"));

    const currentSort = tbody.getAttribute("data-sortcol");
    const currentDir  = tbody.getAttribute("data-sortdir");

    let asc = !(currentSort == colIndex && currentDir == "asc");

    rows.sort((a, b) => {
        let valA = "";
        let valB = "";

        // 🔹 Pfx/Jum → ambil PREFIX
        if (colIndex === 1) {
            valA = a.querySelector('.prefix-badge')?.textContent.trim() || "";
            valB = b.querySelector('.prefix-badge')?.textContent.trim() || "";
        }

        // 🔹 Comm → sort berdasarkan TANGGAL di dalam string
        else if (colIndex === 2) {
            const getDate = (str) => {
                const match = str.match(/(\d{2})\.(\d{2})\.(\d{2})/);
                if (!match) return 0;

                const day = match[1];
                const month = match[2];
                const year = '20' + match[3];

                return new Date(`${year}-${month}-${day}`).getTime();
            };

            valA = getDate(a.cells[colIndex]?.innerText.trim() || "");
            valB = getDate(b.cells[colIndex]?.innerText.trim() || "");
        }

        // 🔹 Prof & lainnya → text biasa
        else {
            valA = a.cells[colIndex]?.innerText.trim() || "";
            valB = b.cells[colIndex]?.innerText.trim() || "";
        }

        // 🔥 Sorting final (AMAN)
        if (valA < valB) return asc ? -1 : 1;
        if (valA > valB) return asc ? 1 : -1;
        return 0;
    });

    rows.forEach(r => tbody.appendChild(r));

    tbody.setAttribute("data-sortcol", colIndex);
    tbody.setAttribute("data-sortdir", asc ? "asc" : "desc");

    updateSortIcons(colIndex, asc);
    renumberRows();
}

function updateSortIcons(colIndex, asc){
    document.querySelectorAll("thead th").forEach((th,i)=>{
        if(i === colIndex){
            th.innerText = th.getAttribute("data-label") + (asc ? " ▲" : " ▼");
        } else {
            th.innerText = th.getAttribute("data-label");
        }
    });
}
</script>

</body>
</html>