<?php
// ==========================================================
// DASHBOARD.PHP (INDEX) - V20.4 ADD_TIME PAUSED FIX
// Fix: saat paused tambah waktu, timer di dashboard tidak ikut naik
// ==========================================================

include 'config.php';
checkLogin(); 
$page_title = "Command Center";
$active_page = "dashboard";
include 'layout.php';

$adb_list = getADBList();

$default_rate = get_setting($conn, 'default_open_bill_rate') ?: "10000";
$min_charge   = get_setting($conn, 'min_open_bill') ?: "3000";
$round_val    = get_setting($conn, 'round_open_bill') ?: "500";

$tvs = mysqli_query($conn, "SELECT * FROM tvs ORDER BY nama_tv ASC");

$pkgs = mysqli_query($conn, "SELECT * FROM packages ORDER BY durasi_menit ASC");
$pkg_options = "";
while($p = mysqli_fetch_assoc($pkgs)) {
    $pkg_options .= "<option value='".htmlspecialchars($p['id'])."'>".htmlspecialchars($p['nama_paket'])." (Rp ".number_format($p['harga']).")</option>";
}

$members_q = mysqli_query($conn, "SELECT id, nama_member, saldo FROM members ORDER BY nama_member ASC");
$member_options = "<option value=''>-- Tamu Regular (Cash) --</option>";
while($m = mysqli_fetch_assoc($members_q)) {
    $member_options .= "<option value='".htmlspecialchars($m['id'])."'>".htmlspecialchars($m['nama_member'])." [Rp ".number_format($m['saldo'])."]</option>";
}

$sticks_data = [];
$sticks_query = mysqli_query($conn, "SELECT * FROM sticks WHERE status = 'available'");
while($stk = mysqli_fetch_assoc($sticks_query)) {
    $sticks_data[] = $stk;
}

$available_tvs = [];
$avail_tv_query = mysqli_query($conn, "SELECT id, nama_tv FROM tvs WHERE status = 'available' ORDER BY nama_tv ASC");
while($avt = mysqli_fetch_assoc($avail_tv_query)) {
    $available_tvs[] = $avt;
}
?>

<link href="https://fonts.googleapis.com/css2?family=Orbitron:wght@400;500;600;700;800;900&family=Plus+Jakarta+Sans:wght@400;500;600;700;800&family=JetBrains+Mono:wght@400;500;600;700&display=swap" rel="stylesheet">
<link href='https://unpkg.com/boxicons@2.1.4/css/boxicons.min.css' rel='stylesheet'>

<style>
    :root {
        --bg-dark: #030712;
        --bg-gradient: linear-gradient(135deg, #030712 0%, #0c1929 50%, #0a192f 100%);
        --card-bg: rgba(15, 23, 42, 0.6);
        --card-border: rgba(6, 182, 212, 0.15);
        --primary: #06b6d4;
        --primary-light: #22d3ee;
        --primary-dark: #0891b2;
        --primary-glow: rgba(6, 182, 212, 0.6);
        --success: #10b981;
        --success-glow: rgba(16, 185, 129, 0.5);
        --warning: #f59e0b;
        --warning-glow: rgba(245, 158, 11, 0.5);
        --danger: #ef4444;
        --danger-glow: rgba(239, 68, 68, 0.5);
        --text-main: #f1f5f9;
        --text-dim: #64748b;
        --glass-bg: rgba(255, 255, 255, 0.03);
        --glass-border: rgba(255, 255, 255, 0.08);
    }

    * { box-sizing: border-box; }
    body { font-family: 'Plus Jakarta Sans', sans-serif; background: var(--bg-dark); color: var(--text-main); min-height: 100vh; position: relative; overflow-x: hidden; }

    .animated-bg { position: fixed; top: 0; left: 0; width: 100%; height: 100%; z-index: -1; overflow: hidden; background: var(--bg-gradient); pointer-events: none; }
    .floating-orb { position: absolute; border-radius: 50%; filter: blur(80px); opacity: 0.4; animation: floatOrb 20s ease-in-out infinite; pointer-events: none; }
    .orb-1 { width: 600px; height: 600px; background: radial-gradient(circle, var(--primary) 0%, transparent 70%); top: -200px; right: -200px; animation-delay: 0s; }
    .orb-2 { width: 500px; height: 500px; background: radial-gradient(circle, #8b5cf6 0%, transparent 70%); bottom: -150px; left: -150px; animation-delay: -7s; }
    .orb-3 { width: 400px; height: 400px; background: radial-gradient(circle, var(--success) 0%, transparent 70%); top: 50%; left: 50%; transform: translate(-50%, -50%); animation-delay: -14s; }
    @keyframes floatOrb { 0%, 100% { transform: translate(0,0) scale(1); } 25% { transform: translate(50px,-50px) scale(1.1); } 50% { transform: translate(-30px,30px) scale(0.95); } 75% { transform: translate(-50px,-30px) scale(1.05); } }

    .grid-overlay { position: absolute; top: 0; left: 0; width: 100%; height: 100%; background-image: linear-gradient(rgba(6,182,212,0.03) 1px, transparent 1px), linear-gradient(90deg, rgba(6,182,212,0.03) 1px, transparent 1px); background-size: 50px 50px; animation: gridMove 30s linear infinite; pointer-events: none; }
    @keyframes gridMove { 0% { transform: translate(0,0); } 100% { transform: translate(50px,50px); } }

    .particles { position: absolute; width: 100%; height: 100%; pointer-events: none; }
    .particle { position: absolute; width: 4px; height: 4px; background: var(--primary); border-radius: 50%; opacity: 0; animation: particleFloat 8s ease-in-out infinite; pointer-events: none; }
    @keyframes particleFloat { 0% { opacity: 0; transform: translateY(100vh) scale(0); } 10% { opacity: 0.8; } 90% { opacity: 0.8; } 100% { opacity: 0; transform: translateY(-20px) scale(1); } }

    .grid-units { display: grid; grid-template-columns: repeat(auto-fill, minmax(340px, 1fr)); gap: 25px; padding: 20px 30px 30px; position: relative; z-index: 1; }

    .unit-card { background: var(--card-bg); backdrop-filter: blur(20px); -webkit-backdrop-filter: blur(20px); border: 1px solid var(--card-border); border-radius: 24px; padding: 25px; position: relative; overflow: hidden; transition: all 0.4s cubic-bezier(0.4,0,0.2,1); }
    .unit-card::before { content: ''; position: absolute; top: 0; left: 0; right: 0; bottom: 0; border-radius: 24px; padding: 2px; background: linear-gradient(135deg, transparent, transparent); -webkit-mask: linear-gradient(#fff 0 0) content-box, linear-gradient(#fff 0 0); mask: linear-gradient(#fff 0 0) content-box, linear-gradient(#fff 0 0); -webkit-mask-composite: xor; mask-composite: exclude; opacity: 0; transition: all 0.4s ease; pointer-events: none; }
    .unit-card:hover::before { background: linear-gradient(135deg, var(--primary), var(--primary-light), #8b5cf6); opacity: 1; }
    .unit-card:hover { transform: translateY(-10px) scale(1.02); box-shadow: 0 25px 50px -12px rgba(0,0,0,0.5), 0 0 60px -15px var(--primary-glow); }
    .unit-card.active { border-color: rgba(16,185,129,0.3); }
    .unit-card.active::after { content: ''; position: absolute; top: 0; left: 0; right: 0; height: 3px; background: linear-gradient(90deg, var(--success), var(--primary)); border-radius: 24px 24px 0 0; pointer-events: none; }
    .unit-card.paused { border-color: rgba(245,158,11,0.3); }
    .unit-card.paused::after { content: ''; position: absolute; top: 0; left: 0; right: 0; height: 3px; background: linear-gradient(90deg, var(--warning), #fbbf24); border-radius: 24px 24px 0 0; pointer-events: none; }

    .card-header { display: flex; justify-content: space-between; align-items: flex-start; margin-bottom: 20px; }
    .tv-info { display: flex; align-items: center; gap: 12px; }
    .tv-icon { width: 48px; height: 48px; background: linear-gradient(135deg, var(--primary), var(--primary-dark)); border-radius: 14px; display: flex; align-items: center; justify-content: center; font-size: 1.4rem; color: #fff; box-shadow: 0 8px 20px -8px var(--primary-glow); animation: iconFloat 3s ease-in-out infinite; }
    @keyframes iconFloat { 0%, 100% { transform: translateY(0); } 50% { transform: translateY(-5px); } }
    .tv-title { font-family: 'Orbitron', sans-serif; font-size: 1.2rem; font-weight: 700; letter-spacing: 1px; margin-bottom: 4px; }

    .adb-status { font-size: 0.65rem; font-weight: 700; display: flex; align-items: center; gap: 5px; }
    .adb-status.online { color: var(--success); }
    .adb-status.offline { color: var(--danger); }
    .adb-dot { width: 8px; height: 8px; border-radius: 50%; animation: dotPulse 2s ease-in-out infinite; }
    .adb-status.online .adb-dot { background: var(--success); box-shadow: 0 0 10px var(--success-glow); }
    .adb-status.offline .adb-dot { background: var(--danger); box-shadow: 0 0 10px var(--danger-glow); }
    @keyframes dotPulse { 0%, 100% { transform: scale(1); opacity: 1; } 50% { transform: scale(1.3); opacity: 0.7; } }

    .status-pill { padding: 6px 14px; border-radius: 20px; font-size: 0.65rem; font-weight: 800; text-transform: uppercase; letter-spacing: 1px; display: flex; align-items: center; gap: 6px; }
    .unit-card.active .status-pill { color: var(--success); background: rgba(16,185,129,0.15); border: 1px solid rgba(16,185,129,0.3); box-shadow: 0 0 20px -5px var(--success-glow); }
    .unit-card.paused .status-pill { color: var(--warning); background: rgba(245,158,11,0.15); border: 1px solid rgba(245,158,11,0.3); box-shadow: 0 0 20px -5px var(--warning-glow); }
    .unit-card.available .status-pill { color: var(--text-dim); background: var(--glass-bg); border: 1px solid var(--glass-border); }
    .status-pill i { font-size: 0.8rem; }

    .timer-box { background: linear-gradient(180deg, rgba(0,0,0,0.4) 0%, rgba(0,0,0,0.2) 100%); border: 1px solid var(--glass-border); border-radius: 20px; padding: 30px 20px; text-align: center; margin-bottom: 20px; position: relative; overflow: hidden; }
    .timer-box::before { content: ''; position: absolute; top: -50%; left: -50%; width: 200%; height: 200%; background: conic-gradient(from 0deg, transparent 0deg, var(--primary-glow) 60deg, transparent 120deg); animation: timerRing 4s linear infinite; opacity: 0.3; pointer-events: none; }
    .unit-card.active .timer-box::before { background: conic-gradient(from 0deg, transparent 0deg, var(--success-glow) 60deg, transparent 120deg); }
    .unit-card.paused .timer-box::before { animation-play-state: paused; background: conic-gradient(from 0deg, transparent 0deg, var(--warning-glow) 60deg, transparent 120deg); }
    @keyframes timerRing { 0% { transform: rotate(0deg); } 100% { transform: rotate(360deg); } }
    .timer-box-inner { position: relative; z-index: 1; }

    .timer-digits { font-family: 'JetBrains Mono', monospace; font-size: 3.2rem; font-weight: 700; color: #fff; text-shadow: 0 0 20px var(--primary-glow), 0 0 40px var(--primary-glow), 0 0 60px rgba(6,182,212,0.3); letter-spacing: 4px; display: block; transition: all 0.3s ease; }
    .unit-card.active .timer-digits { text-shadow: 0 0 20px var(--success-glow), 0 0 40px var(--success-glow), 0 0 60px rgba(16,185,129,0.3); }
    .unit-card.paused .timer-digits { text-shadow: 0 0 20px var(--warning-glow), 0 0 40px var(--warning-glow), 0 0 60px rgba(245,158,11,0.3); }

    .billing-text { font-size: 0.75rem; color: var(--text-dim); font-weight: 700; margin-top: 12px; display: block; text-transform: uppercase; letter-spacing: 2px; }
    .billing-amount { color: var(--success); font-family: 'JetBrains Mono', monospace; font-size: 1rem; text-shadow: 0 0 10px var(--success-glow); }
    .time-expired { color: var(--danger) !important; animation: expiredPulse 1s ease-in-out infinite; text-shadow: 0 0 20px var(--danger-glow), 0 0 40px var(--danger-glow) !important; }
    @keyframes expiredPulse { 0%, 100% { opacity: 1; transform: scale(1); } 50% { opacity: 0.7; transform: scale(1.02); } }

    .info-grid { display: grid; grid-template-columns: 1fr 1fr; gap: 12px; margin-bottom: 20px; }
    .info-item { background: var(--glass-bg); padding: 14px; border-radius: 16px; border: 1px solid var(--glass-border); text-align: center; transition: all 0.3s ease; }
    .info-item:hover { background: rgba(6,182,212,0.1); border-color: var(--primary); transform: translateY(-2px); }
    .info-label { font-size: 0.6rem; color: var(--text-dim); text-transform: uppercase; font-weight: 800; margin-bottom: 6px; display: block; letter-spacing: 1px; }
    .info-value { font-size: 0.9rem; font-weight: 700; color: #fff; display: flex; align-items: center; justify-content: center; gap: 6px; }
    .info-value i { color: var(--primary); animation: iconBounce 2s ease-in-out infinite; }
    @keyframes iconBounce { 0%, 100% { transform: translateY(0); } 50% { transform: translateY(-3px); } }

    .tab-container { display: flex; gap: 8px; margin-bottom: 15px; background: rgba(0,0,0,0.3); padding: 6px; border-radius: 14px; position: relative; z-index: 5; }
    .tab-btn { flex: 1; background: transparent; border: none; color: var(--text-dim); padding: 10px; font-weight: 800; cursor: pointer; font-size: 0.7rem; border-radius: 10px; transition: all 0.3s ease; text-transform: uppercase; letter-spacing: 1px; position: relative; z-index: 5; }
    .tab-btn.active { background: linear-gradient(135deg, var(--primary), var(--primary-dark)); color: #000; box-shadow: 0 4px 15px -3px var(--primary-glow); }
    .tab-btn:hover:not(.active) { background: rgba(255,255,255,0.05); color: var(--text-main); }

    .stik-selector { position: relative; margin-bottom: 12px; z-index: 10; }
    .stik-trigger { background: rgba(0,0,0,0.3); border: 1px solid var(--glass-border); padding: 14px 16px; border-radius: 14px; font-size: 0.85rem; color: var(--text-dim); cursor: pointer; display: flex; align-items: center; gap: 10px; transition: all 0.3s ease; position: relative; z-index: 10; }
    .stik-trigger:hover { border-color: var(--primary); background: rgba(6,182,212,0.1); }
    .stik-trigger i { font-size: 1.2rem; color: var(--primary); animation: joystickWiggle 2s ease-in-out infinite; }
    @keyframes joystickWiggle { 0%, 100% { transform: rotate(0deg); } 25% { transform: rotate(-10deg); } 75% { transform: rotate(10deg); } }
    .stik-dropdown { position: absolute; top: calc(100% + 8px); left: 0; width: 100%; background: rgba(15,23,42,0.98); backdrop-filter: blur(20px); border: 1px solid var(--primary); border-radius: 16px; padding: 12px; z-index: 100; display: none; box-shadow: 0 20px 40px -10px rgba(0,0,0,0.5), 0 0 30px -10px var(--primary-glow); animation: dropdownSlide 0.3s ease; }
    @keyframes dropdownSlide { from { opacity: 0; transform: translateY(-10px); } to { opacity: 1; transform: translateY(0); } }
    .stik-selector.active .stik-dropdown { display: block; }
    .stik-item input { display: none; }
    .stik-item label { display: flex; align-items: center; gap: 12px; padding: 12px; border-radius: 12px; cursor: pointer; transition: all 0.2s ease; font-weight: 600; border: 1px solid transparent; }
    .stik-item label:hover { background: rgba(6,182,212,0.1); }
    .stik-item input:checked + label { background: rgba(6,182,212,0.2); color: var(--primary); border-color: var(--primary); }
    .stik-item label i { font-size: 1.3rem; }

    .modern-select { width: 100%; background: rgba(0,0,0,0.3); border: 1px solid var(--glass-border); padding: 14px 16px; border-radius: 14px; color: #fff; margin-bottom: 12px; outline: none; font-size: 0.9rem; transition: all 0.3s ease; cursor: pointer; position: relative; z-index: 5; -webkit-appearance: none; -moz-appearance: none; appearance: none; background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='12' viewBox='0 0 12 12'%3E%3Cpath fill='%2394a3b8' d='M6 8L1 3h10z'/%3E%3C/svg%3E"); background-repeat: no-repeat; background-position: right 15px center; }
    .modern-select:hover, .modern-select:focus { border-color: var(--primary); background: rgba(6,182,212,0.1); }
    .modern-select option { background: #1e293b; color: #fff; padding: 10px; }

    .btn-start { width: 100%; padding: 16px; border-radius: 16px; border: none; background: linear-gradient(135deg, var(--primary), var(--primary-dark)); color: #000; font-weight: 800; cursor: pointer; text-transform: uppercase; letter-spacing: 2px; font-size: 0.9rem; transition: all 0.3s ease; position: relative; overflow: hidden; z-index: 5; }
    .btn-start::before { content: ''; position: absolute; top: 0; left: -100%; width: 100%; height: 100%; background: linear-gradient(90deg, transparent, rgba(255,255,255,0.3), transparent); transition: left 0.5s ease; pointer-events: none; }
    .btn-start:hover::before { left: 100%; }
    .btn-start:hover { transform: translateY(-2px); box-shadow: 0 10px 30px -10px var(--primary-glow); }
    .btn-start.success { background: linear-gradient(135deg, var(--success), #059669); }
    .btn-start.success:hover { box-shadow: 0 10px 30px -10px var(--success-glow); }

    .action-grid { display: grid; grid-template-columns: 1fr 1fr; gap: 12px; position: relative; z-index: 5; }
    .btn-act { padding: 14px; border-radius: 14px; border: 1px solid var(--glass-border); background: var(--glass-bg); color: #fff; font-weight: 700; font-size: 0.8rem; cursor: pointer; display: flex; align-items: center; justify-content: center; gap: 8px; transition: all 0.3s ease; text-decoration: none; position: relative; overflow: hidden; z-index: 5; }
    .btn-act::before { content: ''; position: absolute; top: 50%; left: 50%; width: 0; height: 0; background: rgba(6,182,212,0.3); border-radius: 50%; transform: translate(-50%,-50%); transition: width 0.5s ease, height 0.5s ease; pointer-events: none; }
    .btn-act:hover::before { width: 300px; height: 300px; }
    .btn-act:hover { border-color: var(--primary); transform: translateY(-3px); box-shadow: 0 10px 20px -10px var(--primary-glow); }
    .btn-act i { font-size: 1.1rem; position: relative; z-index: 1; transition: transform 0.3s ease; }
    .btn-act span { position: relative; z-index: 1; }
    .btn-act:hover i { transform: scale(1.2); }
    .btn-act.stop { background: rgba(239,68,68,0.1); border-color: rgba(239,68,68,0.3); color: var(--danger); }
    .btn-act.stop::before { background: rgba(239,68,68,0.3); }
    .btn-act.stop:hover { background: var(--danger); color: #fff; box-shadow: 0 10px 20px -10px var(--danger-glow); }
    .btn-act.addtime { background: rgba(6,182,212,0.1); border-color: rgba(6,182,212,0.3); color: var(--primary); }
    .btn-act.addtime::before { background: rgba(6,182,212,0.3); }
    .btn-act.addtime:hover { background: var(--primary); color: #000; box-shadow: 0 10px 20px -10px var(--primary-glow); }

    .remote-dock { margin-top: 20px; display: flex; justify-content: center; gap: 12px; border-top: 1px solid var(--glass-border); padding-top: 20px; position: relative; z-index: 5; }
    .remote-btn { width: 46px; height: 46px; border-radius: 14px; background: var(--glass-bg); color: var(--text-dim); display: flex; align-items: center; justify-content: center; cursor: pointer; border: 1px solid var(--glass-border); transition: all 0.3s ease; font-size: 1.2rem; position: relative; z-index: 5; }
    .remote-btn.connect-btn { background: rgba(16,185,129,0.1); border-color: rgba(16,185,129,0.3); color: var(--success); }
    .remote-btn.connect-btn:hover { background: var(--success); color: #000; box-shadow: 0 0 20px var(--success-glow); }
    .remote-btn.connect-btn.connecting { animation: connectPulse 1s ease-in-out infinite; pointer-events: none; }
    .remote-btn.connect-btn.connecting i { animation: spin 1s linear infinite; }
    @keyframes connectPulse { 0%, 100% { box-shadow: 0 0 5px var(--success-glow); } 50% { box-shadow: 0 0 20px var(--success-glow); } }
    @keyframes spin { from { transform: rotate(0deg); } to { transform: rotate(360deg); } }
    .remote-btn:hover { background: linear-gradient(135deg, var(--primary), var(--primary-dark)); color: #000; border-color: var(--primary); transform: translateY(-3px) scale(1.1); box-shadow: 0 10px 20px -10px var(--primary-glow); }
    .remote-btn:active { transform: translateY(0) scale(0.95); }

    .modal-backdrop { position: fixed; top: 0; left: 0; width: 100%; height: 100%; background: rgba(0,0,0,0.85); backdrop-filter: blur(10px); display: none; align-items: center; justify-content: center; z-index: 9999; animation: modalFadeIn 0.3s ease; }
    @keyframes modalFadeIn { from { opacity: 0; } to { opacity: 1; } }
    .modal-content { background: linear-gradient(180deg, rgba(30,41,59,0.95) 0%, rgba(15,23,42,0.98) 100%); backdrop-filter: blur(20px); border-radius: 28px; padding: 30px; border: 1px solid var(--glass-border); width: 90%; max-width: 420px; position: relative; animation: modalSlideIn 0.4s cubic-bezier(0.4,0,0.2,1); }
    @keyframes modalSlideIn { from { opacity: 0; transform: scale(0.9) translateY(20px); } to { opacity: 1; transform: scale(1) translateY(0); } }
    .modal-content h3 { font-family: 'Orbitron', sans-serif; font-size: 1.2rem; margin: 0 0 20px; display: flex; align-items: center; gap: 12px; }
    .modal-content h3 i { font-size: 1.5rem; }

    .receipt-box { background: rgba(0,0,0,0.4); padding: 20px; border-radius: 20px; margin: 15px 0; border: 1px solid var(--glass-border); }
    .billing-item { display: flex; justify-content: space-between; padding: 10px 0; border-bottom: 1px dashed rgba(255,255,255,0.1); font-size: 0.9rem; }
    .total-row { display: flex; justify-content: space-between; padding-top: 15px; margin-top: 15px; border-top: 2px solid var(--primary); font-weight: 800; font-size: 1.2rem; color: var(--primary); }

    .hidden { display: none !important; }
    .no-stik-msg { color: var(--text-dim); font-size: 0.85rem; padding: 15px; text-align: center; }

    @keyframes slideIn { from { transform: translateX(100%); opacity: 0; } to { transform: translateX(0); opacity: 1; } }
    @keyframes slideOut { from { transform: translateX(0); opacity: 1; } to { transform: translateX(100%); opacity: 0; } }

    @media (max-width: 768px) {
        .grid-units { grid-template-columns: 1fr; padding: 15px; }
        .timer-digits { font-size: 2.5rem; }
    }

    ::-webkit-scrollbar { width: 8px; }
    ::-webkit-scrollbar-track { background: var(--bg-dark); }
    ::-webkit-scrollbar-thumb { background: var(--primary); border-radius: 4px; }
    ::-webkit-scrollbar-thumb:hover { background: var(--primary-light); }
</style>

<div class="animated-bg">
    <div class="grid-overlay"></div>
    <div class="floating-orb orb-1"></div>
    <div class="floating-orb orb-2"></div>
    <div class="floating-orb orb-3"></div>
    <div class="particles" id="particles"></div>
</div>

<div class="grid-units">
    <?php while($row = mysqli_fetch_assoc($tvs)): ?>
        <?php
        $tv = getTVData($conn, $row['id']);
        $status = $tv['status'];
        $status_adb = checkADBStatus($tv['ip_address'], $adb_list);

        $sisa_detik = 0; $elapsed = 0; $jenis_paket = 'fixed'; $fnb_total = 0; $is_expired = false;

        if ($status != 'available' && isset($tv['trx_data'])) {
            $trx_id_local = $tv['current_trx_id'];
            $jenis_paket  = $tv['trx_data']['jenis_paket'];

            $stmt_fnb = $conn->prepare("SELECT SUM(total_harga) as total FROM orders_fnb WHERE trx_id = ?");
            $stmt_fnb->bind_param("i", $trx_id_local); $stmt_fnb->execute();
            $fnb_res   = $stmt_fnb->get_result()->fetch_assoc(); $stmt_fnb->close();
            $fnb_total = (int)($fnb_res['total'] ?? 0);

            if ($jenis_paket == 'fixed') {
                $now              = time();
                $target_timestamp = strtotime($tv['trx_data']['target_selesai']);
                if ($status == 'active') {
                    $sisa_detik = $target_timestamp - $now;
                    $is_expired = ($sisa_detik <= 0);
                    $sisa_detik = max(0, $sisa_detik);
                } else {
                    $sisa_detik = max(0, (int)$tv['trx_data']['remaining_seconds']);
                }
            } else {
                if ($status == 'paused') {
                    $elapsed = max(0, (int)$tv['trx_data']['remaining_seconds']);
                } else {
                    $elapsed = max(0, time() - strtotime($tv['trx_data']['start_time']));
                }
            }
        }

        $tv_id_safe       = (int)$tv['id'];
        $tv_nama_safe     = htmlspecialchars($tv['nama_tv'], ENT_QUOTES, 'UTF-8');
        $player_name_safe = htmlspecialchars($tv['trx_data']['nama_member'] ?? "Tamu", ENT_QUOTES, 'UTF-8');

        $status_icon = 'bx-circle';
        if ($status == 'active') $status_icon = 'bx-play-circle';
        elseif ($status == 'paused') $status_icon = 'bx-pause-circle';
        ?>

        <div class="unit-card <?php echo htmlspecialchars($status); ?>" id="card-<?php echo $tv_id_safe; ?>">
            <div class="card-header">
                <div class="tv-info">
                    <div class="tv-icon"><i class='bx bx-tv'></i></div>
                    <div>
                        <div class="tv-title"><?php echo $tv_nama_safe; ?></div>
                        <div class="adb-status <?php echo $status_adb; ?>" id="adb-status-<?php echo $tv_id_safe; ?>">
                            <span class="adb-dot"></span>
                            <span class="adb-text">ADB <?php echo strtoupper($status_adb); ?></span>
                        </div>
                    </div>
                </div>
                <span class="status-pill" id="statuspill-<?php echo $tv_id_safe; ?>">
                    <i class='bx <?php echo $status_icon; ?>'></i>
                    <?php echo strtoupper($status); ?>
                </span>
            </div>

            <div class="timer-box">
                <div class="timer-box-inner">
                    <span class="timer-digits <?php echo $is_expired ? 'time-expired' : ''; ?>"
                        id="timer-<?php echo $tv_id_safe; ?>"
                        data-id="<?php echo $tv_id_safe; ?>"
                        data-status="<?php echo htmlspecialchars($status); ?>"
                        data-type="<?php echo htmlspecialchars($jenis_paket); ?>"
                        data-sisa="<?php echo (int)$sisa_detik; ?>"
                        data-expired="<?php echo $is_expired ? '1' : '0'; ?>"
                        data-elapsed="<?php echo (int)$elapsed; ?>"
                        data-rate="<?php echo (int)($tv['trx_data']['rate_per_jam'] ?? $default_rate); ?>"
                        data-min="<?php echo (int)$min_charge; ?>"
                        data-round="<?php echo (int)$round_val; ?>"
                        data-trx-id="<?php echo (int)($tv['current_trx_id'] ?? 0); ?>"><?php
                        if ($status == 'available') {
                            echo '00:00:00';
                        } elseif ($is_expired) {
                            echo 'WAKTU HABIS';
                        } elseif ($jenis_paket == 'fixed') {
                            printf("%02d:%02d:%02d", floor($sisa_detik/3600), floor(($sisa_detik%3600)/60), $sisa_detik%60);
                        } else {
                            printf("%02d:%02d:%02d", floor($elapsed/3600), floor(($elapsed%3600)/60), $elapsed%60);
                        }
                    ?></span>

                    <span class="billing-text">
                        <?php if ($status == 'available'): ?>
                            <i class='bx bx-game-controller bx-tada'></i> READY TO PLAY
                        <?php elseif ($jenis_paket == 'open'): ?>
                            BILLING: <span class="billing-amount" id="bill-<?php echo $tv_id_safe; ?>">Rp 0</span>
                        <?php else: ?>
                            <i class='bx bx-time-five'></i> REMAINING TIME
                        <?php endif; ?>
                    </span>
                </div>
            </div>

            <?php if ($status == 'available'): ?>
                <div class="tab-container">
                    <button class="tab-btn tab-btn-<?php echo $tv_id_safe; ?> active" onclick="switchTab(this, <?php echo $tv_id_safe; ?>, 'fixed')">
                        <i class='bx bx-package'></i> PAKET
                    </button>
                    <button class="tab-btn tab-btn-<?php echo $tv_id_safe; ?>" onclick="switchTab(this, <?php echo $tv_id_safe; ?>, 'open')">
                        <i class='bx bx-timer'></i> OPEN
                    </button>
                </div>

                <form id="form-fixed-<?php echo $tv_id_safe; ?>" action="process.php" method="POST">
                    <input type="hidden" name="action" value="start">
                    <input type="hidden" name="tv_id" value="<?php echo $tv_id_safe; ?>">
                    <div class="stik-selector">
                        <div class="stik-trigger" onclick="toggleStik(this)">
                            <i class='bx bx-joystick'></i><span>Pilih Stik...</span><i class='bx bx-chevron-down' style="margin-left:auto;"></i>
                        </div>
                        <div class="stik-dropdown">
                            <?php if (empty($sticks_data)): ?>
                                <div class="no-stik-msg"><i class='bx bx-info-circle'></i> Tidak ada stik tersedia</div>
                            <?php else: foreach($sticks_data as $stk): ?>
                                <div class="stik-item">
                                    <input type="checkbox" name="stik[]" value="<?= htmlspecialchars($stk['nama_stik']) ?>" id="stk_f_<?= $tv_id_safe ?>_<?= $stk['id'] ?>" onchange="updateStikText(this)">
                                    <label for="stk_f_<?= $tv_id_safe ?>_<?= $stk['id'] ?>"><i class='bx bxs-joystick'></i> <?= htmlspecialchars($stk['nama_stik']) ?></label>
                                </div>
                            <?php endforeach; endif; ?>
                        </div>
                    </div>
                    <select name="paket_id" class="modern-select" required><?php echo $pkg_options; ?></select>
                    <select name="member_id" class="modern-select"><?php echo $member_options; ?></select>
                    <button type="submit" class="btn-start"><i class='bx bx-play'></i> START SESSION</button>
                </form>

                <form id="form-open-<?php echo $tv_id_safe; ?>" action="process.php" method="POST" class="hidden">
                    <input type="hidden" name="action" value="start_bebas">
                    <input type="hidden" name="tv_id" value="<?php echo $tv_id_safe; ?>">
                    <div class="stik-selector">
                        <div class="stik-trigger" onclick="toggleStik(this)">
                            <i class='bx bx-joystick'></i><span>Pilih Stik...</span><i class='bx bx-chevron-down' style="margin-left:auto;"></i>
                        </div>
                        <div class="stik-dropdown">
                            <?php if (empty($sticks_data)): ?>
                                <div class="no-stik-msg"><i class='bx bx-info-circle'></i> Tidak ada stik tersedia</div>
                            <?php else: foreach($sticks_data as $stk): ?>
                                <div class="stik-item">
                                    <input type="checkbox" name="stik[]" value="<?= htmlspecialchars($stk['nama_stik']) ?>" id="stk_o_<?= $tv_id_safe ?>_<?= $stk['id'] ?>" onchange="updateStikText(this)">
                                    <label for="stk_o_<?= $tv_id_safe ?>_<?= $stk['id'] ?>"><i class='bx bxs-joystick'></i> <?= htmlspecialchars($stk['nama_stik']) ?></label>
                                </div>
                            <?php endforeach; endif; ?>
                        </div>
                    </div>
                    <input type="number" name="harga_per_jam" class="modern-select" value="<?php echo (int)$default_rate; ?>" min="0" placeholder="Rate per jam">
                    <select name="member_id" class="modern-select"><?php echo $member_options; ?></select>
                    <button type="submit" class="btn-start success"><i class='bx bx-timer'></i> START OPEN BILL</button>
                </form>

            <?php else: ?>
                <div class="info-grid">
                    <div class="info-item">
                        <span class="info-label">Player</span>
                        <div class="info-value"><i class='bx bx-user'></i> <?= $player_name_safe ?></div>
                    </div>
                    <div class="info-item">
                        <span class="info-label">FnB Order</span>
                        <div class="info-value" style="color:var(--primary)"><i class='bx bx-food-menu'></i> Rp <?= number_format($fnb_total) ?></div>
                    </div>
                </div>

                <div class="action-grid">
                    <button onclick="togglePause(<?= $tv_id_safe ?>, '<?= $status ?>')"
                            class="btn-act" id="pausebtn-<?= $tv_id_safe ?>">
                        <i class='bx bx-<?php echo $status == 'paused' ? 'play' : 'pause'; ?>'></i>
                        <span><?php echo $status == 'paused' ? 'Resume' : 'Pause'; ?></span>
                    </button>
                    <button onclick="openFnBModal(<?= $tv_id_safe ?>, '<?= $tv_nama_safe ?>')" class="btn-act">
                        <i class='bx bx-plus-circle'></i><span>FnB</span>
                    </button>
                    <?php if ($jenis_paket == 'fixed'): ?>
                    <button onclick="openAddTimeModal(<?= $tv_id_safe ?>, '<?= $tv_nama_safe ?>')" class="btn-act addtime">
                        <i class='bx bx-time-five'></i><span>+Waktu</span>
                    </button>
                    <?php endif; ?>
                    <button onclick="openMoveModal(<?= $tv_id_safe ?>)" class="btn-act">
                        <i class='bx bx-transfer'></i><span>Pindah</span>
                    </button>
                    <button onclick="openStopModal(<?= $tv_id_safe ?>, '<?= $tv_nama_safe ?>')" class="btn-act stop">
                        <i class='bx bx-stop-circle'></i><span>Stop</span>
                    </button>
                </div>
            <?php endif; ?>

            <div class="remote-dock">
                <button onclick="connectTV(event, <?= $tv_id_safe ?>, '<?= $tv_nama_safe ?>')" class="remote-btn connect-btn" id="connect-btn-<?= $tv_id_safe ?>" title="Connect ADB" data-ip="<?= htmlspecialchars($tv['ip_address']) ?>"><i class='bx bx-link'></i></button>
                <button onclick="remote(event, 'adb_power', <?= $tv_id_safe ?>)" class="remote-btn" title="Power"><i class='bx bx-power-off'></i></button>
                <button onclick="remote(event, 'adb_vol_down', <?= $tv_id_safe ?>)" class="remote-btn" title="Vol Down"><i class='bx bx-volume-low'></i></button>
                <button onclick="remote(event, 'adb_vol_up', <?= $tv_id_safe ?>)" class="remote-btn" title="Vol Up"><i class='bx bx-volume-full'></i></button>
                <button onclick="remote(event, 'adb_home', <?= $tv_id_safe ?>)" class="remote-btn" title="Home"><i class='bx bx-home-alt'></i></button>
            </div>
        </div>
    <?php endwhile; ?>
</div>

<!-- MODALS -->
<div id="modalStop" class="modal-backdrop">
    <div class="modal-content">
        <h3 style="color:var(--danger);"><i class='bx bxs-receipt'></i> Konfirmasi Billing</h3>
        <div id="billing_detail" class="receipt-box">Loading...</div>
        <div style="display:flex; gap:12px;">
            <button onclick="closeModal('modalStop')" class="btn-act" style="flex:1"><i class='bx bx-x'></i> Batal</button>
            <button id="confirm_stop_btn" onclick="confirmStop()" class="btn-start success" style="flex:1.5; display:flex; align-items:center; justify-content:center; gap:8px;">
                <i class='bx bx-check'></i> BAYAR & STOP
            </button>
        </div>
    </div>
</div>

<div id="modalFnB" class="modal-backdrop">
    <div class="modal-content">
        <h3 id="fnb_title" style="color:var(--primary);"><i class='bx bx-food-menu'></i> Order FnB</h3>
        <form action="process.php" method="POST" style="margin-top:20px;">
            <input type="hidden" name="action" value="order_fnb">
            <input type="hidden" name="tv_id" id="fnb_tv_id">
            <select name="snack_id" class="modern-select" required>
                <?php
                $snack_q = mysqli_query($conn, "SELECT * FROM snacks WHERE stok > 0 ORDER BY nama_barang ASC");
                if (mysqli_num_rows($snack_q) > 0) {
                    while($s = mysqli_fetch_assoc($snack_q))
                        echo "<option value='".htmlspecialchars($s['id'])."'>".htmlspecialchars($s['nama_barang'])." (Rp ".number_format($s['harga_jual']).") - Stok: ".$s['stok']."</option>";
                } else {
                    echo "<option value=''>Tidak ada snack tersedia</option>";
                }
                ?>
            </select>
            <input type="number" name="qty" class="modern-select" value="1" min="1" max="99" placeholder="Jumlah">
            <div style="display:flex; gap:12px; margin-top:10px;">
                <button type="button" onclick="closeModal('modalFnB')" class="btn-act" style="flex:1"><i class='bx bx-x'></i> Batal</button>
                <button type="submit" class="btn-start" style="flex:1.5"><i class='bx bx-cart-add'></i> Tambah</button>
            </div>
        </form>
    </div>
</div>

<div id="modalMove" class="modal-backdrop">
    <div class="modal-content">
        <h3 style="color:var(--primary);"><i class='bx bx-transfer'></i> Pindah Unit</h3>
        <form action="process.php" method="POST" style="margin-top:20px;">
            <input type="hidden" name="action" value="move">
            <input type="hidden" name="from_tv_id" id="move_from">
            <select name="to_tv_id" class="modern-select" required>
                <?php if (empty($available_tvs)): ?>
                    <option value="">Tidak ada TV tersedia</option>
                <?php else: foreach($available_tvs as $avt): ?>
                    <option value="<?= htmlspecialchars($avt['id']) ?>"><?= htmlspecialchars($avt['nama_tv']) ?></option>
                <?php endforeach; endif; ?>
            </select>
            <div style="display:flex; gap:12px;">
                <button type="button" onclick="closeModal('modalMove')" class="btn-act" style="flex:1"><i class='bx bx-x'></i> Batal</button>
                <button type="submit" class="btn-start" style="flex:1.5" <?= empty($available_tvs) ? 'disabled' : '' ?>><i class='bx bx-check'></i> Pindahkan</button>
            </div>
        </form>
    </div>
</div>

<div id="modalAddTime" class="modal-backdrop">
    <div class="modal-content">
        <h3 style="color:var(--primary);"><i class='bx bx-time-five'></i> Tambah Waktu</h3>
        <div id="addtime_tv_label" style="text-align:center; color:var(--text-dim); font-size:0.85rem; margin-bottom:15px;"></div>
        <input type="hidden" id="addtime_tv_id">
        <select class="modern-select" id="addtime_paket_id" required>
            <?php
            $pkgs2 = mysqli_query($conn, "SELECT * FROM packages ORDER BY durasi_menit ASC");
            while($p2 = mysqli_fetch_assoc($pkgs2))
                echo "<option value='".htmlspecialchars($p2['id'])."' data-menit='".(int)$p2['durasi_menit']."' data-harga='".(int)$p2['harga']."'>".htmlspecialchars($p2['nama_paket'])." (+".htmlspecialchars($p2['durasi_menit'])." menit) - Rp ".number_format($p2['harga'])."</option>";
            ?>
        </select>
        <div id="addtime_preview" style="background:rgba(6,182,212,0.1); border:1px solid rgba(6,182,212,0.2); border-radius:14px; padding:14px; margin-bottom:15px; font-size:0.85rem;">
            <div style="display:flex; justify-content:space-between; margin-bottom:6px;">
                <span style="color:var(--text-dim);">Tambah waktu:</span>
                <span id="addtime_preview_menit" style="color:var(--primary); font-weight:700;">-</span>
            </div>
            <div style="display:flex; justify-content:space-between;">
                <span style="color:var(--text-dim);">Tambah biaya:</span>
                <span id="addtime_preview_harga" style="color:var(--success); font-weight:700;">-</span>
            </div>
        </div>
        <div style="display:flex; gap:12px;">
            <button type="button" onclick="closeModal('modalAddTime')" class="btn-act" style="flex:1"><i class='bx bx-x'></i> Batal</button>
            <button type="button" onclick="confirmAddTime()" id="addtime_submit_btn" class="btn-start" style="flex:1.5; display:flex; align-items:center; justify-content:center; gap:8px;">
                <i class='bx bx-plus'></i> TAMBAH WAKTU
            </button>
        </div>
    </div>
</div>

<script>
    // ===================================================================
    // GLOBAL STATE
    // ===================================================================
    let currentStopTvId  = null;
    let currentStopTrxId = null;
    let alreadyStopped   = false;
    const stoppedTrxMap  = {};

    function createParticles() {
        const container = document.getElementById('particles');
        if (!container) return;
        for (let i = 0; i < 30; i++) {
            const p = document.createElement('div');
            p.className = 'particle';
            p.style.left = Math.random() * 100 + '%';
            p.style.animationDelay = Math.random() * 8 + 's';
            p.style.animationDuration = (5 + Math.random() * 5) + 's';
            container.appendChild(p);
        }
    }
    createParticles();

    function switchTab(btn, id, type) {
        document.getElementById(`form-fixed-${id}`)?.classList.toggle('hidden', type !== 'fixed');
        document.getElementById(`form-open-${id}`)?.classList.toggle('hidden', type !== 'open');
        document.querySelectorAll(`.tab-btn-${id}`).forEach(b => b.classList.remove('active'));
        btn.classList.add('active');
    }

    function toggleStik(el) {
        document.querySelectorAll('.stik-selector.active').forEach(s => {
            if (s !== el.closest('.stik-selector')) s.classList.remove('active');
        });
        el.closest('.stik-selector').classList.toggle('active');
    }

    function updateStikText(input) {
        const selector = input.closest('.stik-selector');
        const checked  = Array.from(selector.querySelectorAll('input:checked')).map(i => i.value);
        const span     = selector.querySelector('.stik-trigger span');
        if (span) span.innerText = checked.length ? checked.join(', ') : 'Pilih Stik...';
    }

    // ===================================================================
    // TIMER SYSTEM
    // ===================================================================
    const timers = [];

    function initTimers() {
        document.querySelectorAll('.timer-digits').forEach(el => {
            const type   = el.dataset.type;
            const status = el.dataset.status;
            if (status === 'available') return;

            const initVal  = (type === 'fixed') ? parseInt(el.dataset.sisa || 0) : parseInt(el.dataset.elapsed || 0);
            const roundVal = parseInt(el.dataset.round) || 1;
            const isExpired = el.dataset.expired === '1';

            const t = {
                el, id: el.dataset.id, type,
                startTime: Date.now(), initSec: initVal,
                rate: parseInt(el.dataset.rate) || 0,
                min:  parseInt(el.dataset.min)  || 0,
                round: roundVal > 0 ? roundVal : 1,
                billEl: document.getElementById(`bill-${el.dataset.id}`),
                trxId: parseInt(el.dataset.trxId) || 0,
                done: isExpired
            };
            timers.push(t);

            if (isExpired && type === 'fixed') {
                el.innerHTML = 'WAKTU HABIS';
                showTimeoutNotification(t.id, t.trxId);
            }
        });
        setInterval(tick, 1000);
    }

    function tick() {
        const now = Date.now();
        timers.forEach(t => {
            const status = t.el.dataset.status;

            // ── PAUSED: freeze di initSec (initSec diupdate oleh addTime jika perlu) ──
            if (status === 'paused') { t.el.innerHTML = formatTime(t.initSec); return; }
            if (status === 'available') { t.el.innerHTML = '00:00:00'; return; }

            const delta = Math.floor((now - t.startTime) / 1000);
            let sec = (t.type === 'fixed') ? (t.initSec - delta) : (t.initSec + delta);
            if (sec < 0) sec = 0;
            t.el.innerHTML = formatTime(sec);

            if (t.type === 'fixed' && sec === 0 && !t.done) {
                t.done = true;
                t.el.classList.add('time-expired');
                t.el.innerHTML = 'WAKTU HABIS';
                showTimeoutNotification(t.id, t.trxId);
            }

            if (t.billEl && t.type === 'open') {
                let cost = Math.max(t.min, Math.ceil((sec / 3600) * t.rate));
                cost = Math.ceil(cost / t.round) * t.round;
                t.billEl.innerText = "Rp " + cost.toLocaleString('id-ID');
            }
        });
    }

    // ===================================================================
    // TOGGLE PAUSE/RESUME VIA AJAX
    // ===================================================================
    function togglePause(tvId, currentStatus) {
        const action = (currentStatus === 'paused') ? 'resume' : 'pause';
        const btn    = document.getElementById(`pausebtn-${tvId}`);
        if (btn) { btn.disabled = true; btn.style.opacity = '0.5'; }

        fetch(`process.php?action=${action}&tv_id=${tvId}&ajax=1`)
            .then(r => r.json())
            .then(data => {
                if (data.status !== 'success') {
                    showToast('✗ Gagal ' + (action === 'pause' ? 'pause' : 'resume'), 'error');
                    if (btn) { btn.disabled = false; btn.style.opacity = ''; }
                    return;
                }

                const timerEl = document.getElementById(`timer-${tvId}`);
                const card    = document.getElementById(`card-${tvId}`);
                const pill    = card?.querySelector('.status-pill');

                if (action === 'pause') {
                    // Simpan sisa detik saat ini ke initSec sebelum freeze
                    const timerObj = timers.find(t => t.id == tvId);
                    if (timerObj) {
                        const delta = Math.floor((Date.now() - timerObj.startTime) / 1000);
                        timerObj.initSec = (timerObj.type === 'fixed')
                            ? Math.max(0, timerObj.initSec - delta)
                            : timerObj.initSec + delta;
                        timerObj.startTime = Date.now();
                    }

                    timerEl.dataset.status = 'paused';
                    card?.classList.remove('active'); card?.classList.add('paused');
                    if (pill) pill.innerHTML = "<i class='bx bx-pause-circle'></i> PAUSED";

                    if (btn) {
                        btn.innerHTML = "<i class='bx bx-play'></i><span>Resume</span>";
                        btn.onclick   = () => togglePause(tvId, 'paused');
                        btn.disabled  = false; btn.style.opacity = '';
                    }
                    showToast('⏸ Sesi di-pause', 'warning');
                } else {
                    // Resume → reload agar sisa detik sync dari DB
                    window.location.reload();
                }
            })
            .catch(() => window.location.reload());
    }

    // ===================================================================
    // AUTO-TIMEOUT
    // ===================================================================
    function showTimeoutNotification(tvId, trxId) {
        if (document.getElementById(`timeout-notif-${tvId}`)) return;

        fetch(`process.php?action=stop&tv_id=${tvId}&ajax=1`)
            .then(r => r.json())
            .then(data => {
                stoppedTrxMap[tvId] = data.trx_id || trxId;
                const timerEl = document.getElementById(`timer-${tvId}`);
                const card    = document.getElementById(`card-${tvId}`);
                if (card) {
                    card.classList.remove('active', 'paused'); card.classList.add('available');
                    const pill = card.querySelector('.status-pill');
                    if (pill) pill.innerHTML = "<i class='bx bx-circle'></i> AVAILABLE";
                    if (timerEl) { timerEl.innerText = "00:00:00"; timerEl.classList.remove('time-expired'); timerEl.dataset.status = 'available'; }
                }
            })
            .catch(() => { stoppedTrxMap[tvId] = trxId; });

        const notif = document.createElement('div');
        notif.id = `timeout-notif-${tvId}`;
        notif.style.cssText = `position:fixed;top:20px;right:20px;z-index:99999;background:linear-gradient(135deg,#ef4444,#dc2626);color:#fff;padding:20px 25px;border-radius:16px;box-shadow:0 10px 40px rgba(239,68,68,0.4);animation:slideIn .3s ease;font-weight:700;backdrop-filter:blur(10px);border:1px solid rgba(255,255,255,.2);min-width:320px;`;
        notif.innerHTML = `<div style="display:flex;align-items:center;gap:12px;"><i class='bx bx-power-off bx-tada' style="font-size:32px;"></i><div><div style="font-size:1.1rem;">⏰ TV ${tvId}: SELESAI!</div><div style="font-size:.8rem;opacity:.9;">Sistem telah mematikan TV otomatis.</div></div></div>`;
        document.body.appendChild(notif);
        setTimeout(() => { notif.style.animation = 'slideOut .3s ease'; setTimeout(() => notif.remove(), 300); }, 10000);
    }

    function formatTime(s) {
        if (s < 0) s = 0;
        return [Math.floor(s/3600), Math.floor((s%3600)/60), s%60].map(v => String(v).padStart(2,'0')).join(':');
    }

    // ===================================================================
    // STOP MODAL
    // ===================================================================
    function openStopModal(id, name) {
        currentStopTvId  = id;
        alreadyStopped   = false;
        const savedTrxId = stoppedTrxMap[id] || null;
        const timerEl    = document.getElementById(`timer-${id}`);
        currentStopTrxId = savedTrxId || (timerEl ? parseInt(timerEl.dataset.trxId) || null : null);
        if (savedTrxId) alreadyStopped = true;

        const detailBox = document.getElementById('billing_detail');
        const stopBtn   = document.getElementById('confirm_stop_btn');
        document.getElementById('modalStop').style.display = 'flex';
        detailBox.innerHTML = '<div style="text-align:center;padding:20px;"><i class="bx bx-loader-alt bx-spin" style="font-size:2rem;color:var(--primary);"></i><div style="margin-top:10px;color:var(--text-dim);">Menghitung...</div></div>';

        let url = `process.php?action=get_summary&tv_id=${id}`;
        if (currentStopTrxId) url += `&trx_id=${currentStopTrxId}`;

        fetch(url)
            .then(r => { if (!r.ok) throw new Error(); return r.json(); })
            .then(data => {
                if (data.status === 'success') {
                    let fnbHtml = '', calcHtml = '';
                    (data.fnb_list || []).forEach(i => {
                        fnbHtml += `<div class="billing-item"><span><i class='bx bx-food-menu' style="color:var(--primary);"></i> ${escapeHtml(i.nama_barang)} (x${i.qty})</span><span>Rp ${parseInt(i.total_harga).toLocaleString('id-ID')}</span></div>`;
                    });
                    if (data.jenis_paket === 'open' && data.calc_info) {
                        const ci = data.calc_info;
                        calcHtml = `<div style="background:rgba(6,182,212,0.1);padding:12px;border-radius:12px;margin-top:12px;font-size:.75rem;border:1px solid rgba(6,182,212,0.2);"><div style="color:var(--primary);font-weight:700;margin-bottom:8px;"><i class='bx bx-calculator'></i> Detail Perhitungan:</div><div style="display:flex;justify-content:space-between;color:var(--text-dim);margin-bottom:4px;"><span>Rate:</span><span>Rp ${ci.rate_per_jam.toLocaleString('id-ID')}/jam</span></div><div style="display:flex;justify-content:space-between;color:var(--text-dim);margin-bottom:4px;"><span>Biaya aktual:</span><span>Rp ${ci.biaya_mentah.toLocaleString('id-ID')}</span></div><div style="display:flex;justify-content:space-between;color:var(--text-dim);"><span>Min. charge:</span><span>Rp ${ci.min_charge.toLocaleString('id-ID')}</span></div></div>`;
                    }
                    detailBox.innerHTML = `
                        <div style="text-align:center;border-bottom:1px solid rgba(255,255,255,.1);padding-bottom:15px;margin-bottom:15px;">
                            <h2 style="margin:0;color:var(--primary);font-family:'Orbitron',sans-serif;font-size:1.3rem;">${escapeHtml(name)}</h2>
                            <div style="color:var(--text-dim);font-size:.85rem;margin-top:5px;"><i class='bx bx-user'></i> ${escapeHtml(data.player)}</div>
                        </div>
                        <div class="billing-item"><b><i class='bx bx-time-five' style="color:var(--primary);"></i> Sesi (${escapeHtml(data.paket)})</b><span style="font-weight:700;">Rp ${data.biaya_sesi.toLocaleString('id-ID')}</span></div>
                        <div style="font-size:.75rem;color:var(--text-dim);padding-left:20px;">Durasi: ${escapeHtml(data.durasi)}</div>
                        ${calcHtml}
                        ${fnbHtml.length ? '<div style="margin-top:15px;font-weight:bold;color:var(--primary);font-size:.75rem;"><i class=\'bx bx-food-menu\'></i> FnB ORDERS:</div>' + fnbHtml : ''}
                        <div class="total-row"><span><i class='bx bx-wallet'></i> TOTAL</span><span>Rp ${data.grand_total.toLocaleString('id-ID')}</span></div>`;
                    stopBtn.disabled = false;
                } else {
                    detailBox.innerHTML = `<div style="color:var(--danger);text-align:center;padding:15px;"><i class='bx bx-error' style="font-size:2rem;"></i><div style="margin-top:8px;">${escapeHtml(data.msg||'Error')}</div></div>`;
                    stopBtn.disabled = true;
                }
            })
            .catch(() => {
                detailBox.innerHTML = `<div style="color:var(--danger);text-align:center;padding:15px;"><i class='bx bx-error' style="font-size:2rem;"></i><div style="margin-top:8px;">Gagal memuat data</div></div>`;
                stopBtn.disabled = true;
            });
    }

    function confirmStop() {
        if (!currentStopTvId) return;
        const btn = document.getElementById('confirm_stop_btn');
        btn.disabled = true; btn.innerHTML = '<i class="bx bx-loader-alt bx-spin"></i> Memproses...';
        if (alreadyStopped) { delete stoppedTrxMap[currentStopTvId]; window.location.href = 'index.php'; return; }
        fetch(`process.php?action=stop&tv_id=${currentStopTvId}&ajax=1`)
            .then(r => r.json())
            .then(() => { window.location.href = 'index.php'; })
            .catch(() => { window.location.href = `process.php?action=stop&tv_id=${currentStopTvId}`; });
    }

    function escapeHtml(text) {
        if (text == null) return '';
        const d = document.createElement('div'); d.textContent = text; return d.innerHTML;
    }

    function openFnBModal(id, name) {
        document.getElementById('fnb_tv_id').value = id;
        document.getElementById('fnb_title').innerHTML = `<i class='bx bx-food-menu'></i> FnB: ${name}`;
        document.getElementById('modalFnB').style.display = 'flex';
    }

    // ===================================================================
    // TAMBAH WAKTU
    // ===================================================================
    function openAddTimeModal(tvId, tvName) {
        document.getElementById('addtime_tv_id').value = tvId;
        document.getElementById('addtime_tv_label').innerHTML = `<i class='bx bx-tv'></i> <b>${escapeHtml(tvName)}</b>`;
        document.getElementById('modalAddTime').style.display = 'flex';
        const btn = document.getElementById('addtime_submit_btn');
        btn.disabled = false; btn.innerHTML = '<i class="bx bx-plus"></i> TAMBAH WAKTU';
        updateAddTimePreview();
    }

    function updateAddTimePreview() {
        const sel = document.getElementById('addtime_paket_id');
        const opt = sel.options[sel.selectedIndex];
        if (opt) {
            document.getElementById('addtime_preview_menit').textContent = `+${opt.dataset.menit||0} menit`;
            document.getElementById('addtime_preview_harga').textContent = `+Rp ${parseInt(opt.dataset.harga||0).toLocaleString('id-ID')}`;
        }
    }

    function confirmAddTime() {
        const tvId    = document.getElementById('addtime_tv_id').value;
        const paketId = document.getElementById('addtime_paket_id').value;
        const btn     = document.getElementById('addtime_submit_btn');
        if (!tvId || !paketId) return;
        btn.disabled = true; btn.innerHTML = '<i class="bx bx-loader-alt bx-spin"></i> Memproses...';

        const fd = new FormData();
        fd.append('action', 'add_time'); fd.append('tv_id', tvId); fd.append('paket_id', paketId);

        fetch('process.php', { method: 'POST', body: fd })
            .then(r => r.json())
            .then(data => {
                if (data.status === 'success') {
                    showToast(`✓ ${data.nama_paket}: +${data.tambah_menit}m ditambahkan!`, 'success');

                    const timerObj = timers.find(t => t.id == tvId);
                    if (timerObj) {
                        const isPaused = timerObj.el.dataset.status === 'paused';

                        if (isPaused) {
                            // ── FIX: Paused → hanya update initSec, JANGAN reset startTime ──
                            // tick() akan render initSec baru tapi timer tetap diam (freeze)
                            timerObj.initSec = data.new_sisa_detik;
                            timerObj.el.innerHTML = formatTime(data.new_sisa_detik);
                        } else {
                            // Active → reset normal
                            timerObj.initSec   = data.new_sisa_detik;
                            timerObj.startTime = Date.now();
                            timerObj.done      = false;
                            timerObj.el.classList.remove('time-expired');
                            timerObj.el.dataset.expired = '0';
                            timerObj.el.dataset.status  = 'active';

                            const card = document.getElementById(`card-${tvId}`);
                            if (card) {
                                card.classList.remove('available'); card.classList.add('active');
                                const pill = card.querySelector('.status-pill');
                                if (pill) pill.innerHTML = "<i class='bx bx-play-circle'></i> ACTIVE";
                            }
                        }
                    }

                    document.getElementById(`timeout-notif-${tvId}`)?.remove();
                    delete stoppedTrxMap[tvId];
                    closeModal('modalAddTime');
                } else {
                    showToast(`✗ ${data.msg || 'Gagal tambah waktu'}`, 'error');
                    btn.disabled = false; btn.innerHTML = '<i class="bx bx-plus"></i> TAMBAH WAKTU';
                }
            })
            .catch(() => {
                showToast('✗ Gagal tambah waktu', 'error');
                btn.disabled = false; btn.innerHTML = '<i class="bx bx-plus"></i> TAMBAH WAKTU';
            });
    }

    document.addEventListener('DOMContentLoaded', () => {
        document.getElementById('addtime_paket_id')?.addEventListener('change', updateAddTimePreview);
    });

    function closeModal(id)    { document.getElementById(id).style.display = 'none'; }
    function openMoveModal(id) { document.getElementById('move_from').value = id; document.getElementById('modalMove').style.display = 'flex'; }

    function remote(e, act, id) {
        e.preventDefault();
        e.currentTarget.style.transform = 'scale(0.9)';
        setTimeout(() => e.currentTarget.style.transform = '', 150);
        fetch(`process.php?action=${act}&tv_id=${id}&ajax=1`).catch(() => {});
    }

    function connectTV(e, tvId, tvName) {
        e.preventDefault();
        const btn  = e.currentTarget;
        const icon = btn.querySelector('i');
        btn.classList.add('connecting'); icon.className = 'bx bx-loader-alt';
        fetch(`process.php?action=adb_connect&tv_id=${tvId}&ajax=1`)
            .then(() => setTimeout(() => {
                fetch('process.php?action=check_adb_status').then(r => r.json()).then(d => {
                    btn.classList.remove('connecting');
                    const online = d.tvs?.find(t => t.id == tvId)?.status === 'online';
                    if (online) { icon.className='bx bx-check'; btn.style.background='var(--success)'; btn.style.color='#000'; showToast(`✓ ${tvName} Connected!`,'success'); }
                    else        { icon.className='bx bx-x';     btn.style.background='var(--danger)';  btn.style.color='#fff'; showToast(`✗ ${tvName} gagal connect`,'error'); }
                    d.tvs?.forEach(tv => {
                        const el = document.getElementById(`adb-status-${tv.id}`);
                        if (el) { el.classList.remove('online','offline'); el.classList.add(tv.status); const t=el.querySelector('.adb-text'); if(t) t.textContent=`ADB ${tv.status.toUpperCase()}`; }
                    });
                    setTimeout(() => { icon.className='bx bx-link'; btn.style.background=''; btn.style.color=''; }, 2000);
                }).catch(() => { btn.classList.remove('connecting'); icon.className='bx bx-error'; btn.style.background='var(--warning)'; showToast(`⚠ Tidak dapat verifikasi ${tvName}`,'warning'); setTimeout(()=>{icon.className='bx bx-link';btn.style.background='';},2000); });
            }, 2000))
            .catch(() => { btn.classList.remove('connecting'); icon.className='bx bx-error'; btn.style.background='var(--danger)'; btn.style.color='#fff'; showToast(`✗ Gagal connect ${tvName}`,'error'); setTimeout(()=>{icon.className='bx bx-link';btn.style.background='';btn.style.color='';},2000); });
    }

    function refreshADBStatus() {
        fetch('process.php?action=check_adb_status').then(r => r.json()).then(data => {
            data.tvs?.forEach(tv => {
                const el = document.getElementById(`adb-status-${tv.id}`);
                if (el) { el.classList.remove('online','offline'); el.classList.add(tv.status); const t=el.querySelector('.adb-text'); if(t) t.textContent=`ADB ${tv.status.toUpperCase()}`; }
            });
        }).catch(() => {});
    }

    function showToast(message, type = 'info') {
        document.querySelectorAll('.toast-notification').forEach(t => t.remove());
        const toast = document.createElement('div');
        toast.className = 'toast-notification';
        const colors = { success: ['var(--success)','#000'], error: ['var(--danger)','#fff'], warning: ['var(--warning)','#000'] };
        const [bg, fg] = colors[type] || ['var(--primary)','#000'];
        toast.style.cssText = `position:fixed;bottom:20px;right:20px;background:${bg};color:${fg};padding:15px 25px;border-radius:12px;font-weight:700;font-size:.9rem;z-index:99999;animation:slideIn .3s ease;box-shadow:0 10px 30px rgba(0,0,0,.3);`;
        toast.textContent = message;
        document.body.appendChild(toast);
        setTimeout(() => { toast.style.animation='slideOut .3s ease'; setTimeout(()=>toast.remove(),300); }, 3000);
    }

    const allTVs = [];
    document.querySelectorAll('.connect-btn').forEach(btn => allTVs.push({ id: btn.id.replace('connect-btn-',''), ip: btn.dataset.ip }));

    function autoReconnectAll() {
        Promise.all(allTVs.map(tv => tv.ip ? fetch(`process.php?action=adb_connect&tv_id=${tv.id}&ajax=1`).then(()=>({id:tv.id,success:true})).catch(()=>({id:tv.id,success:false})) : Promise.resolve({id:tv.id,success:false})))
            .then(() => setTimeout(refreshADBStatus, 2000));
    }

    setTimeout(autoReconnectAll, 2000);
    setInterval(autoReconnectAll, 30000);
    setInterval(refreshADBStatus, 10000);

    initTimers();

    document.addEventListener('click', e => {
        if (!e.target.closest('.stik-selector')) document.querySelectorAll('.stik-selector.active').forEach(s => s.classList.remove('active'));
        if (e.target.classList.contains('modal-backdrop')) e.target.style.display = 'none';
    });

    // ===== AUTO SYNC REPORT =====
    function syncReport() { fetch('sync_report.php').then(r=>r.json()).then(d=>{if(d.status==='success')console.log('Synced:',d.server_response);}).catch(()=>{}); }
    setTimeout(syncReport, 10000);
    setInterval(syncReport, 300000);
</script>