<?php
ob_start();
ini_set('display_errors', 1);
error_reporting(E_ALL);

// === Session cookie hardening — fix "selalu minta password" bug ===
// Force cookie path = '/' so the same PHPSESSID works whether user accesses
// via '/?tab=apps' (root via router.php) or '/inject/?tab=apps' (direct).
// Without this, PHP auto-derives path from script dir → /inject/ vs /
// causing browser to send different cookies → session reset on POST redirect.
if (session_status() === PHP_SESSION_NONE) {
    $cookieParams = session_get_cookie_params();
    session_set_cookie_params([
        'lifetime' => $cookieParams['lifetime'] ?? 0,
        'path'     => '/',
        'domain'   => $cookieParams['domain'] ?? '',
        'secure'   => !empty($_SERVER['HTTPS']) && $_SERVER['HTTPS'] !== 'off',
        'httponly' => true,
        'samesite' => 'Lax'
    ]);
    session_name('PHPSESSID');
    session_start();
} else {
    // Already started elsewhere — leave it alone
}

// =============================================
// TEKNO-APPS Member System - JSON File Storage
// Single monolithic file - No MySQL required
// =============================================

define('SECRET_KEY', 'TEXA-FLOW-2026-SECRET');
define('CODE_LENGTH', 12);
define('DATA_DIR', __DIR__ . '/data');

// =============================================
// DATA LAYER - JSON File Storage
// =============================================
function ensureDataDir() {
    if (!is_dir(DATA_DIR)) mkdir(DATA_DIR, 0755, true);
    if (!file_exists(DATA_DIR . '/.htaccess')) {
        file_put_contents(DATA_DIR . '/.htaccess', "Deny from all\n");
    }
}

function loadData($file) {
    ensureDataDir();
    $path = DATA_DIR . '/' . $file;
    if (!file_exists($path)) return [];
    $raw = file_get_contents($path);
    return json_decode($raw, true) ?: [];
}

function saveData($file, $data) {
    ensureDataDir();
    $path = DATA_DIR . '/' . $file;
    file_put_contents($path, json_encode($data, JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES), LOCK_EX);
}

function nextId($items) {
    $max = 0;
    foreach ($items as $it) { if (isset($it['id']) && is_int($it['id']) && $it['id'] > $max) $max = $it['id']; }
    return $max + 1;
}

function generateCode($length = CODE_LENGTH) {
    $chars = 'ABCDEFGHJKLMNPQRSTUVWXYZ23456789';
    $code = '';
    for ($i = 0; $i < $length; $i++) $code .= $chars[random_int(0, strlen($chars) - 1)];
    return $code;
}

// =============================================
// SEED DEFAULT APPLICATIONS
// =============================================
function seedApps() {
    $apps = loadData('applications.json');
    if (!empty($apps)) return;
    $default_flow_unlock_models = ['lite'=>1,'fast'=>0,'quality'=>0,'lower_priority'=>1,'omni_flash'=>0];
    $apps = [
        ['id'=>'google-flow','name'=>'Google Flow','icon_type'=>'image','icon_value'=>'app_icons/google_flow.png','color_gradient'=>'linear-gradient(135deg, #1a73e8, #34a0ff)','max_servers'=>5,'default_url'=>'https://labs.google/fx/tools/flow','requires_cookie'=>1,'flow_lock_enabled'=>1,'flow_unlock_models'=>$default_flow_unlock_models,'is_active'=>1,'sort_order'=>1],
        ['id'=>'google-whisk','name'=>'Google Whisk','icon_type'=>'image','icon_value'=>'app_icons/google_whisk.png','color_gradient'=>'linear-gradient(135deg, #0f9d58, #00e676)','max_servers'=>5,'default_url'=>'https://labs.google/fx/tools/whisk','requires_cookie'=>1,'flow_lock_enabled'=>1,'flow_unlock_models'=>$default_flow_unlock_models,'is_active'=>1,'sort_order'=>2],
        ['id'=>'grok','name'=>'Grok','icon_type'=>'image','icon_value'=>'app_icons/grok.png','color_gradient'=>'linear-gradient(135deg, #6200ea, #aa00ff)','max_servers'=>5,'default_url'=>'https://grok.com/','requires_cookie'=>1,'flow_lock_enabled'=>1,'flow_unlock_models'=>$default_flow_unlock_models,'is_active'=>1,'sort_order'=>3],
        ['id'=>'single-sora','name'=>'Single Sora\\nRemover','icon_type'=>'image','icon_value'=>'app_icons/sora-color.png','color_gradient'=>'linear-gradient(135deg, #e8710a, #ff9800)','max_servers'=>1,'default_url'=>'https://sora-wm.vercel.app/','requires_cookie'=>0,'flow_lock_enabled'=>1,'flow_unlock_models'=>$default_flow_unlock_models,'is_active'=>1,'sort_order'=>4],
        ['id'=>'bulk-sora','name'=>'Bulk Sora\\nRemover','icon_type'=>'image','icon_value'=>'app_icons/sora.png','color_gradient'=>'linear-gradient(135deg, #d50000, #ff1744)','max_servers'=>1,'default_url'=>'https://texa-bulk-downloader.42web.io/','requires_cookie'=>0,'flow_lock_enabled'=>1,'flow_unlock_models'=>$default_flow_unlock_models,'is_active'=>1,'sort_order'=>5],
    ];
    saveData('applications.json', $apps);
}
seedApps();

// =============================================
// AUTO-MIGRATE OLD DOMAIN IN DATABASE
// =============================================
$appsMigration = loadData('applications.json');
$needsMigration = false;
foreach ($appsMigration as &$migApp) {
    $default_flow_unlock_models = ['lite'=>1,'fast'=>0,'quality'=>0,'lower_priority'=>1,'omni_flash'=>0];
    if (!isset($migApp['flow_lock_enabled'])) {
        $migApp['flow_lock_enabled'] = 1;
        $needsMigration = true;
    }
    if (!isset($migApp['flow_unlock_models']) || !is_array($migApp['flow_unlock_models'])) {
        $migApp['flow_unlock_models'] = $default_flow_unlock_models;
        $needsMigration = true;
    } else {
        foreach ($default_flow_unlock_models as $k => $v) {
            if (!isset($migApp['flow_unlock_models'][$k])) {
                $migApp['flow_unlock_models'][$k] = $v;
                $needsMigration = true;
            }
        }
    }
    if (isset($migApp['icon_value']) && strpos($migApp['icon_value'], 'http://texa.web.id') !== false) {
        $migApp['icon_value'] = str_replace('http://texa.web.id', 'https://test.texaproject.com', $migApp['icon_value']);
        $needsMigration = true;
    }
    if (isset($migApp['default_url']) && strpos($migApp['default_url'], 'http://texa.web.id') !== false) {
        $migApp['default_url'] = str_replace('http://texa.web.id', 'https://test.texaproject.com', $migApp['default_url']);
        $needsMigration = true;
    }
    if (!empty($migApp['custom_servers'])) {
        foreach ($migApp['custom_servers'] as &$cs) {
            if (isset($cs['url']) && strpos($cs['url'], 'http://texa.web.id') !== false) {
                $cs['url'] = str_replace('http://texa.web.id', 'https://test.texaproject.com', $cs['url']);
                $needsMigration = true;
            }
        }
    }
}
if ($needsMigration) {
    saveData('applications.json', $appsMigration);
}

// =============================================
// PACKAGE DEFINITIONS
// =============================================
$PACKAGES = [
    'basic'    => [], // Limits now handled dynamically via custom_config or max_servers
    'pro'      => [],
    'ultimate' => [],
    'trial'    => [],
];
$PKG_LABELS = ['basic'=>'Basic','pro'=>'Pro','ultimate'=>'Ultimate','custom'=>'Custom','trial'=>'Trial'];

// Build APP_LABELS, APP_MAX, APP_URLS from JSON
$allAppsData = loadData('applications.json');
$APP_LABELS = []; $APP_MAX = []; $APP_URLS_PHP = [];
foreach ($allAppsData as $app) {
    if (!$app['is_active']) continue;
    $APP_LABELS[$app['id']] = $app['name'];
    $APP_MAX[$app['id']] = (int)$app['max_servers'];
    if (!empty($app['custom_servers'])) {
        $APP_MAX[$app['id']] = count($app['custom_servers']); // Prioritize custom servers count
    }
    $APP_URLS_PHP[$app['id']] = $app['default_url'] ?? '';
}
// Also build full labels (including inactive) for admin
$ALL_APP_LABELS = [];
foreach ($allAppsData as $app) { $ALL_APP_LABELS[$app['id']] = $app['name']; }

$settings = loadData('settings.json');
// Harga paket: prioritas dari packages.json (main_prices), fallback ke settings.json
$_pkg_from_packages = loadData('packages.json');
$pkg_prices = $_pkg_from_packages['main_prices'] ?? $settings['pkg_prices'] ?? ['basic' => 50000, 'pro' => 100000, 'ultimate' => 150000, 'custom' => 0];

function get_url_token($app_id, $real_url) {
    // Legacy support or fallback if needed
    $settings = loadData('settings.json');
    $key = $settings['url_secret_key'] ?? '';
    if (empty($key)) {
        $key = bin2hex(random_bytes(32));
        $settings['url_secret_key'] = $key;
        saveData('settings.json', $settings);
    }
    $payload = json_encode(['id' => $app_id, 'url' => $real_url, 'ts' => time()]);
    $iv = random_bytes(16);
    $encrypted = openssl_encrypt($payload, 'aes-256-cbc', base64_decode($key), 0, $iv);
    return rtrim(strtr(base64_encode($iv . '::' . $encrypted), '+/', '-_'), '=');
}

function get_url_slug($name) {
    $slug = strtolower(trim(preg_replace('/[^A-Za-z0-9-]+/', '-', $name), '-'));
    return empty($slug) ? 'app' : $slug;
}

// =============================================
// API MODE - JSON Response (called by extension via Worker)
// =============================================
$action = isset($_GET['action']) ? trim($_GET['action']) : '';

// === CORS HEADERS — selalu aktif untuk semua API call (termasuk OPTIONS preflight) ===
if ($action !== '' || $_SERVER['REQUEST_METHOD'] === 'OPTIONS') {
    header('Access-Control-Allow-Origin: *');
    header('Access-Control-Allow-Methods: GET, POST, OPTIONS');
    header('Access-Control-Allow-Headers: Content-Type, Authorization, X-Requested-With');
    header('Access-Control-Max-Age: 86400');
    if ($_SERVER['REQUEST_METHOD'] === 'OPTIONS') {
        http_response_code(200);
        exit();
    }
}

if ($action !== '') {
    header('Content-Type: application/json');

    if ($action === 'takeover') {
        $code = trim($_GET['code'] ?? '');
        $device_id = trim($_GET['device_id'] ?? '');
        if (empty($code) || empty($device_id)) { echo json_encode(['valid'=>false,'reason'=>'empty_code']); exit(); }

        $members = loadData('members.json');
        $rowIdx = -1;
        foreach ($members as $i => $m) { if ($m['code'] === $code) { $rowIdx = $i; break; } }

        if ($rowIdx === -1) { echo json_encode(['valid'=>false,'reason'=>'not_found']); exit(); }

        $members[$rowIdx]['active_device_id'] = $device_id;
        saveData('members.json', $members);

        echo json_encode(['valid'=>true, 'success'=>true]);
        exit();
    }
    
    if ($action === 'register_session') {
        $code = trim($_POST['code'] ?? '');
        if (!empty($code)) {
            $_SESSION['texa_user_code'] = $code;
            echo json_encode(['success' => true]);
        } else {
            echo json_encode(['success' => false]);
        }
        exit();
    }

    if ($action === 'heartbeat') {
        $code = trim($_GET['code'] ?? '');
        $device_id = trim($_GET['device_id'] ?? '');
        if (empty($code) || empty($device_id)) { echo json_encode(['valid'=>false]); exit(); }

        $members = loadData('members.json');
        foreach ($members as $m) {
            if ($m['code'] === $code) {
                // Cek apakah ini user mitra atau user utama
                $is_mitra = !empty($m['mitra_id']);
                $mitra_id = $m['mitra_id'] ?? null;
                $m_ui = !empty($mitra_id) && isset($settings['mitra_ui'][$mitra_id]) ? $settings['mitra_ui'][$mitra_id] : $settings;

                $kick_settings = [
                    'logo' => $is_mitra ? ($m_ui['mitra_kick_logo'] ?? $settings['mitra_kick_logo'] ?? '⚠️') : ($settings['kick_logo'] ?? '⚠️'),
                    'title' => $is_mitra ? ($m_ui['mitra_kick_title'] ?? $settings['mitra_kick_title'] ?? 'Sesi Berakhir.!!!') : ($settings['kick_title'] ?? 'Sesi Berakhir.!!!'),
                    'desc1' => $is_mitra ? ($m_ui['mitra_kick_desc1'] ?? $settings['mitra_kick_desc1'] ?? 'tunggu admin Mitra refresh server.') : ($settings['kick_desc1'] ?? 'tunggu admin TEXA refresh server.'),
                    'desc2' => $is_mitra ? ($m_ui['mitra_kick_desc2'] ?? $settings['mitra_kick_desc2'] ?? 'Cek secara berkala dan pastikan report ke grup WA Mitra. Terimakasih!') : ($settings['kick_desc2'] ?? 'Cek secara berkala dan pastikan report ke grup WA. Terimakasih!'),
                    'wa_btn' => $is_mitra ? ($m_ui['mitra_kick_wa_btn'] ?? $settings['mitra_kick_wa_btn'] ?? 'Whatssap Mitra') : ($settings['kick_wa_btn'] ?? 'Whatssap GRUP'),
                    'wa_link' => $is_mitra ? ($m_ui['mitra_kick_wa_link'] ?? $settings['mitra_kick_wa_link'] ?? 'https://chat.whatsapp.com/') : ($settings['kick_wa_link'] ?? 'https://chat.whatsapp.com/FAg698uVEZOAbOpVLG0FhC'),
                    'close_btn' => $is_mitra ? ($m_ui['mitra_kick_close_btn'] ?? $settings['mitra_kick_close_btn'] ?? 'Tutup & Kembali') : ($settings['kick_close_btn'] ?? 'Tutup & Kembali')
                ];

                if (empty($m['is_active'])) { echo json_encode(['valid'=>false,'reason'=>'inactive','kick_settings'=>$kick_settings]); exit(); }
                if (!empty($m['active_device_id']) && $m['active_device_id'] !== $device_id) {
                    echo json_encode(['valid'=>false,'reason'=>'device_in_use','kick_settings'=>$kick_settings]); exit();
                }

                $show_exp_popup = false;
                $exp_settings = null;
                $trigger_days = (int)($settings['exp_trigger_days'] ?? 3);
                $today = new DateTime();
                $expiry = new DateTime($m['expiry_date']);
                $diff = $today->diff($expiry);
                $days_remaining = $diff->invert ? 0 : $diff->days;
                
                if ($days_remaining <= $trigger_days && $days_remaining >= 0) {
                    $show_exp_popup = true;
                    $exp_settings = [
                        'logo' => $is_mitra ? ($m_ui['mitra_exp_logo'] ?? $settings['mitra_exp_logo'] ?? '⏳') : ($settings['exp_logo'] ?? '⏳'),
                        'title' => $is_mitra ? ($m_ui['mitra_exp_title'] ?? $settings['mitra_exp_title'] ?? 'Masa Aktif Hampir Habis!') : ($settings['exp_title'] ?? 'Masa Aktif Hampir Habis!'),
                        'text' => str_replace('{hari}', $days_remaining, $is_mitra ? ($m_ui['mitra_exp_text'] ?? $settings['mitra_exp_text'] ?? 'Masa aktif voucher Mitra Anda tersisa {hari} hari lagi. Segera hubungi Mitra Anda.') : ($settings['exp_text'] ?? 'Masa aktif voucher Anda tersisa {hari} hari lagi. Segera perpanjang agar akses tidak terputus.')),
                        'btn_text' => $is_mitra ? ($m_ui['mitra_exp_btn_text'] ?? $settings['mitra_exp_btn_text'] ?? 'Hubungi Mitra') : ($settings['exp_btn_text'] ?? 'Perpanjang Sekarang'),
                        'btn_link' => $is_mitra ? ($m_ui['mitra_exp_btn_link'] ?? $settings['mitra_exp_btn_link'] ?? '#') : ($settings['exp_btn_link'] ?? '#')
                    ];
                }

                echo json_encode(['valid'=>true,'kick_settings'=>$kick_settings,'show_exp_popup'=>$show_exp_popup,'exp_settings'=>$exp_settings]); exit();
            }
        }
        echo json_encode(['valid'=>false,'reason'=>'not_found']); exit();
    }

    // === CHECK EXTENSION VERSION (AUTO-DETECT) ===
    if ($action === 'check_version') {
        $client_version = trim($_GET['v'] ?? '');
        $update_active = !empty($settings['ext_update_active']);

        // ============================================================
        // AUTO-DETECT VERSI TERBARU DARI ext_version.json
        // File ini di-generate otomatis saat build dan di-upload ke:
        //   HOST/inject/data/ext_version.json
        // ============================================================
        $ext_version_file = DATA_DIR . '/ext_version.json';
        $auto_version_data = null;
        $auto_latest = null;

        if (file_exists($ext_version_file)) {
            $ev_raw = file_get_contents($ext_version_file);
            $auto_version_data = json_decode($ev_raw, true);
            $auto_latest = isset($auto_version_data['version']) ? trim($auto_version_data['version']) : null;
        }

        // Prioritas: auto-detected (dari ext_version.json) > manual admin setting
        if ($auto_latest && !empty($auto_latest)) {
            $latest_version = $auto_latest;
            // Sync ke settings.json agar admin panel tahu versi terkini
            if (($settings['ext_latest_version'] ?? '') !== $auto_latest) {
                $settings['ext_latest_version'] = $auto_latest;
                saveData('settings.json', $settings);
            }
        } else {
            $latest_version = trim($settings['ext_latest_version'] ?? '1.0.0');
        }

        $needs_update = false;
        if (!empty($client_version)) {
            // Auto-aktif jika ext_version.json ada, atau gunakan toggle admin
            $version_check_active = ($auto_latest !== null) ? true : $update_active;
            if ($version_check_active) {
                $needs_update = version_compare($client_version, $latest_version, '<');
            }
        }

        $response = [
            'needs_update' => $needs_update,
            'latest_version' => $latest_version,
            'client_version' => $client_version,
            'auto_detected' => ($auto_latest !== null),
        ];

        if ($needs_update) {
            $response['update_data'] = [
                'latest_version' => $latest_version,
                'title'    => $settings['ext_update_title']    ?? 'Update Tersedia!',
                'desc'     => str_replace('{version}', $latest_version, $settings['ext_update_desc'] ?? 'Versi terbaru {version} sudah tersedia. Segera update untuk menikmati fitur dan layanan terbaru.'),
                'btn_text' => $settings['ext_update_btn_text'] ?? 'Unduh Sekarang',
                'btn_link' => $settings['ext_update_btn_link'] ?? '#',
            ];
        }

        echo json_encode($response);
        exit();
    }


    if ($action === 'validate') {
        $code = trim($_GET['code'] ?? '');
        $device_id = trim($_GET['device_id'] ?? '');
        if (empty($code) || empty($device_id)) { echo json_encode(['valid'=>false,'reason'=>'empty_code']); exit(); }

        $members = loadData('members.json');
        $row = null; $rowIdx = -1;
        foreach ($members as $i => $m) { if ($m['code'] === $code) { $row = $m; $rowIdx = $i; break; } }

        // Mitra members work perfectly here as well. The database structure is the same.
        if (!$row) { echo json_encode(['valid'=>false,'reason'=>'not_found']); exit(); }
        if (empty($row['is_active'])) { echo json_encode(['valid'=>false,'reason'=>'inactive']); exit(); }

        $today = new DateTime(); $expiry = new DateTime($row['expiry_date']);
        if ($today > $expiry) { 
            $is_mitra = !empty($row['mitra_id']);
            $mitra_id = $row['mitra_id'] ?? null;
            $m_ui = !empty($mitra_id) && isset($settings['mitra_ui'][$mitra_id]) ? $settings['mitra_ui'][$mitra_id] : $settings;

            $expired_settings = [
                'logo' => $is_mitra ? ($m_ui['mitra_exp_logo'] ?? $settings['mitra_exp_logo'] ?? '⏳') : ($settings['exp_logo'] ?? '⏳'),
                'title' => 'Masa Aktif Berakhir',
                'text' => $is_mitra ? ($m_ui['mitra_exp_text'] ?? $settings['mitra_exp_text'] ?? 'Masa aktif voucher Mitra Anda telah habis. Segera hubungi Mitra Anda.') : ($settings['exp_text'] ?? 'Masa aktif voucher Anda telah habis. Segera perpanjang agar akses tidak terputus.'),
                'btn_text' => $is_mitra ? ($m_ui['mitra_exp_btn_text'] ?? $settings['mitra_exp_btn_text'] ?? 'Hubungi Mitra') : ($settings['exp_btn_text'] ?? 'Perpanjang Sekarang'),
                'btn_link' => $is_mitra ? ($m_ui['mitra_exp_btn_link'] ?? $settings['mitra_exp_btn_link'] ?? '#') : ($settings['exp_btn_link'] ?? '#')
            ];
            $expired_settings['text'] = str_replace('{hari}', '0', $expired_settings['text']);
            $expired_settings['text'] = str_replace('tersisa 0 hari lagi', 'telah habis', $expired_settings['text']);

            echo json_encode(['valid'=>false,'reason'=>'expired','expiry'=>$row['expiry_date'],'expired_settings'=>$expired_settings]); 
            exit(); 
        }

        $active_dev = $row['active_device_id'] ?? null;
        if (!empty($active_dev) && $active_dev !== $device_id) { echo json_encode(['valid'=>false,'reason'=>'device_in_use']); exit(); }

        // Resolve apps
        $pkg = $row['package'] ?? 'basic';
        
        $_SESSION['texa_user_code'] = $code;
        $_SESSION['user_code'] = $code;
        setcookie('texa_user_code', $code, time() + 86400, '/');
        $app_limits = [];
        $activeApps = loadData('applications.json');
        
        $PACKAGES_CONFIG = loadData('packages.json');
        $target_mitra = !empty($row['mitra_id']) ? 'mitra_' . $row['mitra_id'] : 'main';
        $pkg_config = $PACKAGES_CONFIG[$target_mitra] ?? $PACKAGES_CONFIG['main'] ?? [];
        // Extract inner array if the root contains prices config
        if (isset($pkg_config['basic']) && !is_array($pkg_config['basic'])) {
            $pkg_config = $PACKAGES_CONFIG['main'] ?? [];
        }
        
        // If the saved config is completely empty (e.g. from the recent bug), fallback to defaults
        if (empty($pkg_config) || empty($pkg_config['basic'])) {
            $pkg_config = [
                'basic'    => ['google-flow'=>3, 'google-whisk'=>3, 'single-sora'=>1],
                'pro'      => ['google-flow'=>3, 'google-whisk'=>3, 'grok'=>3, 'single-sora'=>1],
                'ultimate' => ['google-flow'=>5, 'google-whisk'=>5, 'grok'=>5, 'single-sora'=>1, 'bulk-sora'=>1],
                'trial'    => ['google-flow'=>1],
            ];
        }
        $allowed_apps = $pkg_config[$pkg] ?? [];

        // Always use the latest max_servers from applications.json to prevent old custom_config cache from restricting servers
        foreach ($activeApps as $a) {
            if (!$a['is_active']) continue;
            
            // If custom_config exists, use it. Otherwise, use the dynamic package configuration.
            if (!empty($row['custom_config']) && is_array($row['custom_config'])) {
                if (!isset($row['custom_config'][$a['id']])) continue;
                $allowed_apps[$a['id']] = $row['custom_config'][$a['id']]; // Override allowed_apps with custom_config
            } else {
                if ($pkg !== 'custom' && !isset($allowed_apps[$a['id']])) continue;
            }
            
            $max_srv = (int)$a['max_servers'];
            if (!empty($a['custom_servers'])) {
                $max_srv = count($a['custom_servers']);
            }
            
            // Apply limits from custom_config or package config if necessary
            if (isset($allowed_apps[$a['id']])) {
                $max_srv = min($max_srv, (int)$allowed_apps[$a['id']]);
            }
            
            if ($max_srv > 0) {
                $app_limits[$a['id']] = $max_srv;
            }
        }

        $apps = [];
        $appsAll = loadData('applications.json');
        // Sort by sort_order
        usort($appsAll, function($a,$b){ return ($a['sort_order']??0) - ($b['sort_order']??0); });
        $protocol = (isset($_SERVER['HTTPS']) && $_SERVER['HTTPS'] === 'on') ? 'https' : 'http';
        $base_url = $protocol . '://' . $_SERVER['HTTP_HOST'] . rtrim(dirname($_SERVER['PHP_SELF']), '/\\');

        foreach ($appsAll as $ra) {
            if (!$ra['is_active']) continue;

            // Determine if this app is locked (user doesn't have access)
            $is_locked = !isset($app_limits[$ra['id']]);
            
            $icon_val = $ra['icon_value'];
            if ($ra['icon_type'] === 'image' && strpos($icon_val, 'http') !== 0) {
                $icon_val = $base_url . '/' . ltrim($icon_val, '/');
            }

            $custom_servers = [];
            if (!$is_locked && !empty($ra['custom_servers']) && is_array($ra['custom_servers'])) {
                foreach ($ra['custom_servers'] as $cs) {
                    $orig_host = parse_url($cs['url'], PHP_URL_HOST);      
                    if (!empty($ra['hide_url']) && !empty(trim($cs['url']))) {
                        $cs['url'] = $base_url . '/go.php/' . get_url_slug($cs['name']);
                    }
                    $cs['original_hostname'] = $orig_host;
                    $custom_servers[] = $cs;
                }
            }

            $final_url = $ra['default_url'];
            if (!$is_locked && !empty($ra['hide_url'])) {
                $final_url = $base_url . '/go.php/' . get_url_slug($ra['name']);
            }

            // Fix bug: Override the servers count to match custom servers count if custom servers exist
            $final_servers_count = $is_locked ? 0 : $app_limits[$ra['id']];
            if (!$is_locked && count($custom_servers) > 0) {
                $final_servers_count = count($custom_servers);
            }

            $app_entry = [
                'id' => $ra['id'], 'name' => $ra['name'],
                'icon_type' => $ra['icon_type'], 'icon_value' => $icon_val,
                'type' => 'grid-app', 'servers' => $final_servers_count, 
                'url' => $is_locked ? '' : $final_url, 'requires_cookie' => $is_locked ? false : (bool)$ra['requires_cookie'],
                'locked' => $is_locked,
                'flow_lock_enabled' => isset($ra['flow_lock_enabled']) ? (bool)$ra['flow_lock_enabled'] : true,
                'flow_unlock_models' => [
                    'lite' => isset($ra['flow_unlock_models']['lite']) ? (bool)$ra['flow_unlock_models']['lite'] : true,
                    'fast' => isset($ra['flow_unlock_models']['fast']) ? (bool)$ra['flow_unlock_models']['fast'] : false,
                    'quality' => isset($ra['flow_unlock_models']['quality']) ? (bool)$ra['flow_unlock_models']['quality'] : false,
                    'lower_priority' => isset($ra['flow_unlock_models']['lower_priority']) ? (bool)$ra['flow_unlock_models']['lower_priority'] : true,
                    'omni_flash' => isset($ra['flow_unlock_models']['omni_flash']) ? (bool)$ra['flow_unlock_models']['omni_flash'] : false
                ],
                'flow_hide_other_projects' => isset($ra['flow_hide_other_projects']) ? (bool)$ra['flow_hide_other_projects'] : true,
                'hidden_elements' => $is_locked ? '' : ($ra['hidden_elements'] ?? ''),
                'custom_servers' => $custom_servers,
                'hide_url' => !$is_locked && !empty($ra['hide_url']),
                'original_hostname' => $is_locked ? '' : parse_url($ra['default_url'], PHP_URL_HOST),
                'app_popup_enabled' => !empty($ra['app_popup_enabled']),
                'app_popup_title' => $ra['app_popup_title'] ?? '',
                'app_popup_content' => $ra['app_popup_content'] ?? ''
            ];
            $apps[] = $app_entry;
        }

        // Update last_used & device
        $members[$rowIdx]['last_used'] = date('Y-m-d H:i:s');
        $members[$rowIdx]['active_device_id'] = $device_id;
        saveData('members.json', $members);

        $desktop_grid_columns = isset($settings['desktop_grid_columns']) ? (int)$settings['desktop_grid_columns'] : 4;
        $is_mitra = !empty($row['mitra_id']);
        $mitra_id = $row['mitra_id'] ?? null;
        $m_ui = !empty($mitra_id) && isset($settings['mitra_ui'][$mitra_id]) ? $settings['mitra_ui'][$mitra_id] : $settings;

        $kick_settings = [
            'logo' => $is_mitra ? ($m_ui['mitra_kick_logo'] ?? $settings['mitra_kick_logo'] ?? '⚠️') : ($settings['kick_logo'] ?? '⚠️'),
            'title' => $is_mitra ? ($m_ui['mitra_kick_title'] ?? $settings['mitra_kick_title'] ?? 'Sesi Berakhir.!!!') : ($settings['kick_title'] ?? 'Sesi Berakhir.!!!'),
            'desc1' => $is_mitra ? ($m_ui['mitra_kick_desc1'] ?? $settings['mitra_kick_desc1'] ?? 'tunggu admin Mitra refresh server.') : ($settings['kick_desc1'] ?? 'tunggu admin TEXA refresh server.'),
            'desc2' => $is_mitra ? ($m_ui['mitra_kick_desc2'] ?? $settings['mitra_kick_desc2'] ?? 'Cek secara berkala dan pastikan report ke grup WA Mitra. Terimakasih!') : ($settings['kick_desc2'] ?? 'Cek secara berkala dan pastikan report ke grup WA. Terimakasih!'),
            'wa_btn' => $is_mitra ? ($m_ui['mitra_kick_wa_btn'] ?? $settings['mitra_kick_wa_btn'] ?? 'Whatssap Mitra') : ($settings['kick_wa_btn'] ?? 'Whatssap GRUP'),
            'wa_link' => $is_mitra ? ($m_ui['mitra_kick_wa_link'] ?? $settings['mitra_kick_wa_link'] ?? 'https://chat.whatsapp.com/') : ($settings['kick_wa_link'] ?? 'https://chat.whatsapp.com/FAg698uVEZOAbOpVLG0FhC'),
            'close_btn' => $is_mitra ? ($m_ui['mitra_kick_close_btn'] ?? $settings['mitra_kick_close_btn'] ?? 'Tutup & Kembali') : ($settings['kick_close_btn'] ?? 'Tutup & Kembali')
        ];

        $show_exp_popup = false;
        $exp_settings = null;
        $trigger_days = (int)($settings['exp_trigger_days'] ?? 3);
        $diff = $today->diff($expiry);
        $days_remaining = $diff->invert ? 0 : $diff->days;
        
        if ($days_remaining <= $trigger_days && $days_remaining >= 0) {
            $show_exp_popup = true;
            $exp_settings = [
                'logo' => $is_mitra ? ($m_ui['mitra_exp_logo'] ?? $settings['mitra_exp_logo'] ?? '⏳') : ($settings['exp_logo'] ?? '⏳'),
                'title' => $is_mitra ? ($m_ui['mitra_exp_title'] ?? $settings['mitra_exp_title'] ?? 'Masa Aktif Hampir Habis!') : ($settings['exp_title'] ?? 'Masa Aktif Hampir Habis!'),
                'text' => str_replace('{hari}', $days_remaining, $is_mitra ? ($m_ui['mitra_exp_text'] ?? $settings['mitra_exp_text'] ?? 'Masa aktif voucher Mitra Anda tersisa {hari} hari lagi. Segera hubungi Mitra Anda.') : ($settings['exp_text'] ?? 'Masa aktif voucher Anda tersisa {hari} hari lagi. Segera perpanjang agar akses tidak terputus.')),
                'btn_text' => $is_mitra ? ($m_ui['mitra_exp_btn_text'] ?? $settings['mitra_exp_btn_text'] ?? 'Hubungi Mitra') : ($settings['exp_btn_text'] ?? 'Perpanjang Sekarang'),
                'btn_link' => $is_mitra ? ($m_ui['mitra_exp_btn_link'] ?? $settings['mitra_exp_btn_link'] ?? '#') : ($settings['exp_btn_link'] ?? '#')
            ];
        }

        // === PROMO POPUP ===
        $promo_popup = null;
        if ($is_mitra && !empty($settings['mitra_promo_active'])) {
            $promo_popup = [
                'video_url' => $settings['mitra_promo_video_url'] ?? '',
                'title' => $settings['mitra_promo_title'] ?? '',
                'desc' => $settings['mitra_promo_desc'] ?? '',
                'btn_text' => $settings['mitra_promo_btn_text'] ?? '',
                'btn_link' => $settings['mitra_promo_btn_link'] ?? '',
            ];
        } elseif (!$is_mitra && !empty($settings['promo_active'])) {
            $promo_popup = [
                'video_url' => $settings['promo_video_url'] ?? '',
                'title' => $settings['promo_title'] ?? '',
                'desc' => $settings['promo_desc'] ?? '',
                'btn_text' => $settings['promo_btn_text'] ?? '',
                'btn_link' => $settings['promo_btn_link'] ?? '',
            ];
        }

        echo json_encode(['valid'=>true,'name'=>$row['name'],'expiry'=>$row['expiry_date'],'package'=>$pkg,'apps'=>$apps,'desktop_grid_columns'=>$desktop_grid_columns,'kick_settings'=>$kick_settings,'show_exp_popup'=>$show_exp_popup,'exp_settings'=>$exp_settings,'promo_popup'=>$promo_popup]);
        exit();
    }

    if ($action === 'logout') {
        $code = trim($_GET['code'] ?? ''); $device_id = trim($_GET['device_id'] ?? '');
        if (!empty($code) && !empty($device_id)) {
            $members = loadData('members.json');
            foreach ($members as $i => $m) {
                if ($m['code'] === $code && ($m['active_device_id'] ?? '') === $device_id) {
                    $members[$i]['active_device_id'] = null;
                    saveData('members.json', $members); break;
                }
            }
        }
        echo json_encode(['success'=>true]); exit();
    }

    // =============================================
    // 🌐 PUBLIC API: get_tools_flow
    // Returns active TOOLS-FLOW list for extension dropdown.
    // Usage: GET /inject/index.php?action=get_tools_flow
    // =============================================
    if ($action === 'get_tools_flow') {
        $current_server = trim($_GET['server'] ?? ''); // optional filter from extension
        $tools = loadData('tools_flow.json');
        // Only active, only public-safe fields
        // NOTE: Always return ALL active tools. Mark `is_locked = true` if current_server
        // is NOT in allowed_servers (so extension can render with lock icon + upgrade popup).
        $output = [];
        foreach ($tools as $t) {
            if (empty($t['is_active'])) continue;
            $allowedServers = $t['allowed_servers'] ?? [];
            if (!is_array($allowedServers)) $allowedServers = [];

            // Lock logic:
            // - allowed_servers EMPTY  → tool tersedia di semua server (NEVER locked)
            // - allowed_servers FILLED → tool hanya untuk server yang dicentang
            //   • current_server kosong (admin / no context) → unlocked
            //   • current_server tidak ada di allowed_servers → LOCKED
            $isLocked = false;
            if (!empty($allowedServers) && $current_server !== '' && !in_array($current_server, $allowedServers, true)) {
                $isLocked = true;
            }

            $output[] = [
                'name' => $t['name'] ?? '',
                'path' => $t['path'] ?? '',
                'description' => $t['description'] ?? '',
                'tutorial_url' => $t['tutorial_url'] ?? '',
                'allowed_servers' => $allowedServers, // empty array = all
                'is_locked' => $isLocked
            ];
        }
        echo json_encode(['success' => true, 'tools' => $output]);
        exit();
    }

    // =============================================
    // 🌐 PUBLIC API: get_flow_locks
    // Returns active custom-element locks for extension to enforce.
    // Usage: GET /inject/index.php?action=get_flow_locks&server=<currentServer>
    // =============================================
    if ($action === 'get_flow_locks') {
        $current_server = trim($_GET['server'] ?? '');
        $globalSettings = loadData('settings.json');
        $masterEnabled = !isset($globalSettings['flow_locks_master_enabled']) || !empty($globalSettings['flow_locks_master_enabled']);
        // Master kill-switch — return empty array so extension wipes all overlays
        if (!$masterEnabled) {
            echo json_encode(['success' => true, 'locks' => [], 'master_enabled' => false]);
            exit();
        }
        $locks = loadData('flow_locks.json');
        if (!is_array($locks)) $locks = [];
        $output = [];
        foreach ($locks as $L) {
            if (empty($L['is_active'])) continue;
            $allowedServers = $L['allowed_servers'] ?? [];
            if (!is_array($allowedServers)) $allowedServers = [];
            // If current server provided AND lock is restricted AND current_server NOT in list → skip
            if ($current_server !== '' && !empty($allowedServers) && !in_array($current_server, $allowedServers, true)) {
                continue;
            }
            $output[] = [
                'id' => $L['id'] ?? '',
                'name' => $L['name'] ?? '',
                'mode' => $L['mode'] ?? 'overlay',
                'message' => $L['message'] ?? '',
                'apply_on' => $L['apply_on'] ?? 'both',
                'signature' => $L['signature'] ?? null
            ];
        }
        echo json_encode(['success' => true, 'locks' => $output, 'master_enabled' => true]);
        exit();
    }

    // =============================================
    // 🌐 PUBLIC API: get_flow_url_blocks
    // Returns active URL block rules for extension to enforce.
    // Usage: GET /inject/index.php?action=get_flow_url_blocks&server=<currentServer>
    // =============================================
    if ($action === 'get_flow_url_blocks') {
        $current_server = trim($_GET['server'] ?? '');
        $globalSettings = loadData('settings.json');
        $masterEnabled = !isset($globalSettings['flow_url_blocks_master_enabled']) || !empty($globalSettings['flow_url_blocks_master_enabled']);
        if (!$masterEnabled) {
            echo json_encode(['success' => true, 'rules' => [], 'master_enabled' => false]);
            exit();
        }
        $rules = loadData('flow_url_blocks.json');
        if (!is_array($rules)) $rules = [];
        $output = [];
        foreach ($rules as $R) {
            if (empty($R['is_active'])) continue;
            $allowedServers = $R['allowed_servers'] ?? [];
            if (!is_array($allowedServers)) $allowedServers = [];
            if ($current_server !== '' && !empty($allowedServers) && !in_array($current_server, $allowedServers, true)) {
                continue;
            }
            $output[] = [
                'id' => $R['id'] ?? '',
                'pattern' => $R['pattern'] ?? '',
                'mode' => $R['mode'] ?? 'exact',
                'redirect_url' => $R['redirect_url'] ?? '',
                'message' => $R['message'] ?? '',
            ];
        }
        echo json_encode(['success' => true, 'rules' => $output, 'master_enabled' => true]);
        exit();
    }

    // =============================================
    // 🌐 PUBLIC API: get_extension_integrity
    // Returns SHA-256 hashes of all tracked extension files.
    // Extension uses this to verify its own files haven't been tampered with.
    // Usage: GET /inject/index.php?action=get_extension_integrity
    // =============================================
    if ($action === 'get_extension_integrity') {
        // HTTP cache: browser dan proxy cache 5 menit. Ini layer tambahan di atas
        // cache 10 menit di sisi extension. Kombinasinya bikin server hit minim
        // bahkan untuk 1000+ user (~360 hit/jam total).
        header('Cache-Control: public, max-age=300, immutable');
        header('Vary: Accept-Encoding');
        $integrity = loadData('extension_integrity.json');
        if (!is_array($integrity) || empty($integrity['hashes'])) {
            // Empty/missing file → tell extension to skip enforcement (avoid lockdown
            // when admin hasn't run generate_integrity.php yet)
            echo json_encode([
                'success' => true,
                'enabled' => false,
                'reason' => 'no_baseline',
                'hashes' => new stdClass()
            ]);
            exit();
        }
        echo json_encode([
            'success' => true,
            'enabled' => true,
            'generated_at' => $integrity['generated_at'] ?? '',
            'hashes' => $integrity['hashes']
        ]);
        exit();
    }

    if ($action === 'log_popup') {
        $code = trim($_GET['code'] ?? 'Unknown');
        $logMsg = date('Y-m-d H:i:s') . " - Popup Expiry ditampilkan untuk user: $code\n";
        file_put_contents(__DIR__ . '/data/popup_logs.txt', $logMsg, FILE_APPEND);
        echo json_encode(['success'=>true]);
        exit();
    }

    // =============================================
    // 🔐 PRIVATE API: validate_permission_code
    // Validates the developer/admin permission code that gates code modification
    // attempts inside the extension. The actual code is stored ONLY in
    // generate_integrity.php (SECRET_KEY). Extension JS never holds it.
    //
    // Usage: GET /inject/index.php?action=validate_permission_code&code=XXXX
    // Response: { valid: true|false }
    // =============================================
    if ($action === 'validate_permission_code') {
        // Pull SECRET_KEY from generate_integrity.php at runtime (single source of truth)
        $secretFile = __DIR__ . '/generate_integrity.php';
        $expected = '';
        if (file_exists($secretFile)) {
            $src = file_get_contents($secretFile);
            if (preg_match('/\$SECRET_KEY\s*=\s*[\'\"]([^\'\"]+)[\'\"]/', $src, $m)) {
                $expected = $m[1];
            }
        }
        $given = trim($_GET['code'] ?? $_POST['code'] ?? '');
        $valid = ($expected !== '' && hash_equals($expected, $given));

        // Audit attempts (success or fail) for incident review
        $logMsg = date('Y-m-d H:i:s') . ' | ' .
            ($valid ? 'OK' : 'FAIL') . ' | ip=' . ($_SERVER['REMOTE_ADDR'] ?? '?') .
            ' | ua=' . substr($_SERVER['HTTP_USER_AGENT'] ?? '?', 0, 120) . "\n";
        @file_put_contents(__DIR__ . '/data/permission_code_audit.txt', $logMsg, FILE_APPEND);

        echo json_encode(['valid' => $valid]);
        exit();
    }

    // =============================================
    // 🌐 PUBLIC API: check_member
    // For external tools to verify if a voucher is active and what package they own.
    // Usage: GET /inject/index.php?action=check_member&code=USER_VOUCHER
    // Response: { valid, code, name, package, is_active, expiry_date, days_remaining,
    //             allowed_features, custom_config }
    // =============================================
    if ($action === 'check_member') {
        $code = trim($_GET['code'] ?? $_POST['code'] ?? '');
        if (empty($code)) {
            echo json_encode(['valid'=>false, 'reason'=>'missing_code', 'message'=>'Parameter "code" wajib diisi.']);
            exit();
        }

        $members = loadData('members.json');
        $found = null;
        foreach ($members as $m) {
            if ($m['code'] === $code) { $found = $m; break; }
        }

        if (!$found) {
            echo json_encode(['valid'=>false, 'reason'=>'not_found', 'message'=>'Voucher tidak ditemukan.']);
            exit();
        }

        $isActive = !empty($found['is_active']);
        $expiry = $found['expiry_date'] ?? null;
        $today = new DateTime('now', new DateTimeZone('Asia/Jakarta'));
        $isExpired = false;
        $daysRemaining = null;
        if (!empty($expiry)) {
            try {
                $exp = new DateTime($expiry, new DateTimeZone('Asia/Jakarta'));
                $diff = $today->diff($exp);
                $daysRemaining = $diff->invert ? -$diff->days : $diff->days;
                $isExpired = $diff->invert; // already past expiry
            } catch (Exception $e) {}
        }

        if (!$isActive) {
            echo json_encode([
                'valid' => false,
                'reason' => 'inactive',
                'message' => 'Voucher dinonaktifkan oleh admin.',
                'code' => $found['code'],
                'package' => $found['package'] ?? null
            ]);
            exit();
        }

        if ($isExpired) {
            echo json_encode([
                'valid' => false,
                'reason' => 'expired',
                'message' => 'Voucher sudah expired pada ' . $expiry . '.',
                'code' => $found['code'],
                'package' => $found['package'] ?? null,
                'expiry_date' => $expiry,
                'days_remaining' => $daysRemaining
            ]);
            exit();
        }

        // Resolve allowed features per package
        $package = $found['package'] ?? 'basic';
        $PACKAGES_CONFIG = loadData('packages.json');
        $target_mitra = !empty($found['mitra_id']) ? 'mitra_' . $found['mitra_id'] : 'main';
        $pkg_config = $PACKAGES_CONFIG[$target_mitra] ?? $PACKAGES_CONFIG['main'] ?? [];
        if (isset($pkg_config['basic']) && !is_array($pkg_config['basic'])) {
            $pkg_config = $PACKAGES_CONFIG['main'] ?? [];
        }
        if (empty($pkg_config) || empty($pkg_config['basic'])) {
            $pkg_config = [
                'basic'    => ['google-flow'=>3, 'google-whisk'=>3, 'single-sora'=>1],
                'pro'      => ['google-flow'=>3, 'google-whisk'=>3, 'grok'=>3, 'single-sora'=>1],
                'ultimate' => ['google-flow'=>5, 'google-whisk'=>5, 'grok'=>5, 'single-sora'=>1, 'bulk-sora'=>1],
                'trial'    => ['google-flow'=>1],
            ];
        }
        $allowed = $pkg_config[$package] ?? [];
        // If member has custom_config, override
        if (!empty($found['custom_config']) && is_array($found['custom_config'])) {
            $allowed = $found['custom_config'];
        }

        echo json_encode([
            'valid' => true,
            'code' => $found['code'],
            'name' => $found['name'] ?? '',
            'package' => $package,
            'is_active' => true,
            'expiry_date' => $expiry,
            'days_remaining' => $daysRemaining,
            'allowed_features' => $allowed,
            'custom_config' => $found['custom_config'] ?? null,
            'is_mitra' => !empty($found['mitra_id']),
            'mitra_id' => $found['mitra_id'] ?? null,
            'created_at' => $found['created_at'] ?? null
        ]);
        exit();
    }

    // =============================================
    // 🌐 PUBLIC API: feature_check
    // Cek apakah voucher punya akses ke fitur/app tertentu.
    // Usage: GET /inject/index.php?action=feature_check&code=USER&feature=google-flow
    // Response: { valid, has_access, feature, max_servers, package }
    // =============================================
    if ($action === 'feature_check') {
        $code = trim($_GET['code'] ?? '');
        $feature = trim($_GET['feature'] ?? '');
        if (empty($code) || empty($feature)) {
            echo json_encode(['valid'=>false, 'reason'=>'missing_params']);
            exit();
        }

        $members = loadData('members.json');
        $found = null;
        foreach ($members as $m) {
            if ($m['code'] === $code) { $found = $m; break; }
        }
        if (!$found || empty($found['is_active'])) {
            echo json_encode(['valid'=>false, 'has_access'=>false, 'reason'=>'invalid_or_inactive']);
            exit();
        }

        // Expiry check
        $expiry = $found['expiry_date'] ?? null;
        if (!empty($expiry) && strtotime($expiry) < time()) {
            echo json_encode(['valid'=>false, 'has_access'=>false, 'reason'=>'expired']);
            exit();
        }

        $package = $found['package'] ?? 'basic';
        $PACKAGES_CONFIG = loadData('packages.json');
        $target_mitra = !empty($found['mitra_id']) ? 'mitra_' . $found['mitra_id'] : 'main';
        $pkg_config = $PACKAGES_CONFIG[$target_mitra] ?? $PACKAGES_CONFIG['main'] ?? [];
        if (isset($pkg_config['basic']) && !is_array($pkg_config['basic'])) {
            $pkg_config = $PACKAGES_CONFIG['main'] ?? [];
        }
        $allowed = $pkg_config[$package] ?? [];
        if (!empty($found['custom_config']) && is_array($found['custom_config'])) {
            $allowed = $found['custom_config'];
        }

        $hasAccess = isset($allowed[$feature]);
        $maxServers = $allowed[$feature] ?? 0;

        echo json_encode([
            'valid' => true,
            'has_access' => $hasAccess,
            'feature' => $feature,
            'max_servers' => (int)$maxServers,
            'package' => $package,
            'code' => $found['code']
        ]);
        exit();
    }

    // =============================================
    // USER PROJECTS TRACKER (per voucher)
    // =============================================
    if ($action === 'save_user_project') {
        $code = trim($_GET['code'] ?? $_POST['code'] ?? '');
        $project_url = trim($_GET['project_url'] ?? $_POST['project_url'] ?? '');
        $server_name = trim($_GET['server_name'] ?? $_POST['server_name'] ?? '');
        $payload_index = $_GET['payload_index'] ?? $_POST['payload_index'] ?? '';
        if ($payload_index !== '') $payload_index = intval($payload_index);
        else $payload_index = null;
        if (empty($code) || empty($project_url)) {
            echo json_encode(['success'=>false,'reason'=>'missing_params']); exit();
        }
        // Validate code exists
        $members = loadData('members.json');
        $valid = false;
        foreach ($members as $m) { if ($m['code'] === $code && !empty($m['is_active'])) { $valid = true; break; } }
        if (!$valid) { echo json_encode(['success'=>false,'reason'=>'invalid_code']); exit(); }

        $userProjects = loadData('user_projects.json');
        if (!isset($userProjects[$code])) $userProjects[$code] = [];

        // Check if already exists
        foreach ($userProjects[$code] as &$p) {
            if ($p['url'] === $project_url) {
                $changed = false;
                // Only set server_name if not already set (lock to original server)
                if (!empty($server_name) && empty($p['server_name'])) {
                    $p['server_name'] = $server_name;
                    $changed = true;
                }
                // Only set payload_index if not already set (lock to original payload/account)
                if ($payload_index !== null && !isset($p['payload_index'])) {
                    $p['payload_index'] = $payload_index;
                    $changed = true;
                }
                if ($changed) saveData('user_projects.json', $userProjects);
                echo json_encode(['success'=>true,'already_exists'=>true]); exit();
            }
        }
        unset($p);

        // Max 10 projects per voucher — but skip PINNED projects from FIFO rotation
        if (count($userProjects[$code]) >= 10) {
            // Find the oldest UNPINNED project to remove
            $oldestUnpinnedIdx = -1;
            foreach ($userProjects[$code] as $idx => $p) {
                if (empty($p['pinned'])) {
                    $oldestUnpinnedIdx = $idx;
                    break; // first one (oldest) since array is in insert order
                }
            }
            if ($oldestUnpinnedIdx !== -1) {
                array_splice($userProjects[$code], $oldestUnpinnedIdx, 1);
            } else {
                // All 10 are pinned — reject save
                echo json_encode([
                    'success' => false,
                    'reason' => 'all_pinned',
                    'message' => 'Semua 10 slot project sudah di-pin. Unpin salah satu untuk membuat project baru.'
                ]);
                exit();
            }
        }

        $entry = [
            'url' => $project_url,
            'created_at' => (new DateTime('now', new DateTimeZone('Asia/Jakarta')))->format('Y-m-d H:i:s'),
            'pinned' => false,
            'custom_name' => ''
        ];
        if (!empty($server_name)) {
            $entry['server_name'] = $server_name;
        }
        if ($payload_index !== null) {
            $entry['payload_index'] = $payload_index;
        }
        $userProjects[$code][] = $entry;
        saveData('user_projects.json', $userProjects);
        echo json_encode(['success'=>true,'total'=>count($userProjects[$code])]); exit();
    }

    // =============================================
    // PIN / UNPIN project
    // =============================================
    if ($action === 'pin_user_project') {
        $code = trim($_GET['code'] ?? $_POST['code'] ?? '');
        $project_url = trim($_GET['project_url'] ?? $_POST['project_url'] ?? '');
        $pinned = isset($_GET['pinned']) ? $_GET['pinned'] : ($_POST['pinned'] ?? '1');
        $pinned = ($pinned === '1' || $pinned === 'true' || $pinned === true);
        if (empty($code) || empty($project_url)) {
            echo json_encode(['success'=>false,'reason'=>'missing_params']); exit();
        }
        $userProjects = loadData('user_projects.json');
        if (!isset($userProjects[$code])) {
            echo json_encode(['success'=>false,'reason'=>'not_found']); exit();
        }
        $found = false;
        foreach ($userProjects[$code] as &$p) {
            if ($p['url'] === $project_url) {
                $p['pinned'] = $pinned;
                $found = true;
                break;
            }
        }
        unset($p);
        if (!$found) {
            echo json_encode(['success'=>false,'reason'=>'project_not_found']); exit();
        }
        saveData('user_projects.json', $userProjects);
        echo json_encode(['success'=>true, 'pinned'=>$pinned]); exit();
    }

    // =============================================
    // RENAME project (set custom_name)
    // =============================================
    if ($action === 'rename_user_project') {
        $code = trim($_GET['code'] ?? $_POST['code'] ?? '');
        $project_url = trim($_GET['project_url'] ?? $_POST['project_url'] ?? '');
        $custom_name = trim($_GET['custom_name'] ?? $_POST['custom_name'] ?? '');
        if (empty($code) || empty($project_url)) {
            echo json_encode(['success'=>false,'reason'=>'missing_params']); exit();
        }
        // Sanity: limit name length
        if (strlen($custom_name) > 80) $custom_name = substr($custom_name, 0, 80);

        $userProjects = loadData('user_projects.json');
        if (!isset($userProjects[$code])) {
            echo json_encode(['success'=>false,'reason'=>'not_found']); exit();
        }
        $found = false;
        foreach ($userProjects[$code] as &$p) {
            if ($p['url'] === $project_url) {
                $p['custom_name'] = $custom_name;
                $found = true;
                break;
            }
        }
        unset($p);
        if (!$found) {
            echo json_encode(['success'=>false,'reason'=>'project_not_found']); exit();
        }
        saveData('user_projects.json', $userProjects);
        echo json_encode(['success'=>true, 'custom_name'=>$custom_name]); exit();
    }

    if ($action === 'get_user_projects') {
        $code = trim($_GET['code'] ?? '');
        if (empty($code)) { echo json_encode(['success'=>false,'reason'=>'missing_code']); exit(); }

        $userProjects = loadData('user_projects.json');
        $projects = $userProjects[$code] ?? [];
        echo json_encode(['success'=>true,'projects'=>$projects,'total'=>count($projects),'max'=>10]); exit();
    }

    if ($action === 'delete_user_project') {
        $code = trim($_GET['code'] ?? $_POST['code'] ?? '');
        $project_url = trim($_GET['project_url'] ?? $_POST['project_url'] ?? '');
        if (empty($code) || empty($project_url)) {
            echo json_encode(['success'=>false,'reason'=>'missing_params']); exit();
        }
        $userProjects = loadData('user_projects.json');
        if (isset($userProjects[$code])) {
            $userProjects[$code] = array_values(array_filter($userProjects[$code], function($p) use ($project_url) {
                return $p['url'] !== $project_url;
            }));
            saveData('user_projects.json', $userProjects);
        }
        echo json_encode(['success'=>true]); exit();
    }

    // =============================================
    // EXTENSION UNINSTALL HANDLER
    // Called by chrome.runtime.setUninstallURL when user uninstalls extension
    // =============================================
    if ($action === 'ext_uninstalled') {
        $code = trim($_GET['code'] ?? '');
        $device_id = trim($_GET['device_id'] ?? '');

        // Log the uninstall event
        $logEntry = (new DateTime('now', new DateTimeZone('Asia/Jakarta')))->format('Y-m-d H:i:s')
            . " | UNINSTALL | code=" . ($code ?: 'unknown')
            . " | device=" . ($device_id ?: 'unknown')
            . " | ip=" . ($_SERVER['REMOTE_ADDR'] ?? 'unknown')
            . " | ua=" . substr($_SERVER['HTTP_USER_AGENT'] ?? '', 0, 200)
            . "\n";
        @file_put_contents(__DIR__ . '/data/uninstall_log.txt', $logEntry, FILE_APPEND);

        // Invalidate the device session — clear active_device_id so user must re-login on new install
        if (!empty($code) && !empty($device_id)) {
            $members = loadData('members.json');
            foreach ($members as $i => $m) {
                if ($m['code'] === $code && ($m['active_device_id'] ?? '') === $device_id) {
                    $members[$i]['active_device_id'] = null;
                    $members[$i]['last_uninstall'] = (new DateTime('now', new DateTimeZone('Asia/Jakarta')))->format('Y-m-d H:i:s');
                    saveData('members.json', $members);
                    break;
                }
            }
        }

        // Show a simple confirmation page
        header('Content-Type: text/html; charset=utf-8');
        echo '<!DOCTYPE html><html><head><meta charset="utf-8"><title>TEKNO APPS Uninstalled</title>';
        echo '<style>body{font-family:Inter,sans-serif;background:#020c18;color:#e8f4ff;display:flex;align-items:center;justify-content:center;min-height:100vh;margin:0;}';
        echo '.card{background:rgba(4,22,48,0.85);border:1px solid rgba(0,150,255,0.18);border-radius:20px;padding:48px;max-width:420px;text-align:center;}';
        echo 'h1{font-size:22px;margin:0 0 12px;background:linear-gradient(135deg,#e0f0ff,#4db8ff);-webkit-background-clip:text;-webkit-text-fill-color:transparent;}';
        echo 'p{color:#7aaed4;font-size:13px;line-height:1.6;}</style></head><body>';
        echo '<div class="card"><h1>👋 TEKNO APPS Telah Dihapus</h1>';
        echo '<p>Sesi Anda telah diakhiri dan device telah di-unregister dari server.</p>';
        echo '<p style="font-size:11px;color:#4a7a9b;margin-top:24px;">Untuk menggunakan kembali, install ulang ekstensi dan login dengan voucher Anda.</p>';
        echo '</div></body></html>';
        exit();
    }

    if ($action === 'get_cookies') {
        $code = trim($_GET['code'] ?? ''); $device_id = trim($_GET['device_id'] ?? '');
        $app_id = trim($_GET['app_id'] ?? ''); $server_index = intval($_GET['server_index'] ?? 0);
        if (empty($code)||empty($device_id)||empty($app_id)||$server_index<1) { echo json_encode(['valid'=>false,'reason'=>'invalid_params']); exit(); }

        $members = loadData('members.json');
        $user = null;
        foreach ($members as $m) { if ($m['code'] === $code) { $user = $m; break; } }
        
        $is_mitra = $user && !empty($user['mitra_id']);
        $mitra_id = $user['mitra_id'] ?? null;
        $m_ui = !empty($mitra_id) && isset($settings['mitra_ui'][$mitra_id]) ? $settings['mitra_ui'][$mitra_id] : $settings;

        $kick_settings = [
            'logo' => $is_mitra ? ($m_ui['mitra_kick_logo'] ?? $settings['mitra_kick_logo'] ?? '⚠️') : ($settings['kick_logo'] ?? '⚠️'),
            'title' => $is_mitra ? ($m_ui['mitra_kick_title'] ?? $settings['mitra_kick_title'] ?? 'Sesi Berakhir.!!!') : ($settings['kick_title'] ?? 'Sesi Berakhir.!!!'),
            'desc1' => $is_mitra ? ($m_ui['mitra_kick_desc1'] ?? $settings['mitra_kick_desc1'] ?? 'tunggu admin Mitra refresh server.') : ($settings['kick_desc1'] ?? 'tunggu admin TEXA refresh server.'),
            'desc2' => $is_mitra ? ($m_ui['mitra_kick_desc2'] ?? $settings['mitra_kick_desc2'] ?? 'Cek secara berkala dan pastikan report ke grup WA Mitra. Terimakasih!') : ($settings['kick_desc2'] ?? 'Cek secara berkala dan pastikan report ke grup WA. Terimakasih!'),
            'wa_btn' => $is_mitra ? ($m_ui['mitra_kick_wa_btn'] ?? $settings['mitra_kick_wa_btn'] ?? 'Whatssap Mitra') : ($settings['kick_wa_btn'] ?? 'Whatssap GRUP'),
            'wa_link' => $is_mitra ? ($m_ui['mitra_kick_wa_link'] ?? $settings['mitra_kick_wa_link'] ?? 'https://chat.whatsapp.com/') : ($settings['kick_wa_link'] ?? 'https://chat.whatsapp.com/FAg698uVEZOAbOpVLG0FhC'),
            'close_btn' => $is_mitra ? ($m_ui['mitra_kick_close_btn'] ?? $settings['mitra_kick_close_btn'] ?? 'Tutup & Kembali') : ($settings['kick_close_btn'] ?? 'Tutup & Kembali')
        ];

        // Members input by Mitra are fully accessible by the extension just like any other member
        if (!$user || empty($user['is_active']) || (!empty($user['active_device_id']) && $user['active_device_id'] !== $device_id) || (new DateTime() > new DateTime($user['expiry_date']))) {
            echo json_encode(['valid'=>false,'reason'=>'unauthorized', 'kick_settings'=>$kick_settings]); exit();
        }

        // Set session variables
        $_SESSION['texa_user_code'] = $code;
        $_SESSION['user_code'] = $code;
        setcookie('texa_user_code', $code, time() + 86400, '/');

        $cookies = loadData('cookies.json');
        $cookieData = null; $targetUrl = '';
        foreach ($cookies as $c) {
            if ($c['app_id'] === $app_id && (int)$c['server_index'] === $server_index) {
                $cookieData = $c['cookie_data']; $targetUrl = $c['target_url'] ?? ''; break;
            }
        }
        
        $payloads = [];
        if (isset($cookieData[0]) && is_array($cookieData[0]) && !isset($cookieData[0]['name'])) {
            $payloads = $cookieData;
            $first_payload = $payloads[0] ?? [];
        } else {
            $payloads = [$cookieData];
            $first_payload = $cookieData;
        }
        
        $appsAll = loadData('applications.json');
        foreach ($appsAll as $ra) {
            if ($ra['id'] === $app_id && !empty($ra['hide_url'])) {
                $protocol = (isset($_SERVER['HTTPS']) && $_SERVER['HTTPS'] === 'on') ? 'https' : 'http';
                $base_url = $protocol . '://' . $_SERVER['HTTP_HOST'] . rtrim(dirname($_SERVER['PHP_SELF']), '/\\');
                
                // If there is no targetUrl from cookies.json, we must resolve it from custom_servers or default_url
                if (empty($targetUrl)) {
                    if (!empty($ra['custom_servers']) && isset($ra['custom_servers'][$server_index - 1])) {
                        // Avoid grabbing an empty string if custom_servers array has a blank url
                        $targetUrl = !empty(trim($ra['custom_servers'][$server_index - 1]['url'])) ? $ra['custom_servers'][$server_index - 1]['url'] : $ra['default_url'];
                    } else {
                        $targetUrl = $ra['default_url'];
                    }
                }
                
                // If it's empty even after falling back, don't encrypt    
                if (!empty($targetUrl)) {
                    $slug = get_url_slug($ra['name']);
                    if (!empty($ra['custom_servers']) && isset($ra['custom_servers'][$server_index - 1])) {
                        if (!empty(trim($ra['custom_servers'][$server_index - 1]['name']))) {
                            $slug = get_url_slug($ra['custom_servers'][$server_index - 1]['name']);
                        }
                    }
                    
                    // Simpan URL asli yang spesifik untuk sesi server ini (mengatasi target_url dari cookies.json yang berbeda)
                    $_SESSION['texa_target_url_' . $slug] = $targetUrl;
                    
                    // Juga buat cookie file temporary/session fallback
                    setcookie('texa_target_url_' . $slug, $targetUrl, time() + 3600, '/');
                    
                    if (!is_array($first_payload)) $first_payload = [];
                    // Strip port from domain (Chrome cookies API does not accept ports)
                    $_cookie_host = preg_replace('/:\d+$/', '', $_SERVER['HTTP_HOST']);
                    $_is_secure = (!empty($_SERVER['HTTPS']) && $_SERVER['HTTPS'] !== 'off');
                    $target_cookie = [
                        'domain' => $_cookie_host,
                        'expirationDate' => time() + 3600,
                        'name' => 'texa_target_url_' . $slug,
                        'path' => '/',
                        'sameSite' => $_is_secure ? 'no_restriction' : 'lax',
                        'secure' => $_is_secure,
                        'value' => $targetUrl
                    ];
                    $first_payload[] = $target_cookie;
                    
                    // Append to all payloads
                    foreach ($payloads as &$p) {
                        if (is_array($p)) $p[] = $target_cookie;
                    }
                    
                    // PENTING: Untuk keperluan injeksi cookie di background.js (via API),
                    // target_url HARUS dikirim sebagai URL asli agar domain cookie-nya benar.
                    // Redirect / URL masking via go.php akan diatur secara mandiri 
                    // pada saat render UI oleh ekstensi.
                    // $targetUrl = $base_url . '/go.php/' . $slug; // <- KITA NONAKTIFKAN INI DI API RESPONSE
                }
                break;
            }
        }

        if (!is_array($first_payload)) {
            $first_payload = [];
        }
        $user_code_cookie = [
            'domain' => $_SERVER['HTTP_HOST'],
            'expirationDate' => time() + 86400,
            'name' => 'texa_user_code',
            'path' => '/',
            'sameSite' => 'no_restriction',
            'secure' => true,
            'value' => $code
        ];
        $first_payload[] = $user_code_cookie;
        
        foreach ($payloads as &$p) {
            if (is_array($p)) $p[] = $user_code_cookie;
        }
        
        // Update the first payload in the array
        if (!empty($payloads)) {
            $payloads[0] = $first_payload;
        } else {
            $payloads = [$first_payload];
        }

        echo json_encode(['valid'=>true,'cookies'=>$first_payload, 'cookie_payloads'=>$payloads, 'target_url'=>$targetUrl]); exit();
    }

    if ($action === 'save_cookies') {
        $r_role = $_SESSION['admin_role'] ?? 'admin';
        $r_perms = $_SESSION['permissions'] ?? ['tab_cookies' => true];
        if ($r_role !== 'owner' && empty($r_perms['tab_cookies']) && empty($r_perms['inject_cookies'])) {
            echo json_encode(['success'=>false,'message'=>'Akses Ditolak: Anda tidak memiliki izin untuk Inject Cookies.']); exit();
        }

        $app_id = trim($_POST['app_id'] ?? ''); $server_index = intval($_POST['server_index'] ?? 0);
        $target_url = trim($_POST['target_url'] ?? ''); $cookie_data_raw = trim($_POST['cookie_data'] ?? '');
        if (empty($app_id)||$server_index<1||empty($cookie_data_raw)) { echo json_encode(['success'=>false,'message'=>'Parameter wajib diisi']); exit(); }

        $clean = stripslashes($cookie_data_raw);
        $parsed = json_decode($clean, true);
        if (json_last_error() !== JSON_ERROR_NONE) $parsed = json_decode($cookie_data_raw, true);
        if (json_last_error() !== JSON_ERROR_NONE || !is_array($parsed)) {
            echo json_encode(['success'=>false,'message'=>'Format JSON tidak valid: '.json_last_error_msg()]); exit();
        }

        // Determine if it's an array of payloads or a single payload
        $is_multiple = true;
        // Check if the root element is an array of arrays (multiple payloads)
        if (!is_array($parsed) || !isset($parsed[0]) || !is_array($parsed[0])) {
             $is_multiple = false;
        } else {
             // It's an array of arrays. Let's check the first element.
             // If the first element has 'name' and 'value', it's a single payload of cookies.
             if (isset($parsed[0]['name']) && isset($parsed[0]['value'])) {
                 $is_multiple = false;
             }
        }

        $final_payloads = [];
        if (!$is_multiple) {
            // Single payload logic
            if (isset($parsed['cookies']) && is_array($parsed['cookies'])) {
                $parsed = $parsed['cookies'];
            } elseif (isset($parsed[0]) && is_array($parsed[0]) && isset($parsed[0]['cookies'])) {
                $parsed = $parsed[0]['cookies'];
            }
            // Ensure it's a direct array of objects
            $parsed = array_values($parsed);
            $final_payloads = [$parsed];
        } else {
            // Multiple payloads logic
            foreach ($parsed as $p) {
                if (isset($p['cookies']) && is_array($p['cookies'])) {
                    $p = $p['cookies'];
                } elseif (isset($p[0]) && is_array($p[0]) && isset($p[0]['cookies'])) {
                    $p = $p[0]['cookies'];
                }
                $final_payloads[] = array_values($p);
            }
        }

        $cookies = loadData('cookies.json');
        $found = false;
        foreach ($cookies as $i => $c) {
            if ($c['app_id'] === $app_id && (int)$c['server_index'] === $server_index) {
                $cookies[$i]['cookie_data'] = $final_payloads;
                $cookies[$i]['target_url'] = $target_url;
                $cookies[$i]['updated_by'] = $_SESSION['user_name'] ?? 'System';
                $cookies[$i]['updated_at'] = date('Y-m-d H:i:s');
                $found = true; break;
            }
        }
        if (!$found) $cookies[] = ['app_id'=>$app_id,'server_index'=>$server_index,'target_url'=>$target_url,'cookie_data'=>$final_payloads, 'updated_by'=>$_SESSION['user_name'] ?? 'System', 'updated_at'=>date('Y-m-d H:i:s')];
        saveData('cookies.json', $cookies);
        echo json_encode(['success'=>true, 'payloads_count' => count($final_payloads), 'payload_data' => $final_payloads]); exit();
    }
    
    if ($action === 'get_cookies_info') {
        $app_id = $_GET['app_id'] ?? '';
        $server_index = (int)($_GET['server_index'] ?? 0);
        $cookies = loadData('cookies.json');
        foreach ($cookies as $c) {
            if ($c['app_id'] === $app_id && (int)$c['server_index'] === $server_index) {
                echo json_encode(['success' => true, 'data' => $c]);
                exit();
            }
        }
        echo json_encode(['success' => false]);
        exit();
    }
    
    if ($action === 'get_catalog_url') {
        $settings = loadData('settings.json');
        $catalog_url = $settings['catalog_url'] ?? '';
        
        // Ambil data aplikasi aktif untuk di-loop
        $appsAll = loadData('applications.json');
        $activeApps = [];
        foreach ($appsAll as $app) {
            if ($app['is_active']) {
                $activeApps[] = [
                    'name' => $app['name'],
                    'icon_type' => $app['icon_type'],
                    'icon_value' => $app['icon_value'],
                    'is_active' => true
                ];
            }
        }
        
        echo json_encode(['url' => $catalog_url, 'apps' => $activeApps]);
        exit();
    }

    echo json_encode(['valid'=>false,'reason'=>'invalid_action']); exit();
}

// =============================================
// RBAC & SESSION MANAGEMENT
// =============================================
// Export Deposit History
if (isset($_GET['action']) && $_GET['action'] === 'export_deposit_history') {
    $dh = loadData('deposit_history.json');
    usort($dh, function($a, $b) { return strtotime($b['date']) - strtotime($a['date']); });
    
    header('Content-Type: text/csv; charset=utf-8');
    header('Content-Disposition: attachment; filename=riwayat_semua_saldo_deposit.csv');
    $output = fopen('php://output', 'w');
    fputcsv($output, ['ID', 'Tanggal', 'Mitra ID', 'Jumlah (Rp)', 'Saldo Sebelum (Rp)', 'Saldo Sesudah (Rp)', 'Catatan', 'Oleh']);
    
    foreach ($dh as $row) {
        fputcsv($output, [
            $row['id'] ?? '',
            $row['date'] ?? '',
            $row['mitra_id'] ?? '',
            $row['amount'] ?? 0,
            $row['balance_before'] ?? 0,
            $row['balance_after'] ?? 0,
            $row['note'] ?? '',
            $row['by'] ?? ''
        ]);
    }
    fclose($output);
    exit;
}

if (isset($_GET['logout'])) {
    session_destroy();
    header('Location: ?');
    exit;
}

// Ensure users.json exists with default credentials if missing
$usersFile = 'data/users.json';
if (!file_exists('data')) { mkdir('data', 0755, true); }
if (!file_exists($usersFile)) {
    $defaultUsers = [
        ['id' => 1, 'role' => 'owner', 'name' => 'Owner System', 'password_hash' => password_hash('4rg0v14n', PASSWORD_BCRYPT), 'created_at' => date('Y-m-d H:i:s')],
        ['id' => 2, 'role' => 'admin', 'name' => 'Admin Default', 'password_hash' => password_hash('asu123', PASSWORD_BCRYPT), 'created_at' => date('Y-m-d H:i:s')]
    ];
    file_put_contents($usersFile, json_encode($defaultUsers, JSON_PRETTY_PRINT));
}

// Simple Rate Limiting for Login
$settings = loadData('settings.json');
$lockout_minutes = (int)($settings['mitra_lockout_minutes'] ?? 15);
$lockout_seconds = $lockout_minutes * 60;
$max_attempts = (int)($settings['mitra_max_attempts'] ?? 5);

$loginAttemptsFile = 'data/login_attempts.json';
function checkRateLimit() {
    global $loginAttemptsFile, $lockout_seconds, $max_attempts;
    $ip = $_SERVER['REMOTE_ADDR'];
    $attempts = file_exists($loginAttemptsFile) ? json_decode(file_get_contents($loginAttemptsFile), true) : [];
    
    // Clean old attempts
    $now = time();
    foreach ($attempts as $key => $time) {
        if ($now - $time > $lockout_seconds) unset($attempts[$key]);
    }
    
    $ipAttempts = array_filter($attempts, function($k) use ($ip) { return strpos($k, $ip) === 0; }, ARRAY_FILTER_USE_KEY);
    
    if (count($ipAttempts) >= $max_attempts) {
        file_put_contents($loginAttemptsFile, json_encode($attempts));
        return false; // Blocked
    }
    return true;
}

function recordLoginAttempt() {
    global $loginAttemptsFile;
    $ip = $_SERVER['REMOTE_ADDR'];
    $attempts = file_exists($loginAttemptsFile) ? json_decode(file_get_contents($loginAttemptsFile), true) : [];
    $attempts[$ip . '_' . time()] = time();
    file_put_contents($loginAttemptsFile, json_encode($attempts));
}

$login_error = '';
if ($_SERVER['REQUEST_METHOD'] === 'POST' && isset($_POST['login_password'])) {
    if (!checkRateLimit()) {
        $login_error = "Terlalu banyak percobaan. Coba lagi dalam {$lockout_minutes} menit.";
    } else {
        $pass = $_POST['login_password'] ?? '';
        $users = json_decode(file_get_contents($usersFile), true);
        $loggedIn = false;
        
        foreach ($users as $user) {
            if (password_verify($pass, $user['password_hash'])) {
                if ($user['role'] === 'mitra') {
                    $login_error = 'Akun mitra harus login melalui Portal Mitra (/mitra).';
                    continue;
                }
                
                $_SESSION['admin_logged_in'] = true;
                $_SESSION['admin_role'] = $user['role'];
                $_SESSION['user_id'] = $user['id'];
                $_SESSION['user_name'] = $user['name'] ?? ucfirst($user['role']);
                
                // Load permissions
                if ($user['role'] === 'mitra') {
                    $perms = [
                        'add_member' => true,
                        'edit_member' => false,
                        'inject_cookies' => false,
                        'view_stats' => true
                    ];
                    $_SESSION['commission_rate'] = $user['commission_rate'] ?? 0;
                    $_SESSION['balance'] = $user['balance'] ?? 0;
                } else {
                    $perms = $user['permissions'] ?? [
                        'add_member' => true,
                        'edit_member' => true,
                        'inject_cookies' => true,
                        'view_stats' => true
                    ];
                }
                $_SESSION['permissions'] = $perms;

                $loggedIn = true;
                header('Location: ?');
                exit;
            }
        }
        
        if (!$loggedIn) {
            recordLoginAttempt();
            $login_error = 'Password salah!';
        }
    }
}

if (empty($_SESSION['admin_logged_in'])) {
?>
<!DOCTYPE html>
<html lang="id">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Login - TEKNO-APPS Admin</title>
    <link href="https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600;700;800&display=swap" rel="stylesheet"/>
    <style>
        :root { --bg: #001020; --deep: #020c18; --border: rgba(0,150,255,.18); --text: #e8f4ff; --bright: #0099ff; --muted: #4a7a9b; }
        body { background: var(--deep); color: var(--text); font-family: 'Inter', sans-serif; display: flex; justify-content: center; align-items: center; height: 100vh; margin: 0; }
        body::before{content:"";position:fixed;inset:0;pointer-events:none;background:radial-gradient(ellipse at 50% 50%,rgba(0,80,180,.15) 0%,transparent 70%);}
        .login-card { background: rgba(4,22,48,.85); padding: 40px; border-radius: 15px; border: 1px solid var(--border); width: 100%; max-width: 360px; box-shadow: 0 10px 40px rgba(0,0,0,0.5); text-align: center; position: relative; z-index: 1; backdrop-filter: blur(12px); }
        .logo { width: 50px; height: 50px; border-radius: 14px; background: linear-gradient(135deg,#0044cc,#0099ff); display: inline-flex; align-items: center; justify-content: center; font-size: 18px; font-weight: 900; box-shadow: 0 0 18px rgba(0,150,255,.4); margin-bottom: 15px; }
        .login-card h2 { color: #a8d8ff; margin-top: 0; margin-bottom: 5px; font-size: 20px; font-weight: 800; }
        .login-card p { font-size: 12px; color: var(--muted); margin-bottom: 25px; }
        input { width: 100%; padding: 12px 15px; margin-bottom: 15px; border: 1px solid var(--border); background: rgba(0,20,50,0.6); color: var(--text); border-radius: 8px; box-sizing: border-box; outline: none; font-family: 'Inter', sans-serif; font-size: 13px; transition: all 0.2s; text-align: center; letter-spacing: 2px;}
        input:focus { border-color: var(--bright); box-shadow: 0 0 0 3px rgba(0,150,255,.15); }
        button { width: 100%; padding: 12px; background: linear-gradient(135deg,#0055cc,#0088ff); color: white; border: none; border-radius: 8px; cursor: pointer; font-weight: 700; font-size: 14px; transition: 0.3s; box-shadow: 0 4px 14px rgba(0,100,255,.3); }
        button:hover { transform: translateY(-1px); box-shadow: 0 6px 20px rgba(0,120,255,.4); }
        .err { color: #ff4d4d; font-size: 12px; margin-bottom: 15px; background: rgba(255,77,77,.1); border: 1px solid rgba(255,77,77,.3); padding: 10px; border-radius: 6px; }
    </style>
</head>
<body>
    <div class="login-card">
        <div class="logo">TX</div>
        <h2>Admin Dashboard</h2>
        <p>Masukkan kata sandi akses Anda</p>
        <?php if($login_error) echo '<div class="err">'.$login_error.'</div>'; ?>
        <form method="POST">
            <input type="password" name="login_password" placeholder="••••••••" required autofocus autocomplete="off">
            <button type="submit">MASUK</button>
        </form>
    </div>

</body>
</html>
<?php
    exit;
}

// Role-based Authorization Middleware
$role = $_SESSION['admin_role'] ?? 'admin';
$tab = $_GET['tab'] ?? 'members';

// Default perms if owner, or load from session
if ($role === 'owner') {
    $user_perms = [
        'add_member' => true, 'edit_member' => true, 'view_stats' => true,
        'tab_members' => true, 'tab_apps' => true, 'tab_cookies' => true,
        'tab_packages' => true, 'tab_settings' => true, 'tab_users' => true, 'tab_mitras' => true, 'tab_audit' => true,
        'tab_notepad' => true
    ];
} else {
    $user_perms = $_SESSION['permissions'] ?? [
        'add_member' => true, 'edit_member' => true, 'view_stats' => true,
        'tab_members' => true, 'tab_apps' => false, 'tab_cookies' => false, 'tab_notepad' => false,
        'tab_packages' => false, 'tab_settings' => false, 'tab_users' => false, 'tab_mitras' => false, 'tab_audit' => false
    ];
    // Backward compatibility for old inject_cookies perm
    if (isset($_SESSION['permissions']['inject_cookies']) && !isset($_SESSION['permissions']['tab_cookies'])) {
        $user_perms['tab_cookies'] = $_SESSION['permissions']['inject_cookies'];
    }
}

// Admin is restricted to allowed tabs
if ($role === 'admin') {
    $allowed_tabs = [];
    if (!empty($user_perms['tab_members'])) $allowed_tabs[] = 'members';
    if (!empty($user_perms['tab_apps'])) $allowed_tabs[] = 'apps';
    if (!empty($user_perms['tab_cookies'])) $allowed_tabs[] = 'cookies';
    if (!empty($user_perms['tab_packages'])) $allowed_tabs[] = 'packages';
    if (!empty($user_perms['tab_settings'])) $allowed_tabs[] = 'settings';
    if (!empty($user_perms['tab_users'])) $allowed_tabs[] = 'users';
    if (!empty($user_perms['tab_mitras'])) $allowed_tabs[] = 'mitras';
    if (!empty($user_perms['tab_audit'])) $allowed_tabs[] = 'audit';
    if (!empty($user_perms['tab_notepad'])) $allowed_tabs[] = 'notepad';
    
    // If no tabs allowed, fallback to members to avoid redirect loop if they somehow have no perms
    if (empty($allowed_tabs)) $allowed_tabs[] = 'members';

    if (!in_array($tab, $allowed_tabs)) {
        $first_allowed = $allowed_tabs[0];
        header('HTTP/1.1 403 Forbidden');
        die('<h2>403 - Akses Ditolak</h2><p>Anda tidak memiliki izin untuk mengakses halaman ini.</p><a href="?tab='.$first_allowed.'">Kembali</a>');
    }
}

// Mitra is restricted to allowed tabs
if ($role === 'mitra') {
    $allowed_tabs = ['members', 'mitradashboard'];
    // Allow 'mitras' temporarily if returning to owner
    if (isset($_SESSION['original_owner_id']) && $tab === 'mitras') {
        $allowed_tabs[] = 'mitras';
    }
    if (!in_array($tab, $allowed_tabs)) {
        header('HTTP/1.1 403 Forbidden');
        die('<h2>403 - Akses Ditolak</h2><p>Anda tidak memiliki izin untuk mengakses halaman ini.</p><a href="?tab=members">Kembali</a>');
    }
}

// Action restriction for admin & mitra
if (($role === 'admin' || $role === 'mitra') && $_SERVER['REQUEST_METHOD'] === 'POST') {
    $action = $_POST['action'] ?? '';
    $allowed_admin_actions = [];
    if (!empty($user_perms['add_member'])) $allowed_admin_actions[] = 'add';
    if (!empty($user_perms['edit_member'])) {
        $allowed_admin_actions[] = 'update';
        $allowed_admin_actions[] = 'toggle';
        $allowed_admin_actions[] = 'delete';
        $allowed_admin_actions[] = 'bulk_lunas';
    }
    
    if ($role === 'admin') {
        if (!empty($user_perms['tab_apps'])) {
            $allowed_admin_actions = array_merge($allowed_admin_actions, ['add_app', 'update_app', 'toggle_app', 'delete_app']);
        }
        if (!empty($user_perms['tab_cookies'])) {
            $allowed_admin_actions[] = 'save_cookies'; // assuming this is the action, though it might be AJAX
        }
        if (!empty($user_perms['tab_packages'])) {
            $allowed_admin_actions[] = 'save_packages';
        }
        if (!empty($user_perms['tab_settings'])) {
            $allowed_admin_actions[] = 'save_settings';
        }
        if (!empty($user_perms['tab_users'])) {
            $allowed_admin_actions = array_merge($allowed_admin_actions, ['add_admin', 'delete_user', 'change_pass', 'update_perms']);
        }
        if (!empty($user_perms['tab_mitras'])) {
            $allowed_admin_actions = array_merge($allowed_admin_actions, ['add_mitra', 'update_mitra_detail', 'login_as_mitra', 'delete_user', 'topup_deposit', 'update_mitra_deposit', 'reset_data_mitra']);
        }
        if (!empty($user_perms['tab_notepad'])) {
            $allowed_admin_actions = array_merge($allowed_admin_actions, ['save_note', 'save_account', 'delete_account']);
        }
    }
    
    // allow return_to_owner if they are impersonating
    if (isset($_SESSION['original_owner_id'])) {
        $allowed_admin_actions[] = 'return_to_owner';
    }
    
    if ($action !== '' && !in_array($action, $allowed_admin_actions)) {
         // Some actions might be handled by ajax directly without 'action' field, or maybe 'inject_cookies' is an ajax call.
         header('HTTP/1.1 403 Forbidden');
         die('403 - Akses Ditolak untuk aksi ini. ('.$action.')');
    }
}

// =============================================
// ADMIN PANEL MODE - HTML UI
// =============================================
$msg = ''; $msgType = '';
if (isset($_SESSION['flash_msg'])) {
    $msg = $_SESSION['flash_msg'];
    $msgType = $_SESSION['flash_msgType'] ?? 'info';
    unset($_SESSION['flash_msg'], $_SESSION['flash_msgType']);
}

// Reload apps for admin (include inactive)
$allAppsForAdmin = loadData('applications.json');
usort($allAppsForAdmin, function($a,$b){ return ($a['sort_order']??0) - ($b['sort_order']??0); });
// Rebuild labels with ALL apps for admin forms
$APP_LABELS_ALL = [];
$APP_MAX_ALL = [];
foreach ($allAppsForAdmin as $app) {
    $APP_LABELS_ALL[$app['id']] = $app['name'];
    $APP_MAX_ALL[$app['id']] = (int)$app['max_servers'];
}

// Edit fetch
$editData = null;
if (isset($_GET['edit'])) {
    $eid = (int)$_GET['edit'];
    $members = loadData('members.json');
    foreach ($members as $m) { if ($m['id'] === $eid) { $editData = $m; break; } }
}


// =============================================
// EXT_VERSION.JSON UPLOAD & DELETE HANDLERS
// =============================================
if ($_SERVER['REQUEST_METHOD'] === 'POST' && isset($_POST['upload_ext_version'])) {
    if (isset($_FILES['ext_version_file']) && $_FILES['ext_version_file']['error'] === UPLOAD_ERR_OK) {
        $tmp = $_FILES['ext_version_file']['tmp_name'];
        $content = file_get_contents($tmp);
        $parsed = json_decode($content, true);
        if ($parsed && isset($parsed['version'])) {
            ensureDataDir();
            $dest = DATA_DIR . '/ext_version.json';
            file_put_contents($dest, json_encode($parsed, JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE), LOCK_EX);
            // Auto-sync ke settings.json
            $settings['ext_latest_version'] = $parsed['version'];
            saveData('settings.json', $settings);
            $_SESSION['flash_msg'] = '✅ ext_version.json berhasil diupload! Versi terbaru: v' . htmlspecialchars($parsed['version']);
        } else {
            $_SESSION['flash_msg'] = '❌ File JSON tidak valid atau tidak memiliki field "version".';
        }
    } else {
        $_SESSION['flash_msg'] = '❌ Gagal upload file.';
    }
    header('Location: ' . $_SERVER['REQUEST_URI']);
    exit();
}

if ($_SERVER['REQUEST_METHOD'] === 'POST' && isset($_POST['action_delete_ext_version'])) {
    $ev_target = DATA_DIR . '/ext_version.json';
    if (file_exists($ev_target)) {
        unlink($ev_target);
        $_SESSION['flash_msg'] = '✅ ext_version.json dihapus. Mode manual aktif.';
    }
    header('Location: ' . $_SERVER['REQUEST_URI']);
    exit();
}

if ($_SERVER['REQUEST_METHOD'] === 'POST' && isset($_POST['action'])) {

    $pa = $_POST['action'];

    if ($pa === 'add') {
        $name = trim($_POST['name'] ?? ''); $days = (int)($_POST['days'] ?? 7);
        $custom_code = trim($_POST['custom_code'] ?? '');
        $pkg = $_POST['package'] ?? 'basic';
        if (!array_key_exists($pkg, $PKG_LABELS)) $pkg = 'basic';
        
        $cfg = [];
        if ($pkg === 'custom') {
            foreach ($APP_LABELS_ALL as $aid => $_) {
                if (isset($_POST["app_{$aid}"])) {
                    $sv = (int)($_POST["srv_{$aid}"] ?? 1);
                    $cfg[$aid] = max(1, min($APP_MAX_ALL[$aid] ?? 1, $sv));
                }
            }
        }
        $custom_cfg = !empty($cfg) ? $cfg : null;
        if (empty($name) || $days < 1) { $msg='Nama wajib diisi dan durasi minimal 1 hari.'; $msgType='error'; }
        else {
            $members = loadData('members.json');
            $code = !empty($custom_code) ? $custom_code : generateCode();
            
            // Check uniqueness of code
            $codeExists = false;
            foreach ($members as $m) { if ($m['code'] === $code) { $codeExists = true; break; } }
            
            if ($codeExists) { 
                $msg='Kode akses sudah digunakan, coba lagi.'; $msgType='error'; 
            } else {
                global $pkg_prices, $PACKAGES_CONFIG;
                // If manual price is set, use it. Otherwise, calculate based on package base price and days
                $manual_price_input = trim($_POST['manual_price'] ?? '');
                if ($manual_price_input !== '') {
                    $revenue = (int)$manual_price_input;
                } else {
                    $mitra_id_key = ($_SESSION['admin_role'] === 'mitra') ? 'mitra_' . $_SESSION['user_id'] . '_prices' : null;
                    $current_pkg_prices = $pkg_prices;
                    if ($mitra_id_key && isset($PACKAGES_CONFIG[$mitra_id_key])) {
                        $current_pkg_prices = $PACKAGES_CONFIG[$mitra_id_key];
                    }
                    $base_price = $current_pkg_prices[$pkg] ?? 0;
                    $revenue = (int)round(($base_price / 30) * $days);
                }
                
                $payment_status = $_POST['payment_status'] ?? 'lunas';
                if ($_SESSION['admin_role'] === 'mitra') {
                    $payment_status = 'belum_lunas'; // Force Mitra entries to un-paid by default
                }
                $members[] = ['id'=>nextId($members),'code'=>$code,'name'=>$name,'expiry_date'=>date('Y-m-d',strtotime("+{$days} days")),'package'=>$pkg,'custom_config'=>$custom_cfg,'is_active'=>1,'created_at'=>date('Y-m-d H:i:s'),'last_used'=>null,'active_device_id'=>null,'price_paid'=>$revenue, 'payment_status'=>$payment_status, 'created_by'=>$_SESSION['user_name'] ?? 'System', 'updated_by'=>null, 'mitra_id'=> ($_SESSION['admin_role'] === 'mitra' ? $_SESSION['user_id'] : null)];
                saveData('members.json', $members);
                
                // Update mitra balance if added by mitra
                if ($_SESSION['admin_role'] === 'mitra') {
                    $users = json_decode(file_get_contents('data/users.json'), true);
                    $rate_config = $_SESSION['commission_rate'] ?? [];
                    if (!is_array($rate_config)) {
                        $rate_config = ['basic' => (int)$rate_config, 'pro' => (int)$rate_config, 'ultimate' => (int)$rate_config];
                    }
                    $komisi = $rate_config[$pkg] ?? $rate_config['basic'] ?? 0;
                    foreach ($users as $i => $u) {
                        if ($u['id'] === $_SESSION['user_id']) {
                            $users[$i]['balance'] = ($u['balance'] ?? 0) + $komisi;
                            $_SESSION['balance'] = $users[$i]['balance'];
                            break;
                        }
                    }
                    file_put_contents('data/users.json', json_encode($users, JSON_PRETTY_PRINT));
                }
                
                // Log the activity
                $auditFile = DATA_DIR . '/audit.json';
                $audit = file_exists($auditFile) ? json_decode(file_get_contents($auditFile), true) : [];
                $audit[] = ['time' => date('Y-m-d H:i:s'), 'action' => 'add_member', 'member_id' => $members[count($members)-1]['id'], 'member_name' => $name, 'price' => $revenue, 'by' => $_SESSION['user_name'] ?? 'System', 'mitra_id' => ($_SESSION['admin_role'] === 'mitra' ? $_SESSION['user_id'] : null)];
                file_put_contents($auditFile, json_encode($audit, JSON_PRETTY_PRINT));

                $msg="Member <strong>{$name}</strong> ditambahkan. Kode: <strong>{$code}</strong> | Paket: <strong>{$PKG_LABELS[$pkg]}</strong>"; $msgType='success';
            }
        }
    } elseif ($pa === 'add_trial') {
        $name = trim($_POST['name'] ?? '');
        $days = 2; // Voucher khusus 2 hari
        $pkg = 'basic'; // Akses Basic
        
        $members = loadData('members.json');
        
        // Auto-generate name if empty
        if (empty($name)) {
            $name = 'Trial-' . strtoupper(substr(md5(uniqid()), 0, 6));
        } else {
            $name = $name . ' (TRIAL)';
        }
        
        $code = generateCode();
        
        $members[] = [
            'id' => nextId($members),
            'code' => $code,
            'name' => $name,
            'expiry_date' => date('Y-m-d', strtotime("+{$days} days")),
            'package' => $pkg,
            'custom_config' => null,
            'is_active' => 1,
            'created_at' => date('Y-m-d H:i:s'),
            'last_used' => null,
            'active_device_id' => null,
            'price_paid' => 0, // Trial = 0
            'payment_status' => 'lunas', // Trial otomatis lunas
            'created_by' => $_SESSION['user_name'] ?? 'System',
            'updated_by' => null,
            'mitra_id' => ($_SESSION['admin_role'] === 'mitra' ? $_SESSION['user_id'] : null)
        ];
        saveData('members.json', $members);
        
        // Log the activity
        $auditFile = DATA_DIR . '/audit.json';
        $audit = file_exists($auditFile) ? json_decode(file_get_contents($auditFile), true) : [];
        $audit[] = ['time' => date('Y-m-d H:i:s'), 'action' => 'add_trial', 'member_id' => $members[count($members)-1]['id'], 'member_name' => $name, 'price' => 0, 'by' => $_SESSION['user_name'] ?? 'System', 'mitra_id' => ($_SESSION['admin_role'] === 'mitra' ? $_SESSION['user_id'] : null)];
        file_put_contents($auditFile, json_encode($audit, JSON_PRETTY_PRINT));

        $msg="Voucher Trial 2 Hari berhasil dibuat! Nama: <b>{$name}</b> | Kode Akses: <b style='font-size:18px;color:#00e676;'>{$code}</b>"; $msgType='success';
    }

    if ($pa === 'update') {
        $id = (int)($_POST['id'] ?? 0); $name = trim($_POST['name'] ?? '');
        $code = trim($_POST['code'] ?? ''); $expiry = trim($_POST['expiry_date'] ?? '');
        $manual_price = trim($_POST['manual_price'] ?? '');
        $pkg = $_POST['package'] ?? 'basic';
        if (!array_key_exists($pkg, $PKG_LABELS)) $pkg = 'basic';
        
        $cfg = [];
        if ($pkg === 'custom') {
            foreach ($APP_LABELS_ALL as $aid => $_) {
                if (isset($_POST["app_{$aid}"])) {
                    $sv = (int)($_POST["srv_{$aid}"] ?? 1);
                    $cfg[$aid] = max(1, min($APP_MAX_ALL[$aid] ?? 1, $sv));
                }
            }
        }
        $custom_cfg = !empty($cfg) ? $cfg : null;
        if (empty($name)||empty($code)||empty($expiry)) { $msg='Semua field wajib diisi.'; $msgType='error'; }
        else {
            $members = loadData('members.json');
            foreach ($members as $i => $m) {
                if ($m['id'] === $id) {
                    $members[$i]['name'] = $name; $members[$i]['code'] = $code;
                    $members[$i]['payment_status'] = $_POST['payment_status'] ?? ($m['payment_status'] ?? 'lunas');
                    
                    // 1. Detect Package Upgrade/Downgrade
                    $old_pkg = $m['package'] ?? 'basic';
                    $new_pkg = $pkg;
                    $pkg_changed = ($old_pkg !== $new_pkg);
                    
                    if ($pkg_changed) {
                        global $pkg_prices;
                        $PACKAGES_CONFIG = loadData('packages.json');
                        $mitra_id = $m['mitra_id'] ?? null;
                        
                        if ($mitra_id) {
                            $mitra_id_key = 'mitra_' . $mitra_id . '_prices';
                            $current_pkg_prices = $pkg_prices;
                            if (isset($PACKAGES_CONFIG[$mitra_id_key])) {
                                $current_pkg_prices = $PACKAGES_CONFIG[$mitra_id_key];
                            }
                            
                            $old_price = $current_pkg_prices[$old_pkg] ?? 0;
                            $new_price = $current_pkg_prices[$new_pkg] ?? 0;
                            $price_diff = $new_price - $old_price;
                            
                            $users = json_decode(file_get_contents(DATA_DIR . '/users.json'), true);
                            $u_index = -1;
                            foreach ($users as $ui => $u) {
                                if ($u['id'] == $mitra_id) { $u_index = $ui; break; }
                            }
                            
                            if ($u_index !== -1) {
                                $rate_config = $users[$u_index]['commission_rate'] ?? [];
                                if (!is_array($rate_config)) {
                                    $rate_config = ['basic' => (int)$rate_config, 'pro' => (int)$rate_config, 'ultimate' => (int)$rate_config];
                                }
                                $old_komisi = $rate_config[$old_pkg] ?? $rate_config['basic'] ?? 0;
                                $new_komisi = $rate_config[$new_pkg] ?? $rate_config['basic'] ?? 0;
                                $komisi_diff = $new_komisi - $old_komisi;
                                
                                $deposit_bal = $users[$u_index]['deposit_balance'] ?? 0;
                                
                                if ($price_diff > 0) { // Upgrade
                                    $minus_limit = $users[$u_index]['deposit_minus_limit'] ?? -500000;
                                    // Validasi (walau owner yang mengubah, mitra tetap harus punya saldo)
                                    if ($price_diff > ($deposit_bal - $minus_limit)) {
                                        $msg = '⛔ SALDO DEPOSIT MITRA TIDAK MENCUKUPI untuk upgrade paket ini!'; 
                                        $msgType='error';
                                        break; // Abort
                                    }
                                    $users[$u_index]['deposit_balance'] = $deposit_bal - $price_diff;
                                    $users[$u_index]['balance'] = ($users[$u_index]['balance'] ?? 0) + $komisi_diff;
                                    
                                    $dh = loadData('deposit_history.json');
                                    $dh[] = ['id'=>count($dh)+1,'mitra_id'=>$mitra_id,'amount'=>-$price_diff,'balance_before'=>$deposit_bal,'balance_after'=>$users[$u_index]['deposit_balance'],'date'=>date('Y-m-d H:i:s'),'note'=>"Upgrade Paket (oleh Owner): {$old_pkg} -> {$new_pkg} | Biaya: Rp ".number_format($price_diff,0,',','.').". Komisi +Rp ".number_format($komisi_diff,0,',','.').".",'by'=>$_SESSION['user_name']];
                                    saveData('deposit_history.json', $dh);
                                    
                                    // Update price_paid so it reflects correctly in the dashboard
                                    $members[$i]['price_paid'] = ($m['price_paid'] ?? 0) + $price_diff;
                                    
                                } elseif ($price_diff < 0) { // Downgrade
                                    $abs_price_diff = abs($price_diff);
                                    $abs_komisi_diff = abs($komisi_diff);
                                    
                                    if (($users[$u_index]['balance'] ?? 0) < $abs_komisi_diff) {
                                        $msg = '⛔ SALDO KOMISI MITRA TIDAK MENCUKUPI untuk ditarik saat downgrade!'; 
                                        $msgType='error';
                                        break; // Abort
                                    }
                                    
                                    $users[$u_index]['deposit_balance'] = $deposit_bal + $abs_price_diff;
                                    $users[$u_index]['balance'] = ($users[$u_index]['balance'] ?? 0) - $abs_komisi_diff;
                                    
                                    $dh = loadData('deposit_history.json');
                                    $dh[] = ['id'=>count($dh)+1,'mitra_id'=>$mitra_id,'amount'=>$abs_price_diff,'balance_before'=>$deposit_bal,'balance_after'=>$users[$u_index]['deposit_balance'],'date'=>date('Y-m-d H:i:s'),'note'=>"Downgrade Paket (oleh Owner): {$old_pkg} -> {$new_pkg} | Refund: Rp ".number_format($abs_price_diff,0,',','.').". Tarik Komisi -Rp ".number_format($abs_komisi_diff,0,',','.').".",'by'=>$_SESSION['user_name']];
                                    saveData('deposit_history.json', $dh);
                                    
                                    // Update price_paid so it reflects correctly in the dashboard
                                    $members[$i]['price_paid'] = max(0, ($m['price_paid'] ?? 0) - $abs_price_diff);
                                }
                                
                                file_put_contents(DATA_DIR . '/users.json', json_encode($users, JSON_PRETTY_PRINT));
                                
                                $auditFile = DATA_DIR . '/audit.json';
                                $audit = file_exists($auditFile) ? json_decode(file_get_contents($auditFile), true) : [];
                                $audit[] = ['time' => date('Y-m-d H:i:s'), 'action' => 'change_package', 'member_id' => $id, 'member_name' => $name, 'old_pkg' => $old_pkg, 'new_pkg' => $new_pkg, 'price_diff' => $price_diff, 'by' => $_SESSION['user_name'], 'mitra_id' => $mitra_id];
                                file_put_contents($auditFile, json_encode($audit, JSON_PRETTY_PRINT));
                            }
                        }
                    }

                    // 2. Hitung durasi tambahan jika ada
                    $old_expiry = new DateTime($m['expiry_date']);
                    $new_expiry = new DateTime($expiry);
                    $diff = $old_expiry->diff($new_expiry);
                    $days_added = $diff->invert ? 0 : $diff->days;
                    
                    // Tambahkan harga jika ada hari tambahan dan harga manual tidak diset
                    if ($days_added > 0 && $manual_price === '') {
                        global $pkg_prices;
                        $base_price = $pkg_prices[$pkg] ?? 0;
                        $revenue_addition = (int)round(($base_price / 30) * $days_added);
                        $members[$i]['price_paid'] = ($m['price_paid'] ?? 0) + $revenue_addition;
                        
                        $auditFile = DATA_DIR . '/audit.json';
                        $audit = file_exists($auditFile) ? json_decode(file_get_contents($auditFile), true) : [];
                        $audit[] = ['time' => date('Y-m-d H:i:s'), 'action' => 'upgrade_member', 'member_id' => $id, 'member_name' => $name, 'price_added' => $revenue_addition, 'by' => $_SESSION['user_name'] ?? 'System', 'mitra_id' => ($_SESSION['admin_role'] === 'mitra' ? $_SESSION['user_id'] : null)];
                        file_put_contents($auditFile, json_encode($audit, JSON_PRETTY_PRINT));
                    } elseif ($manual_price !== '') {
                        $members[$i]['price_paid'] = (int)$manual_price;
                    }
                    
                    $members[$i]['expiry_date'] = $expiry; $members[$i]['package'] = $pkg;
                    $members[$i]['custom_config'] = $custom_cfg;
                    
                    $members[$i]['updated_by'] = $_SESSION['user_name'] ?? 'System';
                    $members[$i]['updated_at'] = date('Y-m-d H:i:s');
                    
                    if ($days_added <= 0) {
                        $auditFile = DATA_DIR . '/audit.json';
                        $audit = file_exists($auditFile) ? json_decode(file_get_contents($auditFile), true) : [];
                        $audit[] = ['time' => date('Y-m-d H:i:s'), 'action' => 'update_member', 'member_id' => $id, 'member_name' => $name, 'by' => $_SESSION['user_name'] ?? 'System', 'mitra_id' => ($_SESSION['admin_role'] === 'mitra' ? $_SESSION['user_id'] : null)];
                        file_put_contents($auditFile, json_encode($audit, JSON_PRETTY_PRINT));
                    }
                    break;
                }
            }
            saveData('members.json', $members);
            $msg='Member berhasil diperbarui.'; $msgType='success';
        }
        $editData = null;
    }
    if ($pa === 'toggle') {
        $id = (int)($_POST['id'] ?? 0); $members = loadData('members.json');
        foreach ($members as $i => $m) { 
            if ($m['id'] === $id) { 
                $members[$i]['is_active'] = $m['is_active'] ? 0 : 1; 
                $members[$i]['updated_by'] = $_SESSION['user_name'] ?? 'System';
                $members[$i]['updated_at'] = date('Y-m-d H:i:s');
                break; 
            } 
        }
        saveData('members.json', $members); $msg='Status diperbarui.'; $msgType='info';
    }
    if ($pa === 'refund_member') {
        $id = (int)($_POST['id'] ?? 0);
        $members = loadData('members.json');
        $found = false;
        foreach ($members as $i => $m) {
            if ($m['id'] === $id) {
                $members[$i]['is_active'] = 0; // Nonaktifkan member
                $mitra_id = $m['mitra_id'] ?? null;
                $pkg = $m['package'] ?? 'basic';
                
                $refund_amount = 0;
                $diffDays = 0;
                
                // Calculate proportional diffDays
                $today = new DateTime();
                $expDate = new DateTime($m['expiry_date'] ?? date('Y-m-d'));
                $diffTime = $expDate->getTimestamp() - $today->getTimestamp();
                $diffDays = max(0, ceil($diffTime / (60 * 60 * 24)));
                
                if ($mitra_id) {
                    global $pkg_prices;
                    $PACKAGES_CONFIG = loadData('packages.json');
                    $mitra_id_key = 'mitra_' . $mitra_id . '_prices';
                    $current_pkg_prices = $pkg_prices;
                    if (isset($PACKAGES_CONFIG[$mitra_id_key])) {
                        $current_pkg_prices = $PACKAGES_CONFIG[$mitra_id_key];
                    }
                    if (empty($current_pkg_prices) && isset($PACKAGES_CONFIG['main_prices'])) {
                        $current_pkg_prices = $PACKAGES_CONFIG['main_prices'];
                    }
                    
                    $price_paid = $m['price_paid'] ?? ($current_pkg_prices[$pkg] ?? 0);
                    
                    // Proportional Refund
                    $baseRefund = (int)round(($price_paid / 30) * $diffDays);
                    if ($baseRefund > $price_paid) $baseRefund = $price_paid;
                    
                    global $settings;
                    $adminFeePercent = $settings['refund_admin_fee_percent'] ?? 25;
                    $adminFee = (int)round($baseRefund * ($adminFeePercent / 100));
                    $netRefund = $baseRefund - $adminFee;
                    $refund_amount = $netRefund;
                    
                    $users = loadData('users.json');
                    $u_index = -1;
                    $owner_index = -1;
                    foreach ($users as $ui => $u) {
                        if ($u['id'] == $mitra_id) { $u_index = $ui; }
                        if ($u['role'] === 'owner') { $owner_index = $ui; }
                    }
                    
                    $refund_reason = $_POST['refund_reason'] ?? 'Refund dari Owner';
                    if (empty(trim($refund_reason))) $refund_reason = 'Refund dari Owner';
                    
                    if ($u_index !== -1) {
                        $rate_config = $users[$u_index]['commission_rate'] ?? [];
                        if (!is_array($rate_config)) {
                            $rate_config = ['basic' => (int)$rate_config, 'pro' => (int)$rate_config, 'ultimate' => (int)$rate_config];
                        }
                        $base_komisi = $rate_config[$pkg] ?? $rate_config['basic'] ?? 0;
                        $komisi_proporsional = (int)round(($base_komisi / 30) * $diffDays);
                        if ($komisi_proporsional > $base_komisi) $komisi_proporsional = $base_komisi;
                        
                        $owner_portion = $netRefund - $komisi_proporsional;
                        
                        $users[$u_index]['balance'] = ($users[$u_index]['balance'] ?? 0) - $komisi_proporsional;
                        $old_dep = $users[$u_index]['deposit_balance'] ?? 0;
                        $users[$u_index]['deposit_balance'] = $old_dep + $netRefund;
                        
                        if ($owner_index !== -1) {
                            $users[$owner_index]['balance'] = ($users[$owner_index]['balance'] ?? 0) - $owner_portion;
                        }
                        
                        $dh = loadData('deposit_history.json');
                        $dh[] = ['id'=>count($dh)+1,'mitra_id'=>$mitra_id,'amount'=>$netRefund,'balance_before'=>$old_dep,'balance_after'=>$users[$u_index]['deposit_balance'],'date'=>date('Y-m-d H:i:s'),'note'=>"Refund Proporsional ({$diffDays} hari): {$m['name']} | Alasan: {$refund_reason} | Deposit kembali: Rp ".number_format($netRefund,0,',','.').". Tarik Komisi: -Rp ".number_format($komisi_proporsional,0,',','.'),'by'=>$_SESSION['user_name'] ?? 'System'];
                        saveData('deposit_history.json', $dh);
                        saveData('users.json', $users);
                    }
                } else {
                    $refund_amount = (int)($_POST['refund_amount'] ?? 0); // Manual jika bukan mitra
                    
                    $users = loadData('users.json');
                    $owner_index = -1;
                    foreach ($users as $ui => $u) {
                        if ($u['role'] === 'owner') { $owner_index = $ui; break; }
                    }
                    if ($owner_index !== -1) {
                        $users[$owner_index]['balance'] = ($users[$owner_index]['balance'] ?? 0) - $refund_amount;
                        saveData('users.json', $users);
                    }
                }
                
                $refund_reason_audit = $_POST['refund_reason'] ?? 'Refund dari Owner';
                if (empty(trim($refund_reason_audit))) $refund_reason_audit = 'Refund dari Owner';
                
                // Update audit/log untuk refund
                $auditFile = DATA_DIR . '/audit.json';
                $audit = file_exists($auditFile) ? json_decode(file_get_contents($auditFile), true) : [];
                $audit[] = ['time' => date('Y-m-d H:i:s'), 'action' => 'refund_member', 'member_id' => $id, 'refund_amount' => $refund_amount, 'reason' => $refund_reason_audit, 'by' => $_SESSION['user_name'] ?? 'System'];
                file_put_contents($auditFile, json_encode($audit, JSON_PRETTY_PRINT));
                
                // Update price_paid so Total Pendapatan is reduced in the dashboard
                $members[$i]['price_paid'] = max(0, ($m['price_paid'] ?? 0) - $refund_amount);
                
                $found = true;
                $msg="Refund berhasil diproses. Member dinonaktifkan. Jumlah dikembalikan: Rp " . number_format($refund_amount, 0, ',', '.'); 
                $msgType='success';
                break;
            }
        }
        if ($found) { saveData('members.json', $members); }
        else { $msg='Member tidak ditemukan.'; $msgType='error'; }
    }
    if ($pa === 'delete') {
        $id = (int)($_POST['id'] ?? 0); $members = loadData('members.json');
        
        // --- Added for deletion notification ---
        $deleted_name = "Member";
        $mitra_id = null;
        $pkg = 'basic';
        foreach ($members as $m) {
            if ($m['id'] === $id) {
                $deleted_name = $m['name'];
                $mitra_id = $m['mitra_id'] ?? null;
                $pkg = $m['package'] ?? 'basic';
                break;
            }
        }
        // ---------------------------------------

        $members = array_values(array_filter($members, function($m) use ($id) { return $m['id'] !== $id; }));
        saveData('members.json', $members); 
        
        if ($mitra_id) {
            global $pkg_prices;
            $PACKAGES_CONFIG = loadData('packages.json');
            $mitra_id_key = 'mitra_' . $mitra_id . '_prices';
            $current_pkg_prices = $pkg_prices;
            if (isset($PACKAGES_CONFIG[$mitra_id_key])) {
                $current_pkg_prices = $PACKAGES_CONFIG[$mitra_id_key];
            }
            // Fallback to main_prices if mitra specific price is not set properly
            if (empty($current_pkg_prices) && isset($PACKAGES_CONFIG['main_prices'])) {
                $current_pkg_prices = $PACKAGES_CONFIG['main_prices'];
            }

            $price = $current_pkg_prices[$pkg] ?? 0;
            
            $users = loadData('users.json');
            foreach ($users as $ui => $u) {
                if ($u['id'] == $mitra_id) {
                    $users[$ui]['deposit_balance'] = ($u['deposit_balance'] ?? 0) + $price;
                    
                    $dh = loadData('deposit_history.json');
                    $dh[] = ['id'=>count($dh)+1,'mitra_id'=>$mitra_id,'amount'=>$price,'balance_before'=>($u['deposit_balance'] ?? 0),'balance_after'=>$users[$ui]['deposit_balance'],'date'=>date('Y-m-d H:i:s'),'note'=>"Voucher Dihapus oleh Owner: {$deleted_name} | Pengembalian Saldo: +Rp ".number_format($price,0,',','.'),'by'=>$_SESSION['user_name'] ?? 'System'];
                    saveData('deposit_history.json', $dh);
                    break;
                }
            }
            saveData('users.json', $users);
        }
        
        $auditFile = DATA_DIR . '/audit.json';
        $audit = file_exists($auditFile) ? json_decode(file_get_contents($auditFile), true) : [];
        $audit[] = ['time' => date('Y-m-d H:i:s'), 'action' => 'delete_member', 'member_id' => $id, 'member_name' => $deleted_name, 'by' => $_SESSION['user_name'] ?? 'System', 'mitra_id' => ($_SESSION['admin_role'] === 'mitra' ? $_SESSION['user_id'] : null)];
        file_put_contents($auditFile, json_encode($audit, JSON_PRETTY_PRINT));
        
        $msg="Member <strong>{$deleted_name}</strong> dihapus. Saldo mitra telah dikembalikan."; $msgType='info';
    }

    // APP MANAGEMENT
    if ($pa === 'add_app') {
        $id = trim($_POST['id'] ?? ''); $name = trim($_POST['name'] ?? '');
        $max_srv = (int)($_POST['max_servers'] ?? 1); $url = trim($_POST['default_url'] ?? '');
        $hidden_elements = trim($_POST['hidden_elements'] ?? '');
        $req_cookie = isset($_POST['requires_cookie']) ? 1 : 0;
        $flow_lock_enabled = isset($_POST['flow_lock_enabled']) ? 1 : 0;
        $flow_unlock_models = [
            'lite' => isset($_POST['flow_unlock_lite']) ? 1 : 0,
            'fast' => isset($_POST['flow_unlock_fast']) ? 1 : 0,
            'quality' => isset($_POST['flow_unlock_quality']) ? 1 : 0,
            'lower_priority' => isset($_POST['flow_unlock_lower_priority']) ? 1 : 0,
            'omni_flash' => isset($_POST['flow_unlock_omni_flash']) ? 1 : 0
        ];
        $flow_hide_other_projects = isset($_POST['flow_hide_other_projects']) ? 1 : 0;
        $hide_url = isset($_POST['hide_url']) ? 1 : 0;

        $custom_servers = [];
        if (isset($_POST['server_names']) && is_array($_POST['server_names'])) {
            foreach ($_POST['server_names'] as $idx => $sname) {
                $sname = trim($sname);
                $surl = trim($_POST['server_urls'][$idx] ?? '');
                if ($sname !== '') {
                    $custom_servers[] = ['name' => $sname, 'url' => $surl];
                }
            }
        }
        if (count($custom_servers) > 0) {
            $max_srv = count($custom_servers);
        } else {
            $max_srv = (int)($_POST['max_servers'] ?? 1);
        }
        if (empty($id)) $id = strtolower(trim(preg_replace('/[^A-Za-z0-9-]+/', '-', $name), '-'));
        $icon_type = 'emoji'; $icon_val = 'ðŸ“¦';
        if (isset($_FILES['icon_file']) && $_FILES['icon_file']['error'] === UPLOAD_ERR_OK) {
            $fileExt = strtolower(pathinfo($_FILES['icon_file']['name'], PATHINFO_EXTENSION));
            if (in_array($fileExt, ['png','jpg','jpeg','gif','svg'])) {
                $uploadDir = __DIR__ . '/app_icons/';
                if (!is_dir($uploadDir)) mkdir($uploadDir, 0777, true);
                $newFileName = $id . '_' . time() . '.' . $fileExt;
                if (move_uploaded_file($_FILES['icon_file']['tmp_name'], $uploadDir . $newFileName)) {
                                $icon_type = 'image';
                                $protocol = (isset($_SERVER['HTTPS']) && $_SERVER['HTTPS'] === 'on') ? 'https' : 'http';
                                // Fix base URL generation for #HOST folder
                                $scriptDir = dirname($_SERVER['PHP_SELF']);
                                $scriptDir = str_replace('\\', '/', $scriptDir);
                                $base_url = $protocol . '://' . $_SERVER['HTTP_HOST'] . rtrim($scriptDir, '/');
                                
                                $icon_val = $base_url . '/app_icons/' . $newFileName;
                            }
            }
        }
        if (empty($id)||empty($name)) { $msg='ID dan Nama wajib diisi.'; $msgType='error'; }
        else {
            $apps = loadData('applications.json');
            $exists = false; foreach ($apps as $a) { if ($a['id'] === $id) { $exists = true; break; } }
            if ($exists) { $msg='ID aplikasi sudah digunakan.'; $msgType='error'; }
            else {
                $maxSort = 0; foreach ($apps as $a) { if (($a['sort_order']??0) > $maxSort) $maxSort = $a['sort_order']; }
                $apps[] = ['id'=>$id,'name'=>$name,'icon_type'=>$icon_type,'icon_value'=>$icon_val,'color_gradient'=>'linear-gradient(135deg, #0066ff, #0099ff)','max_servers'=>$max_srv,'default_url'=>$url,'requires_cookie'=>$req_cookie,'flow_lock_enabled'=>$flow_lock_enabled,'flow_unlock_models'=>$flow_unlock_models,'flow_hide_other_projects'=>$flow_hide_other_projects,'hidden_elements'=>$hidden_elements,'is_active'=>1,'sort_order'=>$maxSort+1,'custom_servers'=>$custom_servers,'hide_url'=>$hide_url,'app_popup_enabled'=>0,'app_popup_title'=>'','app_popup_content'=>''];
                saveData('applications.json', $apps);
                $msg="Aplikasi <strong>{$name}</strong> berhasil ditambahkan."; $msgType='success';
                echo "<script>window.location.href='?tab=apps';</script>"; exit();
            }
        }
    }
    if ($pa === 'update_app') {
        $id = trim($_POST['id'] ?? ''); $name = trim($_POST['name'] ?? '');
        $max_srv = (int)($_POST['max_servers'] ?? 1); $url = trim($_POST['default_url'] ?? '');
        $hidden_elements = trim($_POST['hidden_elements'] ?? '');
    $req_cookie = isset($_POST['requires_cookie']) ? 1 : 0;
    $flow_lock_enabled = isset($_POST['flow_lock_enabled']) ? 1 : 0;
    $flow_unlock_models = [
        'lite' => isset($_POST['flow_unlock_lite']) ? 1 : 0,
        'fast' => isset($_POST['flow_unlock_fast']) ? 1 : 0,
        'quality' => isset($_POST['flow_unlock_quality']) ? 1 : 0,
        'lower_priority' => isset($_POST['flow_unlock_lower_priority']) ? 1 : 0,
        'omni_flash' => isset($_POST['flow_unlock_omni_flash']) ? 1 : 0
    ];
    $flow_hide_other_projects = isset($_POST['flow_hide_other_projects']) ? 1 : 0;
    $hide_url = isset($_POST['hide_url']) ? 1 : 0;
    
    $app_popup_enabled = isset($_POST['app_popup_enabled']) ? 1 : 0;
    $app_popup_title = trim($_POST['app_popup_title'] ?? '');
    $app_popup_content = trim($_POST['app_popup_content'] ?? '');

    $custom_servers = [];
        if (isset($_POST['server_names']) && is_array($_POST['server_names'])) {
            foreach ($_POST['server_names'] as $idx => $sname) {
                $sname = trim($sname);
                $surl = trim($_POST['server_urls'][$idx] ?? '');
                if ($sname !== '') {
                    $custom_servers[] = ['name' => $sname, 'url' => $surl];
                }
            }
        }
        if (count($custom_servers) > 0) {
            $max_srv = count($custom_servers);
        } else {
            $max_srv = (int)($_POST['max_servers'] ?? 1);
        }
        if (empty($id)||empty($name)) { $msg='ID dan Nama wajib diisi.'; $msgType='error'; }
        else {
            $apps = loadData('applications.json');
            foreach ($apps as $i => $a) {
                if ($a['id'] === $id) {
                    $apps[$i]['name'] = $name; $apps[$i]['max_servers'] = $max_srv;
                    $apps[$i]['default_url'] = $url; $apps[$i]['requires_cookie'] = $req_cookie;
                    $apps[$i]['flow_lock_enabled'] = $flow_lock_enabled;
                    $apps[$i]['flow_unlock_models'] = $flow_unlock_models;
                    $apps[$i]['flow_hide_other_projects'] = $flow_hide_other_projects;
                    $apps[$i]['hidden_elements'] = $hidden_elements;
                    $apps[$i]['custom_servers'] = $custom_servers;
                    $apps[$i]['hide_url'] = $hide_url;
                    $apps[$i]['app_popup_enabled'] = $app_popup_enabled;
                    $apps[$i]['app_popup_title'] = $app_popup_title;
                    $apps[$i]['app_popup_content'] = $app_popup_content;
                    // Icon upload
                    if (isset($_FILES['icon_file']) && $_FILES['icon_file']['error'] === UPLOAD_ERR_OK) {
                        $fileExt = strtolower(pathinfo($_FILES['icon_file']['name'], PATHINFO_EXTENSION));
                        if (in_array($fileExt, ['png','jpg','jpeg','gif','svg'])) {
                            $uploadDir = __DIR__ . '/app_icons/';
                            if (!is_dir($uploadDir)) mkdir($uploadDir, 0777, true);
                            $newFileName = $id . '_' . time() . '.' . $fileExt;
                            if (move_uploaded_file($_FILES['icon_file']['tmp_name'], $uploadDir . $newFileName)) {
                                $apps[$i]['icon_type'] = 'image';
                                $protocol = (isset($_SERVER['HTTPS']) && $_SERVER['HTTPS'] === 'on') ? 'https' : 'http';
                                // Fix base URL generation for #HOST folder
                                $scriptDir = dirname($_SERVER['PHP_SELF']);
                                // Remove backslashes and ensure no double slash issues
                                $scriptDir = str_replace('\\', '/', $scriptDir);
                                $base_url = $protocol . '://' . $_SERVER['HTTP_HOST'] . rtrim($scriptDir, '/');
                                
                                // Pastikan URL encode pada nama file jika mengandung karakter aneh, tapi di sini kita pakai timestamp jadi aman
                                $apps[$i]['icon_value'] = $base_url . '/app_icons/' . $newFileName;
                            }
                        }
                    }
                    break;
                }
            }
            saveData('applications.json', $apps);
            $msg="Aplikasi <strong>{$name}</strong> berhasil diperbarui."; $msgType='success';
            echo "<script>window.location.href='?tab=apps';</script>"; exit();
        }
    }
    if ($pa === 'toggle_app') {
        $id = $_POST['id'] ?? ''; $apps = loadData('applications.json');
        foreach ($apps as $i => $a) { if ($a['id'] === $id) { $apps[$i]['is_active'] = $a['is_active'] ? 0 : 1; break; } }
        saveData('applications.json', $apps); $msg='Status aplikasi diperbarui.'; $msgType='info';
        echo "<script>window.location.href='?tab=apps';</script>"; exit();
    }
    if ($pa === 'delete_app') {
        $id = $_POST['id'] ?? '';
        $apps = loadData('applications.json');
        $apps = array_values(array_filter($apps, function($a) use ($id) { return $a['id'] !== $id; }));
        saveData('applications.json', $apps);
        $cookies = loadData('cookies.json');
        $cookies = array_values(array_filter($cookies, function($c) use ($id) { return $c['app_id'] !== $id; }));
        saveData('cookies.json', $cookies);
        $msg='Aplikasi dihapus.'; $msgType='info';
        echo "<script>window.location.href='?tab=apps';</script>"; exit();
    }

    // === TOOLS-FLOW MANAGEMENT (for extension TOOLS-FLOW dropdown) ===
    if ($pa === 'add_tool_flow') {
        $name = trim($_POST['tf_name'] ?? '');
        $path = trim($_POST['tf_path'] ?? '');
        $desc = trim($_POST['tf_description'] ?? '');
        $tutorial_url = trim($_POST['tf_tutorial_url'] ?? '');
        $allowed_servers = $_POST['tf_allowed_servers'] ?? [];
        if (!is_array($allowed_servers)) $allowed_servers = [];
        $allowed_servers = array_values(array_filter(array_map('trim', $allowed_servers), function($s){ return $s !== ''; }));
        if (empty($name) || empty($path)) {
            $msg = 'Nama dan Path wajib diisi.'; $msgType = 'error';
        } else {
            // Strip leading slash if user pastes full URL
            $path = preg_replace('#^https?://[^/]+/fx/tools/flow/project/[^/]+/#', '', $path);
            $path = ltrim($path, '/');
            // Validate tutorial URL (allow empty)
            if ($tutorial_url !== '' && !preg_match('#^https?://#i', $tutorial_url)) {
                $tutorial_url = 'https://' . $tutorial_url;
            }
            $tools = loadData('tools_flow.json');
            $tools[] = [
                'id' => uniqid('tf_'),
                'name' => $name,
                'path' => $path,
                'description' => $desc,
                'tutorial_url' => $tutorial_url,
                'allowed_servers' => $allowed_servers, // empty = all servers
                'is_active' => 1,
                'created_at' => (new DateTime('now', new DateTimeZone('Asia/Jakarta')))->format('Y-m-d H:i:s')
            ];
            saveData('tools_flow.json', $tools);
            $_SESSION['flash_msg'] = "Tool Flow <strong>{$name}</strong> berhasil ditambahkan.";
            $_SESSION['flash_msgType'] = 'success';
            if (ob_get_length()) ob_clean();
            header('Location: ?tab=apps&_t=' . time() . '#tools-flow');
            exit();
        }
    }
    if ($pa === 'edit_tool_flow') {
        $id = $_POST['tf_id'] ?? '';
        $name = trim($_POST['tf_name'] ?? '');
        $path = trim($_POST['tf_path'] ?? '');
        $desc = trim($_POST['tf_description'] ?? '');
        $tutorial_url = trim($_POST['tf_tutorial_url'] ?? '');
        $allowed_servers = $_POST['tf_allowed_servers'] ?? [];
        if (!is_array($allowed_servers)) $allowed_servers = [];
        $allowed_servers = array_values(array_filter(array_map('trim', $allowed_servers), function($s){ return $s !== ''; }));
        if (empty($id) || empty($name) || empty($path)) {
            $msg = 'ID, Nama dan Path wajib diisi.'; $msgType = 'error';
        } else {
            $path = preg_replace('#^https?://[^/]+/fx/tools/flow/project/[^/]+/#', '', $path);
            $path = ltrim($path, '/');
            if ($tutorial_url !== '' && !preg_match('#^https?://#i', $tutorial_url)) {
                $tutorial_url = 'https://' . $tutorial_url;
            }
            $tools = loadData('tools_flow.json');
            foreach ($tools as &$t) {
                if (($t['id'] ?? '') === $id) {
                    $t['name'] = $name;
                    $t['path'] = $path;
                    $t['description'] = $desc;
                    $t['tutorial_url'] = $tutorial_url;
                    $t['allowed_servers'] = $allowed_servers;
                    break;
                }
            }
            unset($t);
            saveData('tools_flow.json', $tools);
            $_SESSION['flash_msg'] = 'Tool Flow diperbarui.';
            $_SESSION['flash_msgType'] = 'success';
            if (ob_get_length()) ob_clean();
            header('Location: ?tab=apps&_t=' . time() . '#tools-flow');
            exit();
        }
    }
    if ($pa === 'toggle_tool_flow') {
        $id = $_POST['tf_id'] ?? '';
        $tools = loadData('tools_flow.json');
        foreach ($tools as &$t) {
            if (($t['id'] ?? '') === $id) {
                $t['is_active'] = empty($t['is_active']) ? 1 : 0;
                break;
            }
        }
        unset($t);
        saveData('tools_flow.json', $tools);
        $_SESSION['flash_msg'] = 'Status tool diperbarui.';
        $_SESSION['flash_msgType'] = 'info';
        if (ob_get_length()) ob_clean();
        header('Location: ?tab=apps&_t=' . time() . '#tools-flow');
        exit();
    }
    if ($pa === 'delete_tool_flow') {
        $id = $_POST['tf_id'] ?? '';
        $tools = loadData('tools_flow.json');
        $tools = array_values(array_filter($tools, function($t) use ($id) { return ($t['id'] ?? '') !== $id; }));
        saveData('tools_flow.json', $tools);
        $_SESSION['flash_msg'] = 'Tool Flow dihapus.';
        $_SESSION['flash_msgType'] = 'info';
        if (ob_get_length()) ob_clean();
        header('Location: ?tab=apps&_t=' . time() . '#tools-flow');
        exit();
    }

    // === CUSTOM FLOW LOCKS (Admin paste HTML element → extension auto-lock) ===
    if (in_array($pa, ['add_flow_lock', 'edit_flow_lock', 'toggle_flow_lock', 'delete_flow_lock'], true)) {

        // Helper: parse HTML element snippet → signature for client-side matching
        $parseLockSignature = function($html) {
            $sig = [
                'tag' => '',
                'classes' => [],
                'text' => '',
                'icon_text' => '',
                'data_attrs' => [],
                'aria_label' => '',
                'href' => '',
                'role' => '',
                'data_state' => '',
                'raw' => substr($html, 0, 2000)
            ];
            $html = trim($html);
            if ($html === '') return $sig;
            $doc = new DOMDocument();
            // Suppress warnings on broken HTML
            libxml_use_internal_errors(true);
            $doc->loadHTML('<?xml encoding="UTF-8"><div id="__wrap__">' . $html . '</div>', LIBXML_NOWARNING | LIBXML_NOERROR);
            libxml_clear_errors();
            $wrap = $doc->getElementById('__wrap__');
            if (!$wrap) return $sig;
            // First element child
            $first = null;
            foreach ($wrap->childNodes as $n) {
                if ($n->nodeType === XML_ELEMENT_NODE) { $first = $n; break; }
            }
            if (!$first) return $sig;
            $sig['tag'] = strtolower($first->nodeName);
            $cls = trim($first->getAttribute('class'));
            if ($cls !== '') {
                $sig['classes'] = array_values(array_filter(preg_split('/\s+/', $cls)));
            }
            $sig['aria_label'] = trim($first->getAttribute('aria-label'));
            $sig['href'] = trim($first->getAttribute('href'));
            $sig['role'] = trim($first->getAttribute('role'));
            $sig['data_state'] = trim($first->getAttribute('data-state'));
            // All data-* attrs
            if ($first->hasAttributes()) {
                foreach ($first->attributes as $attr) {
                    if (strpos($attr->nodeName, 'data-') === 0 && $attr->nodeName !== 'data-state') {
                        $sig['data_attrs'][$attr->nodeName] = $attr->nodeValue;
                    }
                }
            }
            // Direct text (excluding hidden screen-reader spans? — keep all for matching)
            $textParts = [];
            foreach ($first->childNodes as $c) {
                if ($c->nodeType === XML_TEXT_NODE) {
                    $t = trim($c->nodeValue);
                    if ($t !== '') $textParts[] = $t;
                }
            }
            // Also capture span text (often the visible/sr label)
            $spans = $first->getElementsByTagName('span');
            foreach ($spans as $sp) {
                $t = trim($sp->textContent);
                if ($t !== '' && !in_array($t, $textParts, true)) $textParts[] = $t;
            }
            $sig['text'] = trim(mb_substr(implode(' ', $textParts), 0, 200));
            // Material / Google symbols icon text (e.g., "apps_spark_2")
            $icons = $first->getElementsByTagName('i');
            foreach ($icons as $ic) {
                $iclass = $ic->getAttribute('class');
                if (stripos($iclass, 'google-symbols') !== false || stripos($iclass, 'material-symbols') !== false || stripos($iclass, 'material-icons') !== false) {
                    $sig['icon_text'] = trim($ic->textContent);
                    break;
                }
            }
            return $sig;
        };

        if ($pa === 'add_flow_lock' || $pa === 'edit_flow_lock') {
            $name = trim($_POST['fl_name'] ?? '');
            $html = trim($_POST['fl_html'] ?? '');
            $mode = trim($_POST['fl_mode'] ?? 'overlay'); // overlay | hide | disable
            $message = trim($_POST['fl_message'] ?? '');
            $applyOn = trim($_POST['fl_apply_on'] ?? 'both'); // list | project | both
            $allowed = $_POST['fl_allowed_servers'] ?? [];
            if (!is_array($allowed)) $allowed = [];
            $allowed = array_values(array_filter(array_map('trim', $allowed), function($s){ return $s !== ''; }));

            if (!in_array($mode, ['overlay', 'hide', 'disable'], true)) $mode = 'overlay';
            if (!in_array($applyOn, ['list', 'project', 'both'], true)) $applyOn = 'both';

            if ($name === '' || $html === '') {
                $msg = 'Nama dan HTML element wajib diisi.'; $msgType = 'error';
            } else {
                $signature = $parseLockSignature($html);
                if ($signature['tag'] === '') {
                    $msg = 'HTML element tidak valid. Pastikan paste lengkap (tag dengan attributes).'; $msgType = 'error';
                } else {
                    $locks = loadData('flow_locks.json');
                    if (!is_array($locks)) $locks = [];
                    if ($pa === 'add_flow_lock') {
                        $locks[] = [
                            'id' => uniqid('fl_'),
                            'name' => $name,
                            'mode' => $mode,
                            'message' => $message,
                            'apply_on' => $applyOn,
                            'allowed_servers' => $allowed, // empty = all servers
                            'signature' => $signature,
                            'is_active' => 1,
                            'created_at' => (new DateTime('now', new DateTimeZone('Asia/Jakarta')))->format('Y-m-d H:i:s')
                        ];
                        $_SESSION['flash_msg'] = "Flow Lock <strong>{$name}</strong> berhasil ditambahkan.";
                    } else {
                        $id = $_POST['fl_id'] ?? '';
                        foreach ($locks as &$L) {
                            if (($L['id'] ?? '') === $id) {
                                $L['name'] = $name;
                                $L['mode'] = $mode;
                                $L['message'] = $message;
                                $L['apply_on'] = $applyOn;
                                $L['allowed_servers'] = $allowed;
                                $L['signature'] = $signature;
                                break;
                            }
                        }
                        unset($L);
                        $_SESSION['flash_msg'] = 'Flow Lock diperbarui.';
                    }
                    saveData('flow_locks.json', $locks);
                    $_SESSION['flash_msgType'] = 'success';
                    if (ob_get_length()) ob_clean();
                    header('Location: ?tab=apps&_t=' . time() . '#flow-locks');
                    exit();
                }
            }
        }

        if ($pa === 'toggle_flow_lock') {
            $id = $_POST['fl_id'] ?? '';
            $locks = loadData('flow_locks.json');
            if (!is_array($locks)) $locks = [];
            foreach ($locks as &$L) {
                if (($L['id'] ?? '') === $id) {
                    $L['is_active'] = empty($L['is_active']) ? 1 : 0;
                    break;
                }
            }
            unset($L);
            saveData('flow_locks.json', $locks);
            $_SESSION['flash_msg'] = 'Status lock diperbarui.';
            $_SESSION['flash_msgType'] = 'info';
            if (ob_get_length()) ob_clean();
            header('Location: ?tab=apps&_t=' . time() . '#flow-locks');
            exit();
        }

        if ($pa === 'delete_flow_lock') {
            $id = $_POST['fl_id'] ?? '';
            $locks = loadData('flow_locks.json');
            if (!is_array($locks)) $locks = [];
            $locks = array_values(array_filter($locks, function($L) use ($id) { return ($L['id'] ?? '') !== $id; }));
            saveData('flow_locks.json', $locks);
            $_SESSION['flash_msg'] = 'Flow Lock dihapus.';
            $_SESSION['flash_msgType'] = 'info';
            if (ob_get_length()) ob_clean();
            header('Location: ?tab=apps&_t=' . time() . '#flow-locks');
            exit();
        }
    }

    // === FLOW LOCKS — MASTER CONTROLS (kill-switch + bulk delete) ===
    if ($pa === 'master_toggle_flow_locks') {
        $settings = loadData('settings.json');
        if (!is_array($settings)) $settings = [];
        $settings['flow_locks_master_enabled'] = empty($settings['flow_locks_master_enabled']) ? 1 : 0;
        saveData('settings.json', $settings);
        $_SESSION['flash_msg'] = $settings['flow_locks_master_enabled']
            ? '🔐 Master Switch AKTIF — semua lock berjalan.'
            : '🔓 Master Switch OFF — SEMUA lock dimatikan untuk semua user.';
        $_SESSION['flash_msgType'] = $settings['flow_locks_master_enabled'] ? 'info' : 'success';
        if (ob_get_length()) ob_clean();
        header('Location: ?tab=apps&_t=' . time() . '#flow-locks');
        exit();
    }

    if ($pa === 'delete_all_flow_locks') {
        // Confirm via form-level POST. Wipe all locks.
        saveData('flow_locks.json', []);
        $_SESSION['flash_msg'] = '🗑 Semua Flow Lock dihapus.';
        $_SESSION['flash_msgType'] = 'success';
        if (ob_get_length()) ob_clean();
        header('Location: ?tab=apps&_t=' . time() . '#flow-locks');
        exit();
    }

    if ($pa === 'bulk_disable_all_flow_locks') {
        // Disable each lock without deleting (preserve config)
        $locks = loadData('flow_locks.json');
        if (!is_array($locks)) $locks = [];
        foreach ($locks as &$L) { $L['is_active'] = 0; }
        unset($L);
        saveData('flow_locks.json', $locks);
        $_SESSION['flash_msg'] = '⏸ Semua lock di-Disable (config tetap tersimpan).';
        $_SESSION['flash_msgType'] = 'info';
        if (ob_get_length()) ob_clean();
        header('Location: ?tab=apps&_t=' . time() . '#flow-locks');
        exit();
    }

    if ($pa === 'bulk_enable_all_flow_locks') {
        $locks = loadData('flow_locks.json');
        if (!is_array($locks)) $locks = [];
        foreach ($locks as &$L) { $L['is_active'] = 1; }
        unset($L);
        saveData('flow_locks.json', $locks);
        $_SESSION['flash_msg'] = '▶ Semua lock di-Enable.';
        $_SESSION['flash_msgType'] = 'success';
        if (ob_get_length()) ob_clean();
        header('Location: ?tab=apps&_t=' . time() . '#flow-locks');
        exit();
    }

    // === FLOW URL BLOCKS — admin manage URL block rules ===
    if (in_array($pa, ['add_flow_url_block', 'edit_flow_url_block', 'toggle_flow_url_block', 'delete_flow_url_block'], true)) {
        $rules = loadData('flow_url_blocks.json');
        if (!is_array($rules)) $rules = [];

        if ($pa === 'add_flow_url_block' || $pa === 'edit_flow_url_block') {
            $pattern = trim($_POST['pattern'] ?? '');
            $mode = in_array($_POST['mode'] ?? '', ['exact', 'wildcard'], true) ? $_POST['mode'] : 'exact';
            $redirect_url = trim($_POST['redirect_url'] ?? '');
            $message = trim($_POST['message'] ?? '');
            $name = trim($_POST['name'] ?? '');
            $allowed = $_POST['allowed_servers'] ?? [];
            if (!is_array($allowed)) $allowed = [];
            $allowed = array_values(array_filter(array_map('trim', $allowed)));

            if ($pattern === '') {
                $_SESSION['flash_msg'] = 'Pattern URL wajib diisi.';
                $_SESSION['flash_msgType'] = 'error';
            } else {
                if ($pa === 'add_flow_url_block') {
                    $rules[] = [
                        'id' => 'fu_' . uniqid(),
                        'name' => $name !== '' ? $name : substr($pattern, 0, 60),
                        'pattern' => $pattern,
                        'mode' => $mode,
                        'redirect_url' => $redirect_url,
                        'message' => $message !== '' ? $message : 'Halaman ini diblokir.',
                        'is_active' => 1,
                        'allowed_servers' => $allowed,
                        'created_at' => date('Y-m-d H:i:s'),
                    ];
                    $_SESSION['flash_msg'] = '✅ URL Block ditambahkan.';
                } else {
                    $rid = $_POST['fr_id'] ?? '';
                    foreach ($rules as &$R) {
                        if (($R['id'] ?? '') === $rid) {
                            $R['name'] = $name !== '' ? $name : substr($pattern, 0, 60);
                            $R['pattern'] = $pattern;
                            $R['mode'] = $mode;
                            $R['redirect_url'] = $redirect_url;
                            $R['message'] = $message !== '' ? $message : 'Halaman ini diblokir.';
                            $R['allowed_servers'] = $allowed;
                            break;
                        }
                    }
                    unset($R);
                    $_SESSION['flash_msg'] = '✅ URL Block diperbarui.';
                }
                saveData('flow_url_blocks.json', $rules);
                $_SESSION['flash_msgType'] = 'success';
            }
            if (ob_get_length()) ob_clean();
            header('Location: ?tab=apps&_t=' . time() . '#flow-url-blocks');
            exit();
        }

        if ($pa === 'toggle_flow_url_block') {
            $rid = $_POST['fr_id'] ?? '';
            foreach ($rules as &$R) {
                if (($R['id'] ?? '') === $rid) {
                    $R['is_active'] = empty($R['is_active']) ? 1 : 0;
                    break;
                }
            }
            unset($R);
            saveData('flow_url_blocks.json', $rules);
            $_SESSION['flash_msg'] = 'Status URL Block diperbarui.';
            $_SESSION['flash_msgType'] = 'info';
            if (ob_get_length()) ob_clean();
            header('Location: ?tab=apps&_t=' . time() . '#flow-url-blocks');
            exit();
        }

        if ($pa === 'delete_flow_url_block') {
            $rid = $_POST['fr_id'] ?? '';
            $rules = array_values(array_filter($rules, function($R) use ($rid) { return ($R['id'] ?? '') !== $rid; }));
            saveData('flow_url_blocks.json', $rules);
            $_SESSION['flash_msg'] = 'URL Block dihapus.';
            $_SESSION['flash_msgType'] = 'info';
            if (ob_get_length()) ob_clean();
            header('Location: ?tab=apps&_t=' . time() . '#flow-url-blocks');
            exit();
        }
    }

    if ($pa === 'master_toggle_flow_url_blocks') {
        $settings = loadData('settings.json');
        if (!is_array($settings)) $settings = [];
        $settings['flow_url_blocks_master_enabled'] = empty($settings['flow_url_blocks_master_enabled']) ? 1 : 0;
        saveData('settings.json', $settings);
        $_SESSION['flash_msg'] = $settings['flow_url_blocks_master_enabled']
            ? '🔐 URL Block Master AKTIF.'
            : '🔓 URL Block Master OFF — semua block dimatikan.';
        $_SESSION['flash_msgType'] = $settings['flow_url_blocks_master_enabled'] ? 'info' : 'success';
        if (ob_get_length()) ob_clean();
        header('Location: ?tab=apps&_t=' . time() . '#flow-url-blocks');
        exit();
    }
    
    if ($pa === 'save_packages') {
        $target = $_POST['target_id'] ?? 'main';
        $packages_data = $_POST['pkg'] ?? [];
        
        $configToSave = [
            'basic' => [],
            'pro' => [],
            'ultimate' => [],
            'trial' => []
        ];
        
        foreach (['basic', 'pro', 'ultimate', 'trial'] as $p) {
            if (isset($packages_data[$p])) {
                foreach ($packages_data[$p] as $app_id => $data) {
                    if (!empty($data['checked'])) {
                        $configToSave[$p][$app_id] = (int)($data['srv'] ?? 1);
                    }
                }
            }
        }
        
        $allPackages = loadData('packages.json');
        $allPackages[$target] = $configToSave;
        
        // Also save custom package prices for this target
        if (isset($_POST['price_basic'])) {
            $allPackages[$target . '_prices'] = [
                'basic' => (int)($_POST['price_basic'] ?? 50000),
                'pro' => (int)($_POST['price_pro'] ?? 100000),
                'ultimate' => (int)($_POST['price_ultimate'] ?? 150000),
                'custom' => (int)($_POST['price_custom'] ?? 0),
            ];
        }
        
        saveData('packages.json', $allPackages);
        
        $msg = 'Konfigurasi Paket & Harga berhasil disimpan untuk ' . ($target === 'main' ? 'Server Asli' : 'Mitra');
        $msgType = 'success';
        $_SESSION['flash_msg'] = $msg;
        $_SESSION['flash_msgType'] = $msgType;
        header("Location: ?tab=packages&target=" . urlencode($target));
        exit();
    }

    // =============================================
    // USERS & MITRA MANAGEMENT ACTIONS
    // =============================================
    if (in_array($pa, ['add_admin', 'add_mitra', 'change_pass', 'delete_user', 'topup_deposit', 'update_mitra_deposit', 'reset_data_mitra', 'login_as_mitra', 'return_to_owner', 'update_perms', 'update_mitra_detail', 'finance_withdraw', 'finance_save_shares', 'finance_distribute'])) {
        $users = loadData('users.json');
        $auditFile = DATA_DIR . '/audit.json';
        $audit = file_exists($auditFile) ? json_decode(file_get_contents($auditFile), true) : [];

        if ($pa === 'add_admin') {
            $new_name = trim($_POST['new_admin_name'] ?? '');
            $new_pass = trim($_POST['new_admin_pass'] ?? '');
            if (!empty($new_pass) && !empty($new_name)) {
                $perms = [
                    'add_member' => isset($_POST['perm_add_member']),
                    'edit_member' => isset($_POST['perm_edit_member']),
                    'view_stats' => isset($_POST['perm_view_stats']),
                    'tab_members' => isset($_POST['perm_tab_members']),
                    'tab_apps' => isset($_POST['perm_tab_apps']),
                    'tab_cookies' => isset($_POST['perm_tab_cookies']),
                    'tab_packages' => isset($_POST['perm_tab_packages']),
                    'tab_settings' => isset($_POST['perm_tab_settings']),
                    'tab_users' => isset($_POST['perm_tab_users']),
                    'tab_mitras' => isset($_POST['perm_tab_mitras']),
                    'tab_audit' => isset($_POST['perm_tab_audit']),
                    'tab_notepad' => isset($_POST['perm_tab_notepad'])
                ];
                $users[] = ['id' => nextId($users), 'role' => 'admin', 'name' => $new_name, 'password_hash' => password_hash($new_pass, PASSWORD_BCRYPT), 'created_at' => date('Y-m-d H:i:s'), 'permissions' => $perms];
                saveData('users.json', $users);
                $audit[] = ['time' => date('Y-m-d H:i:s'), 'action' => 'add_admin', 'by' => $_SESSION['user_id']];
                file_put_contents($auditFile, json_encode($audit, JSON_PRETTY_PRINT));
                $msg = 'Admin kasir baru berhasil ditambahkan!'; $msgType = 'success';
            } else {
                $msg = 'Gagal: Nama dan Password wajib diisi!'; $msgType = 'error';
            }
        } elseif ($pa === 'add_mitra') {
            $new_name = trim($_POST['new_mitra_name'] ?? '');
            $new_email = trim($_POST['new_mitra_email'] ?? '');
            $new_phone = trim($_POST['new_mitra_phone'] ?? '');
            $new_address = trim($_POST['new_mitra_address'] ?? '');
            $new_comm_basic = (int)($_POST['new_mitra_commission_basic'] ?? 0);
            $new_comm_pro = (int)($_POST['new_mitra_commission_pro'] ?? 0);
            $new_comm_ultimate = (int)($_POST['new_mitra_commission_ultimate'] ?? 0);
            $new_pass = trim($_POST['new_mitra_pass'] ?? '');
            
            if (!empty($new_name) && !empty($new_pass)) {
                $users[] = [
                    'id' => nextId($users),
                    'role' => 'mitra',
                    'name' => $new_name,
                    'email' => $new_email,
                    'phone' => $new_phone,
                    'address' => $new_address,
                    'commission_rate' => [
                        'basic' => $new_comm_basic,
                        'pro' => $new_comm_pro,
                        'ultimate' => $new_comm_ultimate
                    ],
                    'balance' => 0,
                    'deposit_balance' => 0,
                    'deposit_minus_limit' => (int)($_POST['new_mitra_minus_limit'] ?? -500000),
                    'points' => 0,
                    'mitra_level' => trim($_POST['new_mitra_level'] ?? 'bronze'),
                    'spins' => 0,
                    'password_hash' => password_hash($new_pass, PASSWORD_BCRYPT, ['cost' => 12]),
                    'created_at' => date('Y-m-d H:i:s'),
                    'is_active' => 1
                ];
                saveData('users.json', $users);
                $audit[] = ['time' => date('Y-m-d H:i:s'), 'action' => 'add_mitra', 'by' => $_SESSION['user_id']];
                file_put_contents($auditFile, json_encode($audit, JSON_PRETTY_PRINT));
                $msg = 'Mitra baru berhasil didaftarkan!'; $msgType = 'success';
            }
        } elseif ($pa === 'change_pass') {
            $uid = (int)($_POST['user_id'] ?? 0);
            $new_pass = trim($_POST['new_pass'] ?? '');
            $targetUser = current(array_filter($users, function($u) use ($uid) { return $u['id'] === $uid; }));
            
            if (!empty($new_pass)) {
                if ($targetUser && $targetUser['role'] === 'owner' && $role === 'admin') {
                    $msg = 'Gagal: Admin tidak memiliki izin mengubah password Owner!'; $msgType = 'error';
                } else {
                    foreach ($users as $i => $u) {
                        if ($u['id'] === $uid) {
                            $users[$i]['password_hash'] = password_hash($new_pass, PASSWORD_BCRYPT);
                            break;
                        }
                    }
                    saveData('users.json', $users);
                    $audit[] = ['time' => date('Y-m-d H:i:s'), 'action' => 'change_password', 'target_user_id' => $uid, 'by' => $_SESSION['user_id']];
                    file_put_contents($auditFile, json_encode($audit, JSON_PRETTY_PRINT));
                    $msg = 'Password berhasil diubah!'; $msgType = 'success';
                }
            }
        } elseif ($pa === 'delete_user') {
            $uid = (int)($_POST['user_id'] ?? 0);
            $ownerCount = count(array_filter($users, function($u) { return $u['role'] === 'owner'; }));
            $targetUser = current(array_filter($users, function($u) use ($uid) { return (int)$u['id'] === $uid; }));
            
            if ($targetUser && $targetUser['role'] === 'owner' && $ownerCount <= 1) {
                $msg = 'Gagal: Tidak dapat menghapus owner terakhir!'; $msgType = 'error';
            } elseif ($targetUser && $targetUser['role'] === 'owner' && $role === 'admin') {
                $msg = 'Gagal: Admin tidak memiliki izin menghapus Owner!'; $msgType = 'error';
            } else {
                $allowDelete = true;
                if ($targetUser && $targetUser['role'] === 'mitra') {
                    $owner_pwd = $_POST['owner_pwd'] ?? '';
                    $valid_owner = false;
                    foreach ($users as $u) {
                        if ($u['role'] === 'owner' && password_verify($owner_pwd, $u['password_hash'])) {
                            $valid_owner = true;
                            break;
                        }
                    }
                    if (!$valid_owner) {
                        $msg = 'Gagal: Password Owner salah! Hapus mitra memerlukan verifikasi Owner.'; 
                        $msgType = 'error';
                        $allowDelete = false;
                    }
                }
                
                if ($allowDelete) {
                    $users = array_values(array_filter($users, function($u) use ($uid) { return (int)$u['id'] !== $uid; }));
                    saveData('users.json', $users);
                    
                    if ($targetUser && $targetUser['role'] === 'mitra') {
                        $members = loadData('members.json');
                        $changed = false;
                        foreach ($members as $i => $m) {
                            if (($m['mitra_id'] ?? null) === $uid) {
                                $members[$i]['mitra_id'] = null;
                                $changed = true;
                            }
                        }
                        if ($changed) saveData('members.json', $members);
                        
                        $dh = loadData('deposit_history.json');
                        $dh = array_values(array_filter($dh, function($d) use ($uid) { return ($d['mitra_id'] ?? 0) != $uid; }));
                        saveData('deposit_history.json', $dh);
                        $ph = loadData('points_history.json');
                        $ph = array_values(array_filter($ph, function($p) use ($uid) { return ($p['mitra_id'] ?? 0) != $uid; }));
                        saveData('points_history.json', $ph);
                        $sh = loadData('spin_history.json');
                        $sh = array_values(array_filter($sh, function($s) use ($uid) { return ($s['mitra_id'] ?? 0) != $uid; }));
                        saveData('spin_history.json', $sh);
                    }

                    $audit[] = ['time' => date('Y-m-d H:i:s'), 'action' => 'delete_user', 'target_user_id' => $uid, 'by' => $_SESSION['user_id']];
                    file_put_contents($auditFile, json_encode($audit, JSON_PRETTY_PRINT));
                    $msg = 'User berhasil dihapus!'; $msgType = 'success';
                }
            }
        } elseif ($pa === 'topup_deposit') {
            $uid = (int)($_POST['mitra_id'] ?? 0);
            $amount = (int)($_POST['topup_amount'] ?? 0);
            $note = trim($_POST['topup_note'] ?? '');
            
            $upload_path = '';
            if (!empty($_FILES['topup_proof']['name']) && $_FILES['topup_proof']['error'] === UPLOAD_ERR_OK) {
                $upload_dir = DATA_DIR . '/uploads';
                if (!is_dir($upload_dir)) mkdir($upload_dir, 0755, true);
                
                $file_size = $_FILES['topup_proof']['size'];
                $max_size = 10 * 1024 * 1024; // 10MB
                $allowed_ext = ['jpg','jpeg','png','gif','webp','pdf'];
                $ext = strtolower(pathinfo($_FILES['topup_proof']['name'], PATHINFO_EXTENSION));
                
                if ($file_size > $max_size) {
                    $msg = 'File terlalu besar! Maksimal 10MB.'; $msgType = 'error';
                    goto skip_topup;
                }
                if (!in_array($ext, $allowed_ext)) {
                    $msg = 'Format file tidak didukung! Gunakan JPG, PNG, GIF, WEBP, atau PDF.'; $msgType = 'error';
                    goto skip_topup;
                }
                
                $filename = 'proof_' . $uid . '_' . time() . '.' . $ext;
                if (move_uploaded_file($_FILES['topup_proof']['tmp_name'], $upload_dir . '/' . $filename)) {
                    $upload_path = 'data/uploads/' . $filename;
                }
            }
            
            if ($amount > 0) {
                foreach ($users as $i => $u) {
                    if ($u['id'] === $uid && $u['role'] === 'mitra') {
                        $before = $u['deposit_balance'] ?? 0;
                        $users[$i]['deposit_balance'] = $before + $amount;
                        saveData('users.json', $users);
                        
                        $dh = loadData('deposit_history.json');
                        $dh[] = ['id'=>count($dh)+1,'mitra_id'=>$uid,'amount'=>$amount,'balance_before'=>$before,'balance_after'=>$before+$amount,'date'=>date('Y-m-d H:i:s'),'note'=>$note ?: 'Top Up Deposit','by'=>$_SESSION['user_name'] ?? 'Owner','proof'=>$upload_path];
                        saveData('deposit_history.json', $dh);
                        
                        $audit[] = ['time'=>date('Y-m-d H:i:s'),'action'=>'topup_deposit','target_user_id'=>$uid,'amount'=>$amount,'by'=>$_SESSION['user_name'] ?? 'Owner'];
                        file_put_contents($auditFile, json_encode($audit, JSON_PRETTY_PRINT));
                        $formatted_amount = number_format($amount,0,',','.');
                        $msg = 'Top up deposit Rp '.$formatted_amount.' berhasil!'; $msgType = 'success';
                        break;
                    }
                }
            }
            skip_topup:
        } elseif ($pa === 'update_mitra_deposit') {
            $uid = (int)($_POST['mitra_id'] ?? 0);
            $minus_limit = (int)($_POST['minus_limit'] ?? -500000);
            $mitra_level = trim($_POST['mitra_level'] ?? 'bronze');
            foreach ($users as $i => $u) {
                if ($u['id'] === $uid && $u['role'] === 'mitra') {
                    $users[$i]['deposit_minus_limit'] = $minus_limit;
                    $users[$i]['mitra_level'] = $mitra_level;
                    saveData('users.json', $users);
                    $msg = 'Konfigurasi mitra berhasil diperbarui!'; $msgType = 'success';
                    break;
                }
            }
        } elseif ($pa === 'reset_data_mitra') {
            $uid = (int)($_POST['mitra_id'] ?? 0);
            $pwd = $_POST['owner_pwd'] ?? '';
            
            $owner = current(array_filter($users, function($u) { return $u['role'] === 'owner'; }));
            if ($owner && password_verify($pwd, $owner['password_hash'])) {
                $targetUser = current(array_filter($users, function($u) use ($uid) { return $u['id'] === $uid && $u['role'] === 'mitra'; }));
                if ($targetUser) {
                    $old_balance = $targetUser['balance'] ?? 0;
                    foreach ($users as $i => $u) {
                        if ($u['id'] === $uid) {
                            $users[$i]['balance'] = 0;
                            $users[$i]['deposit_balance'] = 0;
                            $users[$i]['points'] = 0;
                            $users[$i]['spins'] = 0;
                            break;
                        }
                    }
                    saveData('users.json', $users);
                    
                    $membersFile = DATA_DIR . '/members.json';
                    $all_members = file_exists($membersFile) ? json_decode(file_get_contents($membersFile), true) : [];
                    $filtered_members = array_values(array_filter($all_members, function($m) use ($uid) {
                        return !isset($m['mitra_id']) || $m['mitra_id'] != $uid;
                    }));
                    file_put_contents($membersFile, json_encode($filtered_members, JSON_PRETTY_PRINT));
                    
                    $dh = loadData('deposit_history.json');
                    $dh = array_values(array_filter($dh, function($d) use ($uid) { return ($d['mitra_id'] ?? 0) != $uid; }));
                    saveData('deposit_history.json', $dh);
                    
                    $ph = loadData('points_history.json');
                    $ph = array_values(array_filter($ph, function($p) use ($uid) { return ($p['mitra_id'] ?? 0) != $uid; }));
                    saveData('points_history.json', $ph);
                    
                    $sh = loadData('spin_history.json');
                    $sh = array_values(array_filter($sh, function($s) use ($uid) { return ($s['mitra_id'] ?? 0) != $uid; }));
                    saveData('spin_history.json', $sh);
                    
                    $audit[] = ['time' => date('Y-m-d H:i:s'), 'action' => 'reset_data_mitra', 'target_user_id' => $uid, 'amount_reset' => $old_balance, 'by' => $_SESSION['user_name'] ?? 'Owner'];
                    file_put_contents($auditFile, json_encode($audit, JSON_PRETTY_PRINT));
                    
                    $msg = 'Semua data pendapatan, komisi, deposit, poin, spin, dan member dari mitra tersebut berhasil direset.'; $msgType = 'success';
                }
            } else {
                $msg = 'Gagal mereset data: Password Owner salah.'; $msgType = 'error';
            }
        } elseif ($pa === 'finance_withdraw' && $role === 'owner') {
            $amount = (int)($_POST['amount'] ?? 0);
            $note = trim($_POST['note'] ?? '');
            if ($amount > 0) {
                $finance = loadData('finance.json');
                if (empty($finance['history'])) $finance['history'] = [];
                $finance['total_withdrawn'] = ($finance['total_withdrawn'] ?? 0) + $amount;
                array_unshift($finance['history'], [
                    'date' => date('Y-m-d H:i:s'),
                    'amount' => $amount,
                    'note' => $note,
                    'type' => 'Tutup Buku'
                ]);
                saveData('finance.json', $finance);
                $msg = 'Tutup buku berhasil! Pendapatan telah dikurangi.'; $msgType = 'success';
            }
        } elseif ($pa === 'finance_save_shares' && $role === 'owner') {
            $names = $_POST['share_name'] ?? [];
            $percents = $_POST['share_percent'] ?? [];
            $shares = [];
            $total_percent = 0;
            for ($i = 0; $i < count($names); $i++) {
                if (!empty($names[$i]) && (int)$percents[$i] > 0) {
                    $shares[] = ['name' => trim($names[$i]), 'percent' => (int)$percents[$i]];
                    $total_percent += (int)$percents[$i];
                }
            }
            if ($total_percent > 100) {
                $msg = 'Total persentase tidak boleh lebih dari 100%'; $msgType = 'error';
            } else {
                $finance = loadData('finance.json');
                $finance['profit_shares'] = $shares;
                saveData('finance.json', $finance);
                $msg = 'Pengaturan Bagi Hasil disimpan!'; $msgType = 'success';
            }
        } elseif ($pa === 'finance_distribute' && $role === 'owner') {
            $amount = (int)($_POST['amount'] ?? 0);
            $note = 'Bagi Hasil: ' . trim($_POST['note'] ?? '');
            if ($amount > 0) {
                $finance = loadData('finance.json');
                if (empty($finance['history'])) $finance['history'] = [];
                $finance['total_withdrawn'] = ($finance['total_withdrawn'] ?? 0) + $amount;
                
                $details = [];
                $profit_shares = $finance['profit_shares'] ?? [];
                foreach ($profit_shares as $ps) {
                    $share_amount = ($amount * $ps['percent']) / 100;
                    $details[] = $ps['name'] . ' (' . $ps['percent'] . '% = Rp ' . number_format($share_amount,0,',','.') . ')';
                }
                if (!empty($details)) {
                    $note .= ' | ' . implode(', ', $details);
                }
                
                array_unshift($finance['history'], [
                    'date' => date('Y-m-d H:i:s'),
                    'amount' => $amount,
                    'note' => $note,
                    'type' => 'Bagi Hasil'
                ]);
                saveData('finance.json', $finance);
                $msg = 'Bagi hasil berhasil didistribusikan dan tutup buku!'; $msgType = 'success';
            }
        } elseif ($pa === 'login_as_mitra') {
            $uid = (int)($_POST['mitra_id'] ?? 0);
            $targetUser = current(array_filter($users, function($u) use ($uid) { return $u['id'] === $uid && $u['role'] === 'mitra'; }));
            if ($targetUser) {
                $_SESSION['original_owner_id'] = $_SESSION['user_id'];
                $_SESSION['original_owner_name'] = $_SESSION['user_name'];
                
                $_SESSION['admin_role'] = 'mitra';
                $_SESSION['user_id'] = $targetUser['id'];
                $_SESSION['user_name'] = $targetUser['name'];
                $_SESSION['commission_rate'] = $targetUser['commission_rate'] ?? 0;
                $_SESSION['balance'] = $targetUser['balance'] ?? 0;
                $_SESSION['permissions'] = ['add_member' => true, 'edit_member' => false, 'inject_cookies' => false, 'view_stats' => true];
                
                header("Location: ?tab=mitradashboard");
                exit;
            }
        } elseif ($pa === 'return_to_owner') {
            if (isset($_SESSION['original_owner_id'])) {
                $_SESSION['admin_role'] = 'owner';
                $_SESSION['user_id'] = $_SESSION['original_owner_id'];
                $_SESSION['user_name'] = $_SESSION['original_owner_name'];
                $_SESSION['permissions'] = ['add_member' => true, 'edit_member' => true, 'inject_cookies' => true, 'view_stats' => true];
                unset($_SESSION['original_owner_id']);
                unset($_SESSION['original_owner_name']);
                unset($_SESSION['commission_rate']);
                unset($_SESSION['balance']);
                
                header("Location: ?tab=mitras");
                exit;
            }
        } elseif ($pa === 'update_perms') {
            $uid = (int)($_POST['user_id'] ?? 0);
            foreach ($users as $i => $u) {
                if ($u['id'] === $uid && $u['role'] === 'admin') {
                    $users[$i]['permissions'] = [
                        'add_member' => isset($_POST['perm_add_member']),
                        'edit_member' => isset($_POST['perm_edit_member']),
                        'view_stats' => isset($_POST['perm_view_stats']),
                        'tab_members' => isset($_POST['perm_tab_members']),
                        'tab_apps' => isset($_POST['perm_tab_apps']),
                        'tab_cookies' => isset($_POST['perm_tab_cookies']),
                        'tab_packages' => isset($_POST['perm_tab_packages']),
                        'tab_settings' => isset($_POST['perm_tab_settings']),
                        'tab_users' => isset($_POST['perm_tab_users']),
                        'tab_mitras' => isset($_POST['perm_tab_mitras']),
                        'tab_audit' => isset($_POST['perm_tab_audit']),
                        'tab_notepad' => isset($_POST['perm_tab_notepad'])
                    ];
                    break;
                }
            }
            saveData('users.json', $users);
            // If editing own permissions, update session too
            if ($uid === $_SESSION['user_id']) {
                $updated_user = current(array_filter($users, function($u) use ($uid) { return $u['id'] === $uid; }));
                if ($updated_user) {
                    $_SESSION['permissions'] = $updated_user['permissions'];
                }
            }
            $msg = 'Izin akses admin berhasil diperbarui!'; $msgType = 'success';
        } elseif ($pa === 'update_mitra_detail') {
            $uid = (int)($_POST['user_id'] ?? 0);
            foreach ($users as $i => $u) {
                if ($u['id'] === $uid && $u['role'] === 'mitra') {
                    $users[$i]['name'] = trim($_POST['m_name'] ?? '');
                    $users[$i]['email'] = trim($_POST['m_email'] ?? '');
                    $users[$i]['phone'] = trim($_POST['m_phone'] ?? '');
                    $users[$i]['commission_rate'] = [
                        'basic' => (int)($_POST['m_comm_basic'] ?? 0),
                        'pro' => (int)($_POST['m_comm_pro'] ?? 0),
                        'ultimate' => (int)($_POST['m_comm_ultimate'] ?? 0)
                    ];
                    break;
                }
            }
            saveData('users.json', $users);
            $msg = 'Detail mitra berhasil diperbarui!'; $msgType = 'success';
        }
    }

    // Apply PRG Pattern for all other actions
    if (!empty($msg)) {
        $_SESSION['flash_msg'] = $msg;
        $_SESSION['flash_msgType'] = $msgType;
        
        $tab = $_GET['tab'] ?? '';
        $redirect_url = '?tab=' . urlencode($tab);
        if (empty($tab)) $redirect_url = '?';
        header("Location: " . $redirect_url);
        exit();
    }
}

// Load packages configuration
$PACKAGES_CONFIG = loadData('packages.json');
if (empty($PACKAGES_CONFIG['main'])) {
    $PACKAGES_CONFIG['main'] = [
        'basic'    => ['google-flow'=>3, 'google-whisk'=>3, 'single-sora'=>1],
        'pro'      => ['google-flow'=>3, 'google-whisk'=>3, 'grok'=>3, 'single-sora'=>1],
        'ultimate' => ['google-flow'=>5, 'google-whisk'=>5, 'grok'=>5, 'single-sora'=>1, 'bulk-sora'=>1],
    ];
}

// Prepare member list
$members = loadData('members.json');
usort($members, function($a,$b){ return strtotime($b['created_at']??'0') - strtotime($a['created_at']??'0'); });

// Apply Filters
if (isset($_GET['search']) || isset($_GET['f_paket']) || isset($_GET['f_status']) || isset($_GET['f_expire']) || isset($_GET['f_date']) || isset($_GET['f_payment']) || isset($_GET['f_start_date']) || isset($_GET['f_end_date'])) {
    $search = strtolower(trim($_GET['search'] ?? ''));
    $f_paket = trim($_GET['f_paket'] ?? '');
    $f_status = trim($_GET['f_status'] ?? '');
    $f_expire = trim($_GET['f_expire'] ?? '');
    $f_date = trim($_GET['f_date'] ?? '');
    $f_payment = trim($_GET['f_payment'] ?? '');
    $f_start_date = trim($_GET['f_start_date'] ?? '');
    $f_end_date = trim($_GET['f_end_date'] ?? '');
    
    $filtered_members = [];
    $today = date('Y-m-d');

    foreach ($members as $m) {
        $match = true;
        
        // Filter by Mitra
        if ($role === 'mitra' && ($m['mitra_id'] ?? null) !== $_SESSION['user_id']) {
            continue;
        }
        
        // Filter by Mitra (for Owner/Admin)
        if (($role === 'owner' || $role === 'admin') && isset($_GET['filter_applied']) && isset($_GET['f_mitra']) && $_GET['f_mitra'] !== '') {
            $m_id = $m['mitra_id'] ?? 'none';
            if (empty($m_id)) $m_id = 'none';
            if ((string)$m_id !== $_GET['f_mitra']) {
                $match = false;
            }
        }
        
        // Search by name or code
        if ($search !== '') {
            if (strpos(strtolower($m['name']), $search) === false && strpos(strtolower($m['code']), $search) === false) {
                $match = false;
            }
        }
        
        // Filter by package
        if ($f_paket !== '' && $m['package'] !== $f_paket) {
            $match = false;
        }
        
        // Filter by payment status
        if ($f_payment !== '') {
            $ps = $m['payment_status'] ?? 'lunas'; // default to lunas if not set
            if ($f_payment !== $ps) {
                $match = false;
            }
        }
        
        // Filter by start and end date (transaction created_at)
        if ($f_start_date !== '') {
            $c_date = date('Y-m-d', strtotime($m['created_at'] ?? '0'));
            if ($c_date < $f_start_date) {
                $match = false;
            }
        }
        if ($f_end_date !== '') {
            $c_date = date('Y-m-d', strtotime($m['created_at'] ?? '0'));
            if ($c_date > $f_end_date) {
                $match = false;
            }
        }
        
        // Filter by status (aktif, nonaktif, expired)
        if ($f_status !== '') {
            $isExpired = ($m['expiry_date'] < $today);
            if ($f_status === 'aktif') {
                if (!$m['is_active'] || $isExpired) $match = false;
            } elseif ($f_status === 'nonaktif') {
                if ($m['is_active']) $match = false;
            } elseif ($f_status === 'expired') {
                if (!$isExpired) $match = false;
            }
        }
        
        // Filter by expiry (< 14 Hari, < 7 Hari, < 3 Hari)
        if ($f_expire !== '' && $match) {
            $isExpired = ($m['expiry_date'] < $today);
            if ($isExpired) {
                $match = false; // Already expired, so remaining days is 0, but user wants active remaining days
            } else {
                $expDateTime = new DateTime($m['expiry_date']);
                $todayDateTime = new DateTime($today);
                $diffDays = (int)$todayDateTime->diff($expDateTime)->days;
                if ($f_expire === '14' && $diffDays > 14) $match = false;
                if ($f_expire === '7' && $diffDays > 7) $match = false;
                if ($f_expire === '3' && $diffDays > 3) $match = false;
            }
        }
        
        // Filter by custom date
        if ($f_date !== '' && $match) {
            if ($m['expiry_date'] !== $f_date) {
                $match = false;
            }
        }
        
        if ($match) {
            $filtered_members[] = $m;
        }
    }
    $members = $filtered_members;
} else {
    // If no GET filters are set, we still need to filter for Mitra!
    if ($role === 'mitra') {
        $filtered_members = [];
        foreach ($members as $m) {
            if (($m['mitra_id'] ?? null) === $_SESSION['user_id']) {
                $filtered_members[] = $m;
            }
        }
        $members = $filtered_members;
    }
}

// Apply Sorting
$f_sort = $_GET['f_sort'] ?? 'newest';
if ($f_sort !== 'newest') {
    usort($members, function($a, $b) use ($f_sort) {
        if ($f_sort === 'oldest') {
            return strtotime($a['created_at'] ?? '0') - strtotime($b['created_at'] ?? '0');
        } elseif ($f_sort === 'expire_asc') {
            return strtotime($a['expiry_date']) - strtotime($b['expiry_date']);
        } elseif ($f_sort === 'expire_desc') {
            return strtotime($b['expiry_date']) - strtotime($a['expiry_date']);
        } elseif ($f_sort === 'price_desc') {
            return (int)($b['price_paid'] ?? 0) - (int)($a['price_paid'] ?? 0);
        } elseif ($f_sort === 'price_asc') {
            return (int)($a['price_paid'] ?? 0) - (int)($b['price_paid'] ?? 0);
        }
        return 0;
    });
}

$todayDate = new DateTime();
$total = count($members); // Used the filtered members list so Mitra only sees their own totals
$active = 0; $expired = 0; $totalRevenue = 0; $totalSales = 0; $totalPaid = 0; $totalTrial = 0;
foreach ($members as $m) {
    $exp = new DateTime($m['expiry_date']);
    if ($todayDate > $exp) $expired++;
    elseif ($m['is_active']) $active++;
    
    // Count trial vs paid
    if (($m['package'] ?? '') === 'trial' || (int)($m['price_paid'] ?? 0) === 0) {
        $totalTrial++;
    } else {
        $totalPaid++;
    }
    
    if ($role === 'mitra') {
        $rate_config = $_SESSION['commission_rate'] ?? [];
        if (!is_array($rate_config)) {
            $rate_config = ['basic' => (int)$rate_config, 'pro' => (int)$rate_config, 'ultimate' => (int)$rate_config];
        }
        $m_pkg = $m['package'] ?? 'basic';
        $rate = $rate_config[$m_pkg] ?? $rate_config['basic'] ?? 0;
        
        $grossSale = (int)($m['price_paid'] ?? 0);
        $totalSales += $grossSale;
        $totalRevenue += $rate;
    } else {
        $totalRevenue += (int)($m['price_paid'] ?? 0);
    }
}

// Adjust Total Revenue for Owner based on Withdrawn amount
if ($role === 'owner') {
    $financeData = loadData('finance.json');
    $total_withdrawn = (int)($financeData['total_withdrawn'] ?? 0);
    // Only deduct if not viewing a specific filtered date (to avoid negative daily revenue)
    if (empty($_GET['f_date']) && empty($_GET['f_expire'])) {
        $totalRevenue = max(0, $totalRevenue - $total_withdrawn);
    }
}

// =============================================
// EXPORT HANDLER (Setelah filter dan kalkulasi)
// =============================================
if (isset($_GET['export_format']) && in_array($_GET['export_format'], ['export_csv', 'export_txt'])) {
    $is_csv = $_GET['export_format'] === 'export_csv';
    $ext = $is_csv ? 'csv' : 'txt';
    $filename = "Laporan_Keuangan_TEXA_" . date('Ymd_His') . "." . $ext;
    
    header('Content-Type: text/' . ($is_csv ? 'csv' : 'plain'));
    header('Content-Disposition: attachment; filename="' . $filename . '"');
    
    $out = fopen('php://output', 'w');
    
    if ($is_csv) {
        // Output BOM for Excel UTF-8 support
        fputs($out, $bom =(chr(0xEF) . chr(0xBB) . chr(0xBF)));
        fputcsv($out, ['No', 'Nama Member', 'Kode Akses', 'Paket', 'Status', 'Expire Date', 'Pembayaran', 'Harga/Pendapatan (Rp)', 'Dibuat Pada', 'Dibuat Oleh']);
    } else {
        fwrite($out, "=== LAPORAN KEUANGAN & MEMBER TEXA ===\r\n");
        fwrite($out, "Tanggal Export: " . date('Y-m-d H:i:s') . "\r\n");
        if ($role === 'mitra') {
            fwrite($out, "Total Penjualan Kotor: Rp " . number_format($totalSales, 0, ',', '.') . "\r\n");
            fwrite($out, "Total Pendapatan Bersih (Komisi): Rp " . number_format($totalRevenue, 0, ',', '.') . "\r\n");
        } else {
            fwrite($out, "Total Pendapatan: Rp " . number_format($totalRevenue, 0, ',', '.') . "\r\n");
        }
        fwrite($out, "Total Member Terfilter: " . count($members) . "\r\n");
        fwrite($out, str_repeat("-", 80) . "\r\n\r\n");
    }
    
    $no = 1;
    foreach ($members as $m) {
        $status_txt = $m['is_active'] ? ($m['expiry_date'] < date('Y-m-d') ? 'Expired' : 'Aktif') : 'Nonaktif';
        $harga = (int)($m['price_paid'] ?? 0);
        $creator = $m['created_by'] ?? 'System';
        $pembayaran = ucfirst(str_replace('_', ' ', $m['payment_status'] ?? 'lunas'));
        
        if ($is_csv) {
            fputcsv($out, [$no++, $m['name'], $m['code'], ucfirst($m['package']), $status_txt, $m['expiry_date'], $pembayaran, $harga, $m['created_at'], $creator]);
        } else {
            fwrite($out, "[$no] {$m['name']} (Kode: {$m['code']})\r\n");
            fwrite($out, "    Paket     : " . ucfirst($m['package']) . "\r\n");
            fwrite($out, "    Status    : " . $status_txt . " | Expire: " . $m['expiry_date'] . "\r\n");
            fwrite($out, "    Pembayaran: " . $pembayaran . "\r\n");
            fwrite($out, "    Pendapatan: Rp " . number_format($harga, 0, ',', '.') . "\r\n");
            fwrite($out, "    Dibuat    : {$m['created_at']} oleh {$creator}\r\n");
            fwrite($out, "    " . str_repeat("-", 40) . "\r\n");
            $no++;
        }
    }
    
    if ($is_csv) {
        fputcsv($out, ['', '', '', '', '', '', 'TOTAL PENDAPATAN', $totalRevenue, '', '']);
    }
    
    fclose($out);
    exit();
}

// Edit app fetch
$editApp = null;
if (isset($_GET['edit_app'])) {
    $eaid = $_GET['edit_app'];
    foreach (loadData('applications.json') as $a) { if ($a['id'] === $eaid) { $editApp = $a; break; } }
}

// Reload all apps for display
$allAppsForAdmin = loadData('applications.json');
usort($allAppsForAdmin, function($a,$b){ return ($a['sort_order']??0) - ($b['sort_order']??0); });
// Rebuild active labels for cookies tab
$APP_LABELS = []; $APP_MAX = []; $APP_URLS_PHP = [];
foreach ($allAppsForAdmin as $app) {
    if ($app['is_active']) {
        $APP_LABELS[$app['id']] = $app['name'];
        $APP_MAX[$app['id']] = (int)$app['max_servers'];
        if (!empty($app['custom_servers'])) {
            $APP_MAX[$app['id']] = count($app['custom_servers']); // Prioritize custom servers count
        }
        $APP_URLS_PHP[$app['id']] = $app['default_url'] ?? '';
    }
}

// Prepare cookie metadata for UI
$cookiesData = loadData('cookies.json');
$cookieMeta = [];
foreach ($cookiesData as $c) {
    $key = $c['app_id'] . '_' . $c['server_index'];
    $cookieMeta[$key] = [
        'updated_by' => $c['updated_by'] ?? 'System',
        'updated_at' => $c['updated_at'] ?? 'Unknown'
    ];
}
?>
<!DOCTYPE html>
<html lang="id">
<head>
<meta charset="UTF-8"/>
<meta name="viewport" content="width=device-width,initial-scale=1.0"/>
<title>TEKNO-APPS Member Manager</title>
<link href="https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600;700;800&display=swap" rel="stylesheet"/>
<style>
*,*::before,*::after{box-sizing:border-box;margin:0;padding:0}
:root{--deep:#020c18;--blue:#0066ff;--bright:#0099ff;--light:#4db8ff;--text:#e8f4ff;--sub:#7aaed4;--muted:#4a7a9b;--glass:rgba(4,22,48,.85);--border:rgba(0,150,255,.18);--ok:#00e676;--err:#ff4d4d;--warn:#ffaa00}
body{min-height:100vh;background:var(--deep);font-family:"Inter",sans-serif;color:var(--text)}
body::before{content:"";position:fixed;inset:0;pointer-events:none;background:radial-gradient(ellipse at 15% 15%,rgba(0,80,180,.22) 0%,transparent 55%),radial-gradient(ellipse at 85% 85%,rgba(0,40,130,.16) 0%,transparent 55%)}
.wrap{max-width:1040px;margin:0 auto;padding:28px 18px;position:relative;z-index:1}
.hdr{display:flex;align-items:center;gap:14px;margin-bottom:26px}
.logo{width:46px;height:46px;border-radius:13px;background:linear-gradient(135deg,#0044cc,#0099ff);display:flex;align-items:center;justify-content:center;font-size:15px;font-weight:900;box-shadow:0 0 18px rgba(0,150,255,.4)}
.hdr-text h1{font-size:20px;font-weight:800;background:linear-gradient(135deg,#e0f0ff,#4db8ff);-webkit-background-clip:text;-webkit-text-fill-color:transparent;background-clip:text}
.hdr-text p{font-size:11px;color:var(--muted);margin-top:2px}
.stats{display:grid;grid-template-columns:repeat(3,1fr);gap:12px;margin-bottom:22px}
.sc{background:var(--glass);border:1px solid var(--border);border-radius:13px;padding:16px 18px;backdrop-filter:blur(12px)}
.sv{font-size:26px;font-weight:800;margin-bottom:3px}
.sl{font-size:10px;color:var(--muted);letter-spacing:.5px;text-transform:uppercase}
.sc.t .sv{color:var(--bright)}.sc.a .sv{color:var(--ok)}.sc.e .sv{color:var(--err)}
.alert{padding:11px 15px;border-radius:9px;margin-bottom:18px;font-size:12.5px;font-weight:500}
.alert.success{background:rgba(0,230,118,.1);border:1px solid rgba(0,230,118,.3);color:var(--ok)}
.alert.error{background:rgba(255,77,77,.1);border:1px solid rgba(255,77,77,.3);color:var(--err)}
.alert.info{background:rgba(0,150,255,.1);border:1px solid rgba(0,150,255,.3);color:var(--light)}
.card{background:var(--glass);border:1px solid var(--border);border-radius:15px;backdrop-filter:blur(16px);padding:22px;margin-bottom:22px;overflow:visible;}
.card.edit-card{border-color:rgba(255,170,0,.3);box-shadow:0 0 20px rgba(255,170,0,.1)}
.ct{font-size:13px;font-weight:700;color:#a8d8ff;margin-bottom:16px;display:flex;align-items:center;gap:8px}
.ct::before{content:"";width:3px;height:15px;border-radius:2px;background:linear-gradient(180deg,var(--blue),var(--bright));flex-shrink:0}
.ct.edit-ct::before{background:linear-gradient(180deg,var(--warn),#ff8800)}
.fg{display:grid;grid-template-columns:1fr 1fr;gap:12px}
.fi{display:flex;flex-direction:column;gap:5px}
.fi.full{grid-column:1/-1}
label{font-size:10px;font-weight:700;color:var(--light);letter-spacing:.8px;text-transform:uppercase}
input[type=text],input[type=url],input[type=date],input[type=search],input[type=number]{width:100%;padding:9px 13px;background:rgba(0,20,50,.6);border:1px solid var(--border);border-radius:8px;color:var(--text);font-size:13px;font-family:inherit;outline:none;transition:border-color .2s,box-shadow .2s}
input:focus{border-color:var(--bright);box-shadow:0 0 0 3px rgba(0,150,255,.15)}
input::placeholder{color:var(--muted)}
.dur-group{display:flex;gap:8px;flex-wrap:wrap}
.dur-btn{flex:1;padding:10px 8px;border-radius:9px;border:2px solid var(--border);background:rgba(0,30,80,.4);color:var(--sub);font-size:12px;font-weight:700;font-family:inherit;cursor:pointer;transition:all .2s;text-align:center}
.dur-btn:hover{border-color:var(--bright);color:var(--light);background:rgba(0,60,160,.3)}
.dur-btn.selected{border-color:var(--blue);background:rgba(0,80,200,.35);color:#fff;box-shadow:0 0 12px rgba(0,100,255,.3)}
.dur-badge{display:block;font-size:9px;color:var(--muted);margin-top:2px;font-weight:500;letter-spacing:.5px}
.dur-btn.selected .dur-badge{color:var(--light)}
.pkg-group{display:grid;grid-template-columns:repeat(4,1fr);gap:8px}
.pkg-btn{padding:12px 6px;border-radius:10px;border:2px solid var(--border);background:rgba(0,20,60,.5);color:var(--sub);font-size:13px;font-weight:700;font-family:inherit;cursor:pointer;transition:all .2s;text-align:center;line-height:1.3;white-space:nowrap}
.pkg-btn:hover{border-color:var(--bright);background:rgba(0,60,160,.3);color:var(--light)}
.pkg-btn .pkg-name{display:block;font-size:13px;font-weight:800}
.pkg-btn .pkg-desc{display:block;font-size:9px;margin-top:3px;font-weight:500;letter-spacing:.3px;opacity:.7}
.pkg-btn[data-pkg="basic"].selected{border-color:#0099ff;background:rgba(0,100,220,.25);color:#7ad4ff}
.pkg-btn[data-pkg="basic"].selected .pkg-desc{opacity:1}
.pkg-btn[data-pkg="pro"].selected{border-color:#00e676;background:rgba(0,160,80,.2);color:#00e676}
.pkg-btn[data-pkg="pro"].selected .pkg-desc{opacity:1}
.pkg-btn[data-pkg="ultimate"].selected{border-color:#ffaa00;background:rgba(180,110,0,.2);color:#ffcc44}
.pkg-btn[data-pkg="ultimate"].selected .pkg-desc{opacity:1}
.pkg-btn[data-pkg="custom"].selected{border-color:#cc44ff;background:rgba(100,0,180,.2);color:#ee88ff}
.pkg-btn[data-pkg="custom"].selected .pkg-desc{opacity:1}
.custom-cfg{display:none;margin-top:12px;padding:14px;background:rgba(100,0,200,.08);border:1px solid rgba(150,50,255,.2);border-radius:10px}
.custom-cfg.visible{display:block}
.app-row{display:flex;align-items:center;justify-content:space-between;padding:7px 0;border-bottom:1px solid rgba(0,80,160,.1);gap:12px}
.app-row:last-child{border-bottom:none}
.app-chk{display:flex;align-items:center;gap:8px;flex:1}
.app-chk input[type=checkbox]{width:16px;height:16px;cursor:pointer;accent-color:var(--bright)}
.app-chk label{font-size:12px;font-weight:500;letter-spacing:0;text-transform:none;color:var(--text);cursor:pointer}
.srv-ctrl{display:flex;align-items:center;gap:6px;flex-shrink:0}
.srv-ctrl label{font-size:10px;color:var(--muted);white-space:nowrap}
.srv-ctrl input{width:58px;text-align:center;padding:5px 8px}
.btn{padding:10px 20px;border-radius:8px;border:none;font-size:12.5px;font-weight:700;font-family:inherit;cursor:pointer;transition:all .2s;display:inline-flex;align-items:center;gap:6px;text-decoration:none}
.bp{background:linear-gradient(135deg,#0055cc,#0088ff);color:#fff;box-shadow:0 4px 14px rgba(0,100,255,.3)}
.bp:hover{transform:translateY(-1px);box-shadow:0 6px 20px rgba(0,120,255,.4)}
.bw{background:linear-gradient(135deg,#aa6000,#ff9900);color:#fff;box-shadow:0 4px 14px rgba(200,100,0,.3)}
.bw:hover{transform:translateY(-1px);box-shadow:0 6px 20px rgba(200,120,0,.4)}
.bsm{padding:5px 11px;font-size:11px;border-radius:7px}
.bd{background:rgba(180,20,20,.3);color:#ff8080;border:1px solid rgba(255,60,60,.2)}
.bd:hover{background:rgba(200,30,30,.5)}
.bt{background:rgba(0,60,140,.3);color:var(--light);border:1px solid var(--border)}
.bt:hover{background:rgba(0,100,200,.4)}
.be2{background:rgba(180,120,0,.25);color:#ffcc44;border:1px solid rgba(255,180,0,.2)}
.be2:hover{background:rgba(200,140,0,.4)}
.sr{display:flex;gap:10px;margin-bottom:14px}
.sr input{flex:1}
.tw{overflow-x:auto; max-width: 100%;}
table{width:100%;border-collapse:collapse; white-space: normal;}
th{font-size:10px;font-weight:700;color:var(--muted);letter-spacing:.7px;text-transform:uppercase;padding:7px 5px;text-align:left;border-bottom:1px solid var(--border)}
td{padding:8px 5px;font-size:11px;border-bottom:1px solid rgba(0,80,160,.1);vertical-align:middle; word-break: break-word;}
tr:last-child td{border-bottom:none}
tr:hover td{background:rgba(0,60,140,.12)}
code.kd{display:inline-block; max-width:100%; vertical-align:bottom; background:rgba(0,80,160,.25);border:1px solid var(--border);border-radius:6px;padding:3px 8px;font-size:11px;font-family:"Courier New",monospace;color:var(--light);letter-spacing:0.5px; word-break: break-all;}
.badge{display:inline-flex;align-items:center;padding:2px 7px;border-radius:20px;font-size:9.5px;font-weight:700;letter-spacing:.4px}
.ba{background:rgba(0,230,118,.1);border:1px solid rgba(0,230,118,.3);color:var(--ok)}
.be{background:rgba(255,77,77,.1);border:1px solid rgba(255,77,77,.2);color:var(--err)}
.bn{background:rgba(100,100,100,.12);border:1px solid rgba(150,150,150,.18);color:#888}
.pb-basic{background:rgba(0,100,220,.15);border:1px solid rgba(0,150,255,.3);color:#7ad4ff}
.pb-pro{background:rgba(0,160,80,.12);border:1px solid rgba(0,230,118,.25);color:#00e676}
.pb-ultimate{background:rgba(200,120,0,.15);border:1px solid rgba(255,170,0,.3);color:#ffcc44}
.pb-custom{background:rgba(120,0,200,.15);border:1px solid rgba(180,50,255,.3);color:#ee88ff}
.sisa{font-size:10.5px}
.sisa.ok{color:var(--ok)}.sisa.warn{color:var(--warn)}.sisa.err{color:var(--err)}
.empty{text-align:center;padding:36px;color:var(--muted);font-size:13px}
.tabs{display:flex;flex-wrap:wrap;gap:10px;margin-bottom:20px;border-bottom:1px solid var(--border);padding-bottom:12px;}
.tab-btn{flex-shrink:0; white-space:nowrap;}
.tab-btn{background:transparent;border:none;color:var(--muted);font-size:14px;font-weight:700;cursor:pointer;padding:8px 16px;border-radius:8px;transition:0.2s}
.tab-btn:hover{color:var(--light);background:var(--glass)}
.tab-btn.active{color:var(--bright);background:rgba(0,100,255,0.15);box-shadow:0 0 10px rgba(0,150,255,0.2)}
.tab-content{display:none}
.tab-content.active{display:block}
textarea{width:100%;background:rgba(0,20,50,.6);border:1px solid var(--border);border-radius:8px;padding:12px;color:var(--text);font-family:monospace;font-size:12px;resize:vertical;min-height:150px;outline:none}
textarea:focus{border-color:var(--bright);box-shadow:0 0 0 3px rgba(0,150,255,.15)}
select{width:100%;background:rgba(0,20,50,.6);border:1px solid var(--border);border-radius:8px;padding:9px 13px;color:var(--text);font-size:13px;outline:none;cursor:pointer}
select option { background-color: var(--deep); color: var(--text); }

/* Dropdown Actions */
.act-dropdown { position: relative; display: inline-block; overflow: visible !important; }
.act-btn { background: rgba(0, 100, 255, 0.2); border: 1px solid var(--border); color: var(--light); padding: 4px 10px; border-radius: 6px; cursor: pointer; display: flex; align-items: center; gap: 4px; font-size: 11px; transition: 0.2s; position: relative; z-index: 10; }
.act-btn:hover { background: rgba(0, 120, 255, 0.4); }
.act-menu { display: none; position: absolute; right: 0; top: 100%; margin-top: 4px; background: var(--deep); border: 1px solid var(--border); border-radius: 8px; min-width: 120px; box-shadow: 0 5px 15px rgba(0,0,0,0.5); z-index: 1000; overflow: hidden; }
.act-menu.show { display: block; }
.act-menu a, .act-menu button { display: block; width: 100%; text-align: left; padding: 8px 12px; font-size: 11px; background: transparent; border: none; color: var(--text); cursor: pointer; transition: 0.2s; text-decoration: none; }
.act-menu a:hover, .act-menu button:hover { background: rgba(0, 100, 255, 0.2); color: var(--light); }
.act-menu .m-edit { color: #ffcc44; }
.act-menu .m-del { color: #ff4d4d; border-top: 1px solid rgba(255,255,255,0.05); }

/* Column Widths */
.member-table th:nth-child(1) { width: 4%; }
.member-table th:nth-child(2) { width: 22%; }
.member-table th:nth-child(3) { width: 18%; }
.member-table th:nth-child(4) { width: 10%; }
.member-table th:nth-child(5) { width: 12%; }
.member-table th:nth-child(6) { width: 8%; }
.member-table th:nth-child(7) { width: 10%; }
.member-table th:nth-child(8) { width: 8%; }
.member-table th:nth-child(9) { width: 8%; text-align: right; }
.member-table td:nth-child(9) { text-align: right; overflow: visible; }

/* App Table Specific Adjustments */
.app-table th:nth-child(1) { width: 35%; }
.app-table th:nth-child(2) { width: 12%; }
.app-table th:nth-child(3) { width: 15%; }
.app-table th:nth-child(4) { width: 15%; }
.app-table th:nth-child(5) { width: 10%; }
.app-table th:nth-child(6) { width: 13%; text-align: right; }
.app-table td:nth-child(6) { text-align: right; overflow: visible; }

@media (max-width: 768px) {
  .wrap{padding:18px 12px}.logo{width:38px;height:38px;font-size:13px}.hdr-text h1{font-size:16px}
  .stats{grid-template-columns:1fr 1fr;gap:9px;margin-bottom:18px}.sc{padding:12px 14px}.sv{font-size:21px}
  .fg{grid-template-columns:1fr}.card{padding:16px;border-radius:12px}
  .btn{padding:9px 16px;font-size:12px}.bp,.bw{width:100%;justify-content:center}
  .sr{flex-direction:column;gap:8px}.pkg-group{gap:6px}
  /* On mobile, allow horizontal scrolling if it still overflows */
  .tw{overflow-x:auto;}
  table { min-width: 700px; }
}
@media (max-width: 768px) {
  .stats { grid-template-columns: repeat(2, 1fr) !important; }
}
@media (max-width: 768px) {
  .stats { grid-template-columns: repeat(2, 1fr) !important; }
}
@media (max-width: 480px) {
  .wrap{padding:14px 10px}
  .stats{grid-template-columns:1fr !important}
  .hdr-text p{display:none}
  .tw table { min-width: 100% !important; table-layout: auto !important; }
  .tw table, .tw tbody, .tw th, .tw td, .tw tr { display: block; box-sizing: border-box; width: 100%; }
  .tw table thead{display:none}
  .tw table tr{background:rgba(0,30,70,.4);border:1px solid var(--border);border-radius:10px;margin-bottom:10px;padding:10px 12px}
  .tw table td{display:flex;justify-content:space-between;align-items:center;border:none;padding:8px 0;font-size:12px; overflow: visible; white-space: normal !important; text-align:right;}
  .tw table td::before{content:attr(data-label);font-size:10px;font-weight:700;color:var(--muted);text-transform:uppercase;letter-spacing:.6px;flex-shrink:0;margin-right:8px;text-align:left;}
  .pkg-btn{min-width:60px;font-size:11px}
  .act-menu { bottom: 100%; top: auto; margin-bottom: 4px; right: 0; left: auto; z-index: 9999; }
  .filter-container { flex-direction: column; align-items: stretch !important; }
  .filter-container > div { width: 100%; margin-bottom: 5px; text-align: left !important; }
  .filter-container select, .filter-container input { width: 100% !important; }
}
</style>
</head>
<body>
<div class="wrap">
<div class="hdr" style="justify-content: space-between;">
  <div style="display:flex;align-items:center;gap:14px;">
    <div class="logo">TX</div>
    <div class="hdr-text">
      <h1>TEKNO-APPS &mdash; Member Manager</h1>
      <p>Kelola kode akses member extension (JSON Mode) &bull; Login sebagai: <strong style="color:var(--bright);"><?php echo htmlspecialchars($_SESSION['user_name'] ?? ucfirst($role)); ?></strong> <span class="badge pb-<?php echo $role==='owner'?'ultimate':($role==='mitra'?'custom':'basic'); ?>" style="font-size:8px; padding:1px 4px;"><?php echo strtoupper($role); ?></span></p>
    </div>
  </div>
  <div style="display:flex; gap:10px;">
    <?php if (isset($_SESSION['original_owner_id'])): ?>
    <form method="POST" action="?tab=mitras" style="margin:0;">
        <input type="hidden" name="action" value="return_to_owner">
        <button type="submit" class="btn bp" style="padding: 8px 15px; font-size: 11px; background: linear-gradient(135deg, #cc8800, #ffaa00);">&#x2B05; Kembali ke Owner</button>
    </form>
    <?php endif; ?>
    <a href="?logout=1" class="btn bd" style="padding: 8px 15px; font-size: 11px;">&#x1F6AA; Logout</a>
  </div>
</div>
<div class="stats" style="grid-template-columns: repeat(<?php echo $user_perms['view_stats'] ? 6 : 5; ?>, 1fr);">
  <div class="sc t"><div class="sv"><?php echo $total; ?></div><div class="sl">Total Member</div></div>
  <div class="sc a"><div class="sv"><?php echo $active; ?></div><div class="sl">Aktif</div></div>
  <div class="sc e"><div class="sv"><?php echo $expired; ?></div><div class="sl">Expired</div></div>
  <div class="sc" style="border-color: rgba(0,150,255,0.3);"><div class="sv" style="color: #4db8ff;"><?php echo $totalPaid; ?></div><div class="sl" style="color: #4db8ff;">💰 Berbayar</div></div>
  <div class="sc" style="border-color: rgba(255,170,0,0.3);"><div class="sv" style="color: #ffaa00;"><?php echo $totalTrial; ?></div><div class="sl" style="color: #ffaa00;">🎁 Trial</div></div>
  <?php if ($user_perms['view_stats']): ?>
  <div class="sc r" style="background: linear-gradient(135deg, rgba(0,230,118,0.1), rgba(0,200,100,0.1)); border-color: rgba(0,230,118,0.3);">
    <div class="sv" style="color: #00e676; font-size: 20px;">Rp <?php echo number_format($totalRevenue, 0, ',', '.'); ?></div>
    <div class="sl" style="color: #00e676;">Total Pendapatan</div>
  </div>
  <?php endif; ?>
</div>
<?php if ($msg): ?><div class="alert <?php echo $msgType; ?>"><?php echo $msgType==='success'?'&#x2705;':($msgType==='error'?'&#x274C;':'&#x2139;&#xFE0F;'); ?> <?php echo $msg; ?></div><?php endif; ?>

<div class="tabs">
  <?php if ($role === 'owner'): ?>
  <button class="tab-btn <?php echo $tab==='members'?'active':''; ?>" onclick="switchTab('members')">Kelola Member</button>
  <button class="tab-btn <?php echo $tab==='apps'?'active':''; ?>" onclick="switchTab('apps')">Kelola Aplikasi</button>
  <button class="tab-btn <?php echo $tab==='cookies'?'active':''; ?>" onclick="switchTab('cookies')">Inject Cookies</button>
  <button class="tab-btn <?php echo $tab==='packages'?'active':''; ?>" onclick="switchTab('packages')">Konfigurasi Paket</button>
  <button class="tab-btn <?php echo $tab==='settings'?'active':''; ?>" onclick="switchTab('settings')">Pengaturan</button>
  <button class="tab-btn <?php echo $tab==='users'?'active':''; ?>" onclick="switchTab('users')">Manajemen User</button>
  <button class="tab-btn <?php echo $tab==='audit'?'active':''; ?>" onclick="switchTab('audit')">Histori Log</button>
  <button class="tab-btn <?php echo $tab==='mitras'?'active':''; ?>" onclick="switchTab('mitras')">Manajemen Mitra</button>
  <button class="tab-btn <?php echo $tab==='finance'?'active':''; ?>" onclick="switchTab('finance')">💰 Manajemen Keuangan</button>
  <button class="tab-btn <?php echo $tab==='notepad'?'active':''; ?>" onclick="switchTab('notepad')">📋 Notepad & Akun</button>
  <?php elseif ($role === 'mitra'): ?>
  <button class="tab-btn <?php echo $tab==='members'?'active':''; ?>" onclick="switchTab('members')">Member Saya</button>
  <button class="tab-btn <?php echo $tab==='mitradashboard'?'active':''; ?>" onclick="switchTab('mitradashboard')">Dashboard Pendapatan</button>
  <?php else: ?>
  <?php if (!empty($user_perms['tab_members'])): ?><button class="tab-btn <?php echo $tab==='members'?'active':''; ?>" onclick="switchTab('members')">Kelola Member</button><?php endif; ?>
  <?php if (!empty($user_perms['tab_apps'])): ?><button class="tab-btn <?php echo $tab==='apps'?'active':''; ?>" onclick="switchTab('apps')">Kelola Aplikasi</button><?php endif; ?>
  <?php if (!empty($user_perms['tab_cookies'])): ?><button class="tab-btn <?php echo $tab==='cookies'?'active':''; ?>" onclick="switchTab('cookies')">Inject Cookies</button><?php endif; ?>
  <?php if (!empty($user_perms['tab_packages'])): ?><button class="tab-btn <?php echo $tab==='packages'?'active':''; ?>" onclick="switchTab('packages')">Konfigurasi Paket</button><?php endif; ?>
  <?php if (!empty($user_perms['tab_settings'])): ?><button class="tab-btn <?php echo $tab==='settings'?'active':''; ?>" onclick="switchTab('settings')">Pengaturan</button><?php endif; ?>
  <?php if (!empty($user_perms['tab_users'])): ?><button class="tab-btn <?php echo $tab==='users'?'active':''; ?>" onclick="switchTab('users')">Manajemen User</button><?php endif; ?>
  <?php if (!empty($user_perms['tab_audit'])): ?><button class="tab-btn <?php echo $tab==='audit'?'active':''; ?>" onclick="switchTab('audit')">Histori Log</button><?php endif; ?>
  <?php if (!empty($user_perms['tab_mitras'])): ?><button class="tab-btn <?php echo $tab==='mitras'?'active':''; ?>" onclick="switchTab('mitras')">Manajemen Mitra</button><?php endif; ?>
  <?php if (!empty($user_perms['tab_notepad'])): ?><button class="tab-btn <?php echo $tab==='notepad'?'active':''; ?>" onclick="switchTab('notepad')">📋 Notepad & Akun</button><?php endif; ?>
  <?php endif; ?>
</div><!-- MEMBERS TAB -->
<div id="tab-members" class="tab-content <?php echo $tab==='members'?'active':''; ?>">
<?php
function renderPkgSelector($selPkg, $prefix, $customCfg, $APP_LABELS, $APP_MAX) {
  global $pkg_prices;
?>
<div class="fi full">
  <label>Paket</label>
  <input type="hidden" name="package" id="<?php echo $prefix;?>_pkg_val" value="<?php echo htmlspecialchars($selPkg); ?>"/>
  <div class="pkg-group" id="<?php echo $prefix;?>_pkg_group">
    <button type="button" class="pkg-btn<?php echo $selPkg==='basic'?' selected':''; ?>" data-pkg="basic" onclick="setPkg('<?php echo $prefix;?>','basic', <?php echo $pkg_prices['basic']??0; ?>)"><span class="pkg-name">Basic</span><span class="pkg-desc" style="color:#00e676;font-weight:bold;font-size:10px;">Rp <?php echo number_format($pkg_prices['basic']??0, 0, ',', '.'); ?></span><span class="pkg-desc">Flow &middot; Whisk &middot; Sora</span></button>
    <button type="button" class="pkg-btn<?php echo $selPkg==='pro'?' selected':''; ?>" data-pkg="pro" onclick="setPkg('<?php echo $prefix;?>','pro', <?php echo $pkg_prices['pro']??0; ?>)"><span class="pkg-name">Pro</span><span class="pkg-desc" style="color:#00e676;font-weight:bold;font-size:10px;">Rp <?php echo number_format($pkg_prices['pro']??0, 0, ',', '.'); ?></span><span class="pkg-desc">+Grok</span></button>
    <button type="button" class="pkg-btn<?php echo $selPkg==='ultimate'?' selected':''; ?>" data-pkg="ultimate" onclick="setPkg('<?php echo $prefix;?>','ultimate', <?php echo $pkg_prices['ultimate']??0; ?>)"><span class="pkg-name">Ultimate</span><span class="pkg-desc" style="color:#00e676;font-weight:bold;font-size:10px;">Rp <?php echo number_format($pkg_prices['ultimate']??0, 0, ',', '.'); ?></span><span class="pkg-desc">Full Access</span></button>
    <button type="button" class="pkg-btn<?php echo $selPkg==='custom'?' selected':''; ?>" data-pkg="custom" onclick="setPkg('<?php echo $prefix;?>','custom', <?php echo $pkg_prices['custom']??0; ?>)"><span class="pkg-name">Custom</span><span class="pkg-desc" style="color:#00e676;font-weight:bold;font-size:10px;">Rp <?php echo number_format($pkg_prices['custom']??0, 0, ',', '.'); ?></span><span class="pkg-desc">Pilih Sendiri</span></button>
  </div>
  <div class="custom-cfg visible" id="<?php echo $prefix;?>_custom" style="margin-top:15px;border-top:1px solid rgba(255,255,255,0.05);padding-top:10px;">
    <div style="font-size:11px;color:var(--light);margin-bottom:10px;font-weight:600">Konfigurasi Akses Aplikasi: <span style="font-weight:normal;color:var(--muted)">(Centang otomatis mengikuti Paket)</span></div>
    <?php foreach ($APP_LABELS as $aid => $alabel):
      $checked = isset($customCfg[$aid]) ? 'checked' : '';
      $srvVal = $customCfg[$aid] ?? 1;
      $maxSrv = $APP_MAX[$aid];
    ?>
    <div class="app-row" id="<?php echo $prefix;?>_row_<?php echo $aid;?>" style="<?php echo $checked ? 'background: rgba(0, 230, 118, 0.1); border-left: 3px solid #00e676;' : 'opacity: 0.5; filter: grayscale(100%);'; ?> padding: 8px 12px; border-radius: 6px; margin-bottom: 6px; transition: all 0.3s ease;">
      <div class="app-chk">
        <input type="checkbox" name="app_<?php echo $aid;?>" id="<?php echo $prefix;?>_<?php echo $aid;?>" <?php echo $checked;?> onchange="toggleSrv('<?php echo $prefix;?>_<?php echo $aid;?>_srv',this.checked); toggleRowColor('<?php echo $prefix;?>_row_<?php echo $aid;?>',this.checked)" <?php echo $selPkg!=='custom'?'disabled':''; ?> style="transform: scale(1.2); margin-right: 10px;"/>
        <label for="<?php echo $prefix;?>_<?php echo $aid;?>" style="font-weight: 600; color: <?php echo $checked ? '#00e676' : 'var(--text)'; ?>;"><?php echo $alabel; ?></label>
      </div>
      <?php if ($maxSrv > 1): ?>
      <div class="srv-ctrl">
        <label style="color: <?php echo $checked ? '#00e676' : 'var(--muted)'; ?>; font-weight: 600;">Server:</label>
        <input type="number" name="srv_<?php echo $aid;?>" id="<?php echo $prefix;?>_<?php echo $aid;?>_srv" value="<?php echo $srvVal;?>" min="1" max="<?php echo $maxSrv;?>" <?php echo $checked && $selPkg==='custom'?'':'disabled';?> style="background: <?php echo $checked ? 'rgba(0, 230, 118, 0.15)' : 'var(--deep)'; ?>; border-color: <?php echo $checked ? 'rgba(0, 230, 118, 0.3)' : 'var(--border)'; ?>; color: <?php echo $checked ? '#00e676' : 'var(--text)'; ?>; font-weight: bold; width: 60px;"/>
      </div>
      <?php endif; ?>
    </div>
    <?php endforeach; ?>
  </div>
</div>
<?php } ?>

<?php if ($editData):
  $editPkg = $editData['package'] ?? 'basic';
  $editCustom = !empty($editData['custom_config']) && is_array($editData['custom_config']) ? $editData['custom_config'] : [];
?>
<div class="card edit-card">
  <div class="ct edit-ct">Edit Member: <?php echo htmlspecialchars($editData['name']); ?></div>
  <form method="POST">
    <input type="hidden" name="action" value="update"/>
    <input type="hidden" name="id" value="<?php echo $editData['id']; ?>"/>
    <div class="fg">
      <div class="fi"><label>Nama Member</label><input type="text" name="name" value="<?php echo htmlspecialchars($editData['name']); ?>" required/></div>
      <div class="fi"><label>Kode Akses</label><input type="text" name="code" value="<?php echo htmlspecialchars($editData['code']); ?>" required/></div>

      <div class="fi full">
        <label>Ubah Tanggal Expire / Tambah Hari</label>
        <div style="display:flex; gap:10px; align-items:center;">
          <input type="date" name="expiry_date" id="edit_expiry_date" value="<?php echo $editData['expiry_date']; ?>" style="flex:1;" required/>
          <span style="color:var(--muted);font-size:12px;">atau</span>
          <div style="display:flex; align-items:center; background:rgba(0,20,50,.6); border:1px solid var(--border); border-radius:8px; padding:0 12px; width: 150px;">
            <span style="font-size:16px; color:#00e676; font-weight:bold; margin-right:5px;">+</span>
            <input type="number" id="edit_add_days" placeholder="Hari" min="1" oninput="addDaysToExpiry(this.value)" style="flex:1; background:transparent; border:none; color:var(--text); font-size:14px; outline:none; text-align:center; padding: 10px 0;"/>
          </div>
        </div>
        <p style="font-size:10px; color:var(--muted); margin-top:4px;">Pilih tanggal manual ATAU ketik jumlah hari untuk menambahkan masa aktif dari tanggal expire saat ini.</p>
      </div>
      <div class="fi full" style="margin-bottom: 8px;">
        <label>Harga / Pendapatan Transaksi (Rp)</label>
        <div style="background: rgba(0,230,118,0.1) !important; border: 1px solid rgba(0,230,118,0.3) !important; padding: 12px; border-radius: 8px;">
          <input type="number" name="manual_price" value="<?php echo htmlspecialchars($editData['price_paid'] ?? 0); ?>" style="width: 100%; background: transparent !important; border: none !important; color: #00e676 !important; outline: none; font-size: 14px;"/>
        </div>
      </div>
      <?php renderPkgSelector($editPkg, 'ed', $editCustom, $APP_LABELS_ALL, $APP_MAX_ALL); ?>
      <div class="fi full" style="display:flex; gap:8px; justify-content:space-between; margin-top:15px; border-top: 1px dashed rgba(255,255,255,0.1); padding-top: 15px;">
        <button type="button" class="btn" style="background: rgba(255,0,0,0.1); color: #ff4d4d; border: 1px solid rgba(255,0,0,0.3);" onclick="confirmRefund(<?php echo $editData['id']; ?>, '<?php echo $editData['expiry_date']; ?>', <?php echo $editData['price_paid'] ?? 0; ?>)">
          &#128176; Refund & Nonaktifkan
        </button>
        <div style="display:flex;gap:8px;">
          <a href="?" class="btn bt">Batal</a>
          <button type="submit" class="btn bw">&#x270E; Simpan Perubahan</button>
        </div>
      </div>
    </div>
  </form>
</div>
<script>
const ORIGINAL_EXPIRY = '<?php echo $editData['expiry_date']; ?>';
function addDaysToExpiry(days) {
    const d = parseInt(days) || 0;
    const expDateInput = document.getElementById('edit_expiry_date');
    if (!expDateInput) return;
    
    if (d > 0) {
        const dateObj = new Date(ORIGINAL_EXPIRY);
        dateObj.setDate(dateObj.getDate() + d);
        const yyyy = dateObj.getFullYear();
        const mm = String(dateObj.getMonth() + 1).padStart(2, '0');
        const dd = String(dateObj.getDate()).padStart(2, '0');
        expDateInput.value = `${yyyy}-${mm}-${dd}`;
    } else {
        expDateInput.value = ORIGINAL_EXPIRY;
    }
}

function confirmRefund(memberId, expiryDate, pricePaid) {
    if (pricePaid <= 0) {
        alert("Member ini tidak memiliki data harga yang dibayar, tidak dapat melakukan refund.");
        return;
    }
    
    const today = new Date();
    const expDate = new Date(expiryDate);
    const diffTime = expDate - today;
    const diffDays = Math.ceil(diffTime / (1000 * 60 * 60 * 24));
    
    if (diffDays <= 0) {
        alert("Member sudah expired, tidak ada sisa durasi untuk direfund.");
        return;
    }
    
    const totalDays = 30; // Asumsi paket 30 hari untuk perhitungan proporsional (bisa diubah jika perlu)
    // Atau kita asumsikan refund berbasis proporsi sisa hari terhadap harga
    // Tapi karena kita tidak simpan durasi awal (add_days), kita pakai pendekatan (Harga / 30) * Sisa Hari, maks = Harga Awal.
    
    let baseRefund = Math.round((pricePaid / 30) * diffDays);
    if (baseRefund > pricePaid) baseRefund = pricePaid;
    
    const adminFeePercent = <?php echo $settings['refund_admin_fee_percent'] ?? 25; ?>;
    const adminFee = Math.round(baseRefund * (adminFeePercent / 100));
    const netRefund = baseRefund - adminFee;
    
    const msg = `DETAIL REFUND MEMBER\n` +
                `Sisa Durasi Aktif: ${diffDays} hari\n` +
                `Harga Dibayar: Rp ${pricePaid.toLocaleString('id-ID')}\n\n` +
                `Perhitungan Refund (Proporsional): Rp ${baseRefund.toLocaleString('id-ID')}\n` +
                `Potongan Admin (${adminFeePercent}%): - Rp ${adminFee.toLocaleString('id-ID')}\n` +
                `---------------------------\n` +
                `Total Dana Dikembalikan: Rp ${netRefund.toLocaleString('id-ID')}\n\n` +
                `Lanjutkan proses refund dan nonaktifkan member ini?`;
                
    if (confirm(msg)) {
        const reason = prompt("Masukkan catatan/alasan refund (Opsional):", "Refund dari Owner");
        if (reason === null) return; // User clicked Cancel on prompt
        
        const form = document.createElement('form');
        form.method = 'POST';
        form.style.display = 'none';
        
        const actionInput = document.createElement('input');
        actionInput.name = 'action';
        actionInput.value = 'refund_member';
        form.appendChild(actionInput);
        
        const idInput = document.createElement('input');
        idInput.name = 'id';
        idInput.value = memberId;
        form.appendChild(idInput);
        
        const refundAmountInput = document.createElement('input');
        refundAmountInput.name = 'refund_amount';
        refundAmountInput.value = netRefund;
        form.appendChild(refundAmountInput);

        const reasonInput = document.createElement('input');
        reasonInput.name = 'refund_reason';
        reasonInput.value = reason;
        form.appendChild(reasonInput);
        
        document.body.appendChild(form);
        form.submit();
    }
}
</script>
<?php endif; ?>

<?php if ($user_perms['add_member']): ?>
<div class="card">
  <div class="ct">Tambah Member Baru</div>
  <form method="POST">
    <input type="hidden" name="action" value="add"/>
    <input type="hidden" name="expiry_days" id="expiry_days" value="7"/>
    <div class="fg">
      <div class="fi"><label>Nama Member</label><input type="text" name="name" placeholder="contoh: John Doe" required/></div>
      <div class="fi"><label>Kode Akses</label><input type="text" name="custom_code" placeholder="Kosongkan untuk auto-generate"/></div>

      <div class="fi full">
        <label>Durasi Aktif</label>
        <input type="hidden" name="days" id="add_days" value="7"/>
        <div class="dur-group" style="display:flex; gap:10px; align-items:stretch;">
          <div style="flex:1; display:flex; gap:10px;">
            <button type="button" class="dur-btn" data-days="3" onclick="setDays(3)" style="flex:1;">3 Hari<span class="dur-badge">Short</span></button>
            <button type="button" class="dur-btn selected" data-days="7" onclick="setDays(7)" style="flex:1;">7 Hari<span class="dur-badge">Standard</span></button>
            <button type="button" class="dur-btn" data-days="30" onclick="setDays(30)" style="flex:1;">30 Hari<span class="dur-badge">Premium</span></button>
          </div>
          <div style="width: 120px; display:flex; flex-direction:column;">
            <input type="number" id="custom_days_input" placeholder="Custom" min="1" oninput="setCustomDays(this.value)" style="flex:1; background:rgba(0,20,50,.6); border:1px solid var(--border); border-radius:8px; padding:0 12px; color:var(--text); font-size:14px; outline:none; text-align:center;"/>
            <span style="font-size:10px; color:var(--muted); text-align:center; margin-top:4px;">Hari</span>
          </div>
        </div>
      </div>
      <div class="fi full" style="margin-bottom: 8px;">
        <label>Harga / Pendapatan Transaksi (Rp)</label>
        <div style="background: rgba(0,230,118,0.1) !important; border: 1px solid rgba(0,230,118,0.3) !important; padding: 12px; border-radius: 8px;">
          <input type="number" name="manual_price" id="add_manual_price" placeholder="Otomatis mengikuti paket jika dikosongkan" style="width: 100%; background: transparent !important; border: none !important; color: #00e676 !important; outline: none; font-size: 14px;"/>
        </div>
        <p style="font-size:10px; color:var(--muted); margin-top:4px;">Isi jika ingin mengatur harga spesifik untuk member ini. Biarkan kosong untuk menggunakan harga default paket.</p>
      </div>
      <?php renderPkgSelector('basic', 'add', [], $APP_LABELS_ALL, $APP_MAX_ALL); ?>
      <div class="fi full" style="display:flex;justify-content:flex-end;margin-top:4px">
        <button type="submit" class="btn bp">&#x2726; Tambah Member</button>
      </div>
    </div>
  </form>
</div>
<?php endif; ?>

<div class="card">
  <div class="ct">Daftar Member</div>
  <div class="sr filter-container" style="background: rgba(255,255,255,0.02); padding: 15px; border-radius: 8px; margin-bottom: 15px;">
    <form method="GET" style="display:flex; gap:10px; flex-wrap: wrap; align-items: flex-end;">
      <input type="hidden" name="filter_applied" value="1">
      <div style="flex: 1; min-width: 200px;">
        <label style="display:block; font-size:11px; margin-bottom:4px; color:var(--muted)">Cari Nama / Kode</label>
        <input type="search" name="search" value="<?php echo htmlspecialchars($_GET['search'] ?? ''); ?>" placeholder="Masukkan kata kunci..." style="width:100%; margin:0;" />
      </div>
      <div style="width: 150px;">
        <label style="display:block; font-size:11px; margin-bottom:4px; color:var(--muted)">Paket</label>
        <select name="f_paket" style="width:100%; margin:0; padding: 10px; background: var(--bg); border: 1px solid rgba(255,255,255,0.1); color: var(--fg); border-radius: 6px;">
          <option value="">Semua Paket</option>
          <option value="basic" <?php echo (isset($_GET['f_paket']) && $_GET['f_paket'] === 'basic') ? 'selected' : ''; ?>>Basic (Rp <?php echo number_format($pkg_prices['basic']??0, 0, ',', '.'); ?>)</option>
          <option value="pro" <?php echo (isset($_GET['f_paket']) && $_GET['f_paket'] === 'pro') ? 'selected' : ''; ?>>Pro (Rp <?php echo number_format($pkg_prices['pro']??0, 0, ',', '.'); ?>)</option>
          <option value="ultimate" <?php echo (isset($_GET['f_paket']) && $_GET['f_paket'] === 'ultimate') ? 'selected' : ''; ?>>Ultimate (Rp <?php echo number_format($pkg_prices['ultimate']??0, 0, ',', '.'); ?>)</option>
          <option value="custom" <?php echo (isset($_GET['f_paket']) && $_GET['f_paket'] === 'custom') ? 'selected' : ''; ?>>Custom</option>
        </select>
      </div>
      <div style="width: 150px;">
        <label style="display:block; font-size:11px; margin-bottom:4px; color:var(--muted)">Status</label>
        <select name="f_status" style="width:100%; margin:0; padding: 10px; background: var(--bg); border: 1px solid rgba(255,255,255,0.1); color: var(--fg); border-radius: 6px;">
          <option value="">Semua Status</option>
          <option value="aktif" <?php echo (isset($_GET['f_status']) && $_GET['f_status'] === 'aktif') ? 'selected' : ''; ?>>Aktif</option>
          <option value="nonaktif" <?php echo (isset($_GET['f_status']) && $_GET['f_status'] === 'nonaktif') ? 'selected' : ''; ?>>Nonaktif</option>
          <option value="expired" <?php echo (isset($_GET['f_status']) && $_GET['f_status'] === 'expired') ? 'selected' : ''; ?>>Expired</option>
        </select>
      </div>

      <div style="width: 150px;">
        <label style="display:block; font-size:11px; margin-bottom:4px; color:var(--muted)">Expire (Sisa)</label>
        <select name="f_expire" style="width:100%; margin:0; padding: 10px; background: var(--bg); border: 1px solid rgba(255,255,255,0.1); color: var(--fg); border-radius: 6px;">
          <option value="">Semua Waktu</option>
          <option value="14" <?php echo (isset($_GET['f_expire']) && $_GET['f_expire'] === '14') ? 'selected' : ''; ?>>&lt; 14 Hari</option>
          <option value="7" <?php echo (isset($_GET['f_expire']) && $_GET['f_expire'] === '7') ? 'selected' : ''; ?>>&lt; 7 Hari</option>
          <option value="3" <?php echo (isset($_GET['f_expire']) && $_GET['f_expire'] === '3') ? 'selected' : ''; ?>>&lt; 3 Hari</option>
        </select>
      </div>
      <div style="width: 150px;">
        <label style="display:block; font-size:11px; margin-bottom:4px; color:var(--muted)">Tanggal Expire</label>
        <input type="date" name="f_date" value="<?php echo htmlspecialchars($_GET['f_date'] ?? ''); ?>" style="width:100%; margin:0; padding: 9px; background: var(--bg); border: 1px solid rgba(255,255,255,0.1); color: var(--fg); border-radius: 6px; font-size: 13px; outline: none;"/>
      </div>
      <div style="width: 150px;">
        <label style="display:block; font-size:11px; margin-bottom:4px; color:var(--muted)">Start Transaksi</label>
        <input type="date" name="f_start_date" value="<?php echo htmlspecialchars($_GET['f_start_date']??''); ?>" style="width:100%; margin:0; padding: 9px; background: var(--bg); border: 1px solid rgba(255,255,255,0.1); color: var(--fg); border-radius: 6px; font-size: 13px; outline: none;">
      </div>
      <div style="width: 150px;">
        <label style="display:block; font-size:11px; margin-bottom:4px; color:var(--muted)">End Transaksi</label>
        <input type="date" name="f_end_date" value="<?php echo htmlspecialchars($_GET['f_end_date']??''); ?>" style="width:100%; margin:0; padding: 9px; background: var(--bg); border: 1px solid rgba(255,255,255,0.1); color: var(--fg); border-radius: 6px; font-size: 13px; outline: none;">
      </div>
      <div style="width: 150px;">
        <label style="display:block; font-size:11px; margin-bottom:4px; color:var(--muted)">Urutkan (Sortir)</label>
        <select name="f_sort" style="width:100%; margin:0; padding: 10px; background: var(--bg); border: 1px solid rgba(255,255,255,0.1); color: var(--fg); border-radius: 6px;">
          <option value="newest" <?php echo (!isset($_GET['f_sort']) || $_GET['f_sort'] === 'newest') ? 'selected' : ''; ?>>Terbaru</option>
          <option value="oldest" <?php echo (isset($_GET['f_sort']) && $_GET['f_sort'] === 'oldest') ? 'selected' : ''; ?>>Terlama</option>
          <option value="expire_asc" <?php echo (isset($_GET['f_sort']) && $_GET['f_sort'] === 'expire_asc') ? 'selected' : ''; ?>>Expire Terdekat</option>
          <option value="expire_desc" <?php echo (isset($_GET['f_sort']) && $_GET['f_sort'] === 'expire_desc') ? 'selected' : ''; ?>>Expire Terjauh</option>
          <option value="price_desc" <?php echo (isset($_GET['f_sort']) && $_GET['f_sort'] === 'price_desc') ? 'selected' : ''; ?>>Harga Tertinggi</option>
          <option value="price_asc" <?php echo (isset($_GET['f_sort']) && $_GET['f_sort'] === 'price_asc') ? 'selected' : ''; ?>>Harga Terendah</option>
        </select>
      </div>
      
      <?php if ($role === 'owner' || $role === 'admin'): ?>
      <div style="width: 150px;">
        <label style="display:block; font-size:11px; margin-bottom:4px; color:var(--muted)">Mitra / Afiliasi</label>
        <select name="f_mitra" style="width:100%; margin:0; padding: 10px; background: var(--bg); border: 1px solid rgba(255,255,255,0.1); color: var(--fg); border-radius: 6px;">
          <option value="">Semua Data</option>
          <option value="none" <?php echo (isset($_GET['f_mitra']) && $_GET['f_mitra'] === 'none') ? 'selected' : ''; ?>>Admin System (Tanpa Mitra)</option>
          <?php 
          $all_mitras = array_filter($users ?? json_decode(file_get_contents('data/users.json'), true) ?: [], fn($u) => $u['role'] === 'mitra');
          foreach ($all_mitras as $m): 
          ?>
              <option value="<?php echo $m['id']; ?>" <?php echo (isset($_GET['f_mitra']) && $_GET['f_mitra'] === (string)$m['id']) ? 'selected' : ''; ?>><?php echo htmlspecialchars($m['name']); ?></option>
          <?php endforeach; ?>
        </select>
      </div>
      <?php endif; ?>

      <div style="display:flex; gap: 8px; align-items: center; width: 100%; margin-top: 5px;">
        <button type="submit" class="btn bp" style="margin:0; padding: 8px 16px;">Terapkan Filter</button>
        <?php if (isset($_GET['filter_applied'])): ?>
          <a href="?" class="btn bt" style="margin:0; padding: 8px 16px; line-height: 20px;">Reset Filter</a>
        <?php endif; ?>
        
        <div style="flex-grow: 1;"></div>
        
        <button type="button" class="btn bsm" style="background:#107c41; border:none; color:white; margin:0; padding:8px 16px; border-radius:6px;" onclick="exportData('export_csv')">📊 Export CSV (Excel)</button>
        <button type="button" class="btn bsm" style="background:#4a7a9b; border:none; color:white; margin:0; padding:8px 16px; border-radius:6px;" onclick="exportData('export_txt')">📄 Export TXT</button>
        
        <script>
        function exportData(format) {
            const url = new URL(window.location.href);
            url.searchParams.set('export_format', format);
            window.location.href = url.toString();
        }
        </script>
      </div>
    </form>
  </div>

  <div class="tw"><table class="member-table">
    <thead><tr>

      <th style="width:40px;">#</th><th>Nama</th><th>Kode</th><th>Paket</th><th>Expire</th><th>Sisa</th><th>Login</th><th>Status</th><th style="width:90px; text-align:center;">Aksi</th>
    </tr></thead>
    <tbody>
    <?php $i=1;
    if (empty($members)): ?>
      <tr><td colspan="<?php echo ($role === 'owner' || $role === 'admin') ? '10' : '9'; ?>" class="empty">Belum ada member. Tambahkan di atas.</td></tr>
    <?php else: foreach ($members as $r):
      $today2 = new DateTime(); $exp = new DateTime($r['expiry_date']);
      $isExp = $today2 > $exp;
      $sisa = $isExp ? 0 : (int)$today2->diff($exp)->days;
      $cls = $isExp ? 'be' : ($r['is_active'] ? 'ba' : 'bn');
      $lbl = $isExp ? 'EXPIRED' : ($r['is_active'] ? 'AKTIF' : 'NONAKTIF');
      $sc = $isExp ? 'err' : ($sisa <= 3 ? 'warn' : 'ok');
      $pkg = $r['package'] ?? 'basic';
      $pkgLbl = $PKG_LABELS[$pkg] ?? 'Basic';
    ?>
      <tr>

        <td data-label="#" style="color:var(--muted);"><?php echo $i++; ?></td>
        <td data-label="Nama">
          <strong><?php echo htmlspecialchars($r['name']); ?></strong>
          <?php if(!empty($r['price_paid']) && $user_perms['view_stats']): ?>
          <div style="font-size:9px; color:#00e676; margin-top:3px;">+Rp <?php echo number_format($r['price_paid'],0,',','.'); ?></div>
          <?php endif; ?>
          <?php if(!empty($r['updated_by'])): ?>
          <div style="font-size:8.5px; color:var(--muted); margin-top:3px; font-style:italic;">Edit: <?php echo htmlspecialchars($r['updated_by']); ?></div>
          <?php elseif(!empty($r['created_by'])): ?>
          <div style="font-size:8.5px; color:var(--muted); margin-top:3px; font-style:italic;">Input: <?php echo htmlspecialchars($r['created_by']); ?></div>
          <?php endif; ?>
        </td>
        <td data-label="Kode"><code class="kd"><?php echo htmlspecialchars($r['code']); ?></code></td>
        <td data-label="Paket"><span class="badge pb-<?php echo $pkg; ?>"><?php echo $pkgLbl; ?></span></td>
        <td data-label="Expire" style="color:<?php echo $isExp?'var(--err)':'var(--sub)'; ?>"><?php echo $r['expiry_date']; ?></td>
        <td data-label="Sisa"><span class="sisa <?php echo $sc; ?>"><?php echo $isExp ? 'Expired' : "{$sisa} hari"; ?></span></td>
        <td data-label="Login" style="color:var(--muted);font-size:11px"><?php echo $r['last_used'] ? date('d/m/Y H:i',strtotime($r['last_used'])) : '-'; ?></td>
        <td data-label="Status"><span class="badge <?php echo $cls; ?>"><?php echo $lbl; ?></span></td>
        <td data-label="Aksi" style="text-align:center;">
          <div class="act-dropdown">
            <button type="button" class="act-btn" onclick="toggleMenu(this)">&#x270E; Aksi &#x25BC;</button>
            <div class="act-menu">
              <?php if ($user_perms['edit_member']): ?>
              <a href="?edit=<?php echo $r['id']; ?>" class="m-edit">&#x270E; Edit</a>
              <button type="button" onclick="submitFormAction('toggle', '<?php echo $r['id']; ?>')"><?php echo $r['is_active']?'&#x1F512; Nonaktifkan':'&#x1F513; Aktifkan'; ?></button>
              <button type="button" onclick="if(confirm('Hapus member ini?')) submitFormAction('delete', '<?php echo $r['id']; ?>')" class="m-del">&#x1F5D1; Hapus</button>
              <?php else: ?>
              <button type="button" onclick="alert('Akses ditolak. Anda tidak memiliki izin untuk mengedit member.')" class="m-edit" style="color:var(--muted)">&#x270E; Edit (Terkunci)</button>
              <?php endif; ?>
            </div>
          </div>
        </td>
      </tr>
    <?php endforeach; endif; ?>
    </tbody>
  </table></div>

</div>
</div>

<?php if ($role === 'owner' || !empty($user_perms['tab_apps'])): ?>
<!-- ADD APP TAB -->
<div id="tab-apps" class="tab-content <?php echo $tab==='apps'?'active':''; ?>">
  <?php if ($editApp): ?>
  <div class="card edit-card">
    <div class="ct edit-ct">Edit Aplikasi: <?php echo htmlspecialchars($editApp['name']); ?></div>
    <form method="POST" enctype="multipart/form-data">
      <input type="hidden" name="action" value="update_app"/>
      <input type="hidden" name="id" value="<?php echo htmlspecialchars($editApp['id']); ?>"/>
      <div class="fg">
        <div class="fi"><label>Nama Aplikasi</label><input type="text" name="name" value="<?php echo htmlspecialchars($editApp['name']); ?>" required/></div>
        <div class="fi"><label>Maksimal Server (Default)</label><input type="number" name="max_servers" value="<?php echo $editApp['max_servers']; ?>" min="1" required/></div>
        <div class="fi"><label>Upload Icon Baru (Opsional)</label><input type="file" name="icon_file" accept="image/*"/></div>
        <div class="fi"><label>URL Default (Tujuan)</label><input type="url" name="default_url" value="<?php echo htmlspecialchars($editApp['default_url'] ?? ''); ?>"/></div>
        <div class="fi"><label style="color: #ff4db8;">🔒 Sembunyikan URL Asli (Gunakan Redirect Aman)</label>
            <div style="display:flex; align-items:center; height:100%;">
                <input type="checkbox" name="hide_url" value="1" <?php echo !empty($editApp['hide_url']) ? 'checked' : ''; ?> style="width:20px;height:20px;cursor:pointer;accent-color:#ff4db8;">
                <span style="font-size:11px;color:var(--muted);margin-left:10px;">URL tujuan tidak akan terlihat di ekstensi browser pengguna.</span>
            </div>
        </div>

        <!-- Custom Servers Block -->
        <div class="fi full" style="background: rgba(0, 50, 100, 0.2); padding: 15px; border-radius: 10px; border: 1px dashed rgba(0, 150, 255, 0.3);">
            <div style="display:flex; justify-content:space-between; align-items:center; margin-bottom: 10px;">
                <label style="margin:0;">Custom Server Links (Opsional)</label>
                <button type="button" class="btn bsm bp" onclick="addServerRow('edit_server_list')">+ Tambah Server Link</button>
            </div>
            <p style="font-size:10px; color:var(--muted); margin-bottom:10px;">Jika Anda menambahkan custom link di sini, angka "Maksimal Server" di atas akan diabaikan dan ekstensi akan menggunakan daftar server spesifik ini.</p>
            <div id="edit_server_list">
                <?php 
                if (!empty($editApp['custom_servers'])) {
                    foreach ($editApp['custom_servers'] as $srv) {
                        echo '<div class="srv-row" style="display:flex; gap:10px; margin-bottom:8px;">
                            <input type="text" name="server_names[]" placeholder="Nama Server (Misal: Flow 1)" value="'.htmlspecialchars($srv['name']).'" style="flex:1;" required/>
                            <input type="url" name="server_urls[]" placeholder="URL Target (Opsional)" value="'.htmlspecialchars($srv['url']).'" style="flex:2;"/>
                            <button type="button" class="btn bsm bd" onclick="this.parentElement.remove()">X</button>
                        </div>';
                    }
                }
                ?>
            </div>
        </div>

        <div class="fi full">
          <label>Hidden Elements (CSS Selectors atau Teks)</label>
          <div style="display:flex; gap: 10px; align-items: stretch; margin-bottom: 8px;">
            <textarea id="html_analyzer_input" placeholder="âš¡ MAGIC EXTRACTOR: Paste kode HTML elemen (dari Inspect Element) di sini untuk menghasilkan aturan otomatis..." style="min-height: 60px; font-size: 11px; flex: 1; border-color: rgba(200, 50, 255, 0.4); background: rgba(50, 0, 80, 0.1);"></textarea>
            <button type="button" onclick="analyzeHtml()" class="btn" style="background: linear-gradient(135deg, #aa00ff, #ff00ff); color: white; border: none; padding: 0 15px;">&#10024; Generate</button>
          </div>
          <textarea id="hidden_elements_input" name="hidden_elements" rows="3" placeholder="Contoh CSS: .user-profile, #avatar&#10;Contoh Text: TEXT:1600 AI credits&#10;Contoh Exact Menu: EXACT:Veo 3.1 - Quality" style="min-height: 80px;"><?php echo htmlspecialchars($editApp['hidden_elements'] ?? ''); ?></textarea>
          <p style="font-size:10px;color:var(--muted);margin-top:4px;">Gunakan koma untuk memisahkan aturan. Gunakan <b>TEXT:</b> untuk teks umum, atau <b>EXACT:</b> khusus untuk menghapus tombol dropdown presisi tinggi (seperti "EXACT:Veo 3.1 - Quality").</p>
          <div class="app-chk" style="margin-top:10px;">
            <input type="checkbox" name="flow_lock_enabled" id="ea_flow_lock_enabled" value="1" <?php echo (!isset($editApp['flow_lock_enabled']) || $editApp['flow_lock_enabled']) ? 'checked' : ''; ?>/>
            <label for="ea_flow_lock_enabled" style="font-weight:bold;color:var(--light);">Aktifkan Lock/Hide Flow (Model & UI Restriction)</label>
          </div>
          <p style="font-size:10px;color:var(--muted);margin-top:4px;margin-left:24px;">Khusus halaman Google Flow. Jika dimatikan, elemen model tidak akan dikunci/disembunyikan oleh Flow Lock Script.</p>
          <?php $eaUnlock = $editApp['flow_unlock_models'] ?? ['lite'=>1,'fast'=>0,'quality'=>0,'lower_priority'=>1,'omni_flash'=>0]; ?>
          <div style="margin-top:8px; margin-left:24px; padding:10px; border:1px dashed rgba(124,58,237,.5); border-radius:8px; background:rgba(124,58,237,.08);">
            <label style="display:block; margin-bottom:8px; font-size:11px; color:#d8b4fe;">Unlock Parsial Model Veo</label>
            <div class="app-chk"><input type="checkbox" name="flow_unlock_lite" id="ea_unlock_lite" value="1" <?php if (!empty($eaUnlock['lite'])) echo 'checked'; ?>/><label for="ea_unlock_lite">Izinkan Lite</label></div>
            <div class="app-chk"><input type="checkbox" name="flow_unlock_fast" id="ea_unlock_fast" value="1" <?php if (!empty($eaUnlock['fast'])) echo 'checked'; ?>/><label for="ea_unlock_fast">Izinkan Fast</label></div>
            <div class="app-chk"><input type="checkbox" name="flow_unlock_quality" id="ea_unlock_quality" value="1" <?php if (!empty($eaUnlock['quality'])) echo 'checked'; ?>/><label for="ea_unlock_quality">Izinkan Quality</label></div>
            <div class="app-chk"><input type="checkbox" name="flow_unlock_lower_priority" id="ea_unlock_lower" value="1" <?php if (!empty($eaUnlock['lower_priority'])) echo 'checked'; ?>/><label for="ea_unlock_lower">Izinkan Lower Priority</label></div>
            <div class="app-chk"><input type="checkbox" name="flow_unlock_omni_flash" id="ea_unlock_omni_flash" value="1" <?php if (!empty($eaUnlock['omni_flash'])) echo 'checked'; ?>/><label for="ea_unlock_omni_flash">Izinkan Omni Flash</label></div>
            <div class="app-chk" style="margin-top:8px; padding-top:8px; border-top:1px dashed rgba(124,58,237,.3);"><input type="checkbox" name="flow_hide_other_projects" id="ea_hide_projects" value="1" <?php if (!isset($editApp['flow_hide_other_projects']) || !empty($editApp['flow_hide_other_projects'])) echo 'checked'; ?>/><label for="ea_hide_projects">Sembunyikan Project Milik Akun (Hanya tampilkan project user sendiri)</label></div>
          </div>
        </div>
        <div class="fi full">
          <div class="app-chk" style="margin-top:10px;">
            <input type="checkbox" name="requires_cookie" id="ea_req_cookie" value="1" <?php if ($editApp['requires_cookie']) echo 'checked'; ?>/>
            <label for="ea_req_cookie" style="font-weight:bold;color:var(--light);">Membutuhkan Injeksi Cookie Otentikasi Terpusat</label>
          </div>
          <p style="font-size:10px;color:var(--muted);margin-top:4px;margin-left:24px;">Hapus centang jika aplikasi berfungsi tanpa login.</p>
        </div>

        <!-- App Specific Popup Block -->
        <div class="fi full" style="background: rgba(0, 150, 100, 0.2); padding: 15px; border-radius: 10px; border: 1px dashed rgba(0, 255, 150, 0.3); margin-top: 15px;">
            <div class="app-chk">
                <input type="checkbox" name="app_popup_enabled" id="ea_app_popup_enabled" value="1" <?php echo !empty($editApp['app_popup_enabled']) ? 'checked' : ''; ?>/>
                <label for="ea_app_popup_enabled" style="font-weight:bold;color:var(--light);">Tampilkan Popup Spesifik Aplikasi (Tutorial / Pengumuman)</label>
            </div>
            <p style="font-size:10px; color:var(--muted); margin-bottom:10px; margin-left: 24px;">Jika aktif, popup ini akan muncul saat aplikasi ini dimuat di ekstensi pengguna.</p>
            <div style="margin-left: 24px; margin-top: 10px;">
                <div class="fi"><label>Judul Popup</label><input type="text" name="app_popup_title" id="ea_app_popup_title" value="<?php echo htmlspecialchars($editApp['app_popup_title'] ?? ''); ?>" placeholder="Contoh: Tutorial Penggunaan Aplikasi Ini" /></div>

                <!-- Mode Switcher -->
                <div style="display:flex; gap:6px; margin-top:14px; padding:4px; background:rgba(0,0,0,.25); border-radius:8px; border:1px solid var(--border);">
                    <button type="button" id="ea_popup_mode_builder" class="btn" style="flex:1; padding:7px 10px; font-size:11px; background:linear-gradient(135deg,#00aa55,#00cc66); border:none; color:#fff; font-weight:600;">🎨 Mode Builder Cepat</button>
                    <button type="button" id="ea_popup_mode_manual" class="btn" style="flex:1; padding:7px 10px; font-size:11px; background:rgba(100,100,100,.2); border:1px solid #555; color:#aaa; font-weight:600;">📝 Mode HTML Manual</button>
                </div>

                <!-- BUILDER MODE -->
                <div id="ea_popup_builder" style="margin-top:12px; padding:12px; background:rgba(0,170,85,.08); border:1px solid rgba(0,170,85,.3); border-radius:8px;">
                    <p style="font-size:10px; color:#7adfa3; margin-bottom:10px; line-height:1.5;">
                        ✨ Tinggal isi field di bawah, sistem otomatis bangun HTML lengkap dengan styling profesional. Tidak perlu coding.
                    </p>
                    <div class="fi" style="margin-bottom:10px;">
                        <label>🎬 URL Video <span style="color:var(--muted); font-weight:400; text-transform:none; letter-spacing:0;">(opsional · MP4/WebM langsung atau YouTube/Vimeo)</span></label>
                        <input type="url" id="ea_pb_video" placeholder="https://upload.texaproject.com/photo/07e0a6be3f7a" style="font-family:monospace; font-size:11px;" />
                    </div>
                    <div class="fi" style="margin-bottom:10px;">
                        <label>🚀 Headline <span style="color:var(--muted); font-weight:400; text-transform:none; letter-spacing:0;">(judul utama dengan emoji)</span></label>
                        <input type="text" id="ea_pb_headline" placeholder="🚀 TEKNO-AFFILIATE TOOLS" maxlength="100" />
                    </div>
                    <div class="fi" style="margin-bottom:10px;">
                        <label>💡 Subtitle / Tagline <span style="color:var(--muted); font-weight:400; text-transform:none; letter-spacing:0;">(satu baris pendek)</span></label>
                        <input type="text" id="ea_pb_subtitle" placeholder="Bikin konten affiliate jadi super mudah!" maxlength="160" />
                    </div>
                    <div class="fi" style="margin-bottom:10px;">
                        <label>📝 Deskripsi Utama <span style="color:var(--muted); font-weight:400; text-transform:none; letter-spacing:0;">(paragraf · bisa pakai **tebal** untuk bold)</span></label>
                        <textarea id="ea_pb_description" rows="3" placeholder="Cukup tulis ide kreatif atau produk yang ingin dipromosikan, lalu biarkan AI bekerja. Dalam hitungan menit, sistem akan menghasilkan **video UGC siap pakai** dengan tampilan profesional."></textarea>
                    </div>
                    <div class="fi" style="margin-bottom:10px;">
                        <label>✅ Daftar Fitur / Bullet Points <span style="color:var(--muted); font-weight:400; text-transform:none; letter-spacing:0;">(satu item per baris)</span></label>
                        <textarea id="ea_pb_bullets" rows="5" placeholder="Tinggal tulis ide&#10;Otomatis jadi video UGC&#10;Cocok untuk affiliate marketing&#10;Hemat waktu produksi konten&#10;Siap upload ke TikTok, Reels, dan Shorts"></textarea>
                    </div>
                    <div class="fi" style="margin-bottom:10px;">
                        <label>🎯 Closing Statement <span style="color:var(--muted); font-weight:400; text-transform:none; letter-spacing:0;">(opsional · paragraf penutup)</span></label>
                        <textarea id="ea_pb_closing" rows="2" placeholder="Mulai sekarang, buat konten yang lebih cepat, lebih mudah, dan lebih menghasilkan dengan **TEKNO-AFFILIATE TOOLS**."></textarea>
                    </div>
                    <button type="button" id="ea_pb_generate" class="btn bp" style="width:100%; padding:10px; font-size:12px; background:linear-gradient(135deg,#00aa55,#00cc66); border:none; color:#fff; font-weight:700;">
                        ⚡ Build HTML Otomatis &amp; Tampilkan Pratinjau
                    </button>
                    <div id="ea_pb_preview_wrap" style="display:none; margin-top:12px; padding:12px; background:rgba(0,0,0,.35); border:1px solid var(--border); border-radius:8px;">
                        <div style="display:flex; justify-content:space-between; align-items:center; margin-bottom:8px;">
                            <span style="font-size:11px; color:#7adfa3; font-weight:600;">👁 Pratinjau Live:</span>
                            <span style="font-size:9px; color:var(--muted);">HTML akan diisi otomatis ke field manual di bawah</span>
                        </div>
                        <div id="ea_pb_preview" style="background:#0a1b30; padding:14px; border-radius:6px; min-height:100px;"></div>
                    </div>
                </div>

                <!-- MANUAL HTML MODE -->
                <div id="ea_popup_manual" style="margin-top:12px;">
                    <div class="fi"><label>Konten / Deskripsi (Dukung HTML &amp; Embed iframe/Video/Gambar)</label>
                        <textarea name="app_popup_content" id="ea_app_popup_content" rows="4" placeholder="Contoh: Silakan tonton video tutorial berikut. <iframe src='...'></iframe>" style="min-height: 80px; font-family:monospace; font-size:11px;"><?php echo htmlspecialchars($editApp['app_popup_content'] ?? ''); ?></textarea>
                    </div>
                </div>
            </div>
        </div>
        <script>
        (function() {
            const $builder = document.getElementById('ea_popup_builder');
            const $manual  = document.getElementById('ea_popup_manual');
            const $btnB    = document.getElementById('ea_popup_mode_builder');
            const $btnM    = document.getElementById('ea_popup_mode_manual');
            const $contentField = document.getElementById('ea_app_popup_content');
            const $previewWrap  = document.getElementById('ea_pb_preview_wrap');
            const $preview      = document.getElementById('ea_pb_preview');

            const ACTIVE_GREEN = 'linear-gradient(135deg,#00aa55,#00cc66)';
            const INACTIVE_BG  = 'rgba(100,100,100,.2)';

            function setMode(mode) {
                if (mode === 'manual') {
                    $builder.style.display = 'none';
                    $manual.style.display = 'block';
                    $btnM.style.background = ACTIVE_GREEN;
                    $btnM.style.color = '#fff';
                    $btnM.style.border = 'none';
                    $btnB.style.background = INACTIVE_BG;
                    $btnB.style.color = '#aaa';
                    $btnB.style.border = '1px solid #555';
                } else {
                    $builder.style.display = 'block';
                    $manual.style.display = 'block';
                    $btnB.style.background = ACTIVE_GREEN;
                    $btnB.style.color = '#fff';
                    $btnB.style.border = 'none';
                    $btnM.style.background = INACTIVE_BG;
                    $btnM.style.color = '#aaa';
                    $btnM.style.border = '1px solid #555';
                }
            }
            $btnB.addEventListener('click', () => setMode('builder'));
            $btnM.addEventListener('click', () => setMode('manual'));
            // Default: if existing content already saved → show manual; else builder
            setMode($contentField.value.trim() ? 'manual' : 'builder');

            // Helper: detect video type & build embed tag
            function buildVideoEmbed(url) {
                if (!url) return '';
                const u = url.trim();
                // YouTube
                const yt = u.match(/(?:youtube\.com\/(?:watch\?v=|embed\/|v\/|shorts\/)|youtu\.be\/)([A-Za-z0-9_-]{11})/);
                if (yt) {
                    return '<div style="position:relative; padding-bottom:56.25%; height:0; overflow:hidden; border-radius:8px; margin-bottom:15px;">'
                         + '<iframe src="https://www.youtube.com/embed/' + yt[1] + '?rel=0" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture" allowfullscreen style="position:absolute; top:0; left:0; width:100%; height:100%;"></iframe>'
                         + '</div>';
                }
                // Vimeo
                const vm = u.match(/vimeo\.com\/(\d+)/);
                if (vm) {
                    return '<div style="position:relative; padding-bottom:56.25%; height:0; overflow:hidden; border-radius:8px; margin-bottom:15px;">'
                         + '<iframe src="https://player.vimeo.com/video/' + vm[1] + '" frameborder="0" allow="autoplay; fullscreen; picture-in-picture" allowfullscreen style="position:absolute; top:0; left:0; width:100%; height:100%;"></iframe>'
                         + '</div>';
                }
                // Direct MP4/WebM/MOV — use <video> tag (also works for upload.texaproject.com without extension thanks to the type override)
                return '<video controls playsinline style="max-width: 100%; border-radius: 8px; margin-bottom: 15px;">'
                     + '<source src="' + u.replace(/"/g, '&quot;') + '" type="video/mp4">'
                     + 'Browser Anda tidak mendukung pemutar video.'
                     + '</video>';
            }

            // Inline markdown: **bold** → <strong>bold</strong>
            function applyBold(text) {
                if (!text) return '';
                const escaped = text.replace(/&/g, '&amp;').replace(/</g, '&lt;').replace(/>/g, '&gt;');
                return escaped.replace(/\*\*([^*]+)\*\*/g, '<strong>$1</strong>');
            }

            function buildHtml() {
                const video    = (document.getElementById('ea_pb_video').value || '').trim();
                const headline = (document.getElementById('ea_pb_headline').value || '').trim();
                const subtitle = (document.getElementById('ea_pb_subtitle').value || '').trim();
                const desc     = (document.getElementById('ea_pb_description').value || '').trim();
                const bullets  = (document.getElementById('ea_pb_bullets').value || '').trim();
                const closing  = (document.getElementById('ea_pb_closing').value || '').trim();

                const videoHtml = buildVideoEmbed(video);
                const headHtml = headline ? '<h4 style="color: #4dc3ff; margin: 0 0 10px 0; font-size: 18px; font-weight: bold;">' + applyBold(headline) + '</h4>' : '';
                const subHtml  = subtitle ? '<p style="margin: 0 0 10px 0; color: #e8f4ff; font-weight: bold;">' + applyBold(subtitle) + '</p>' : '';
                const descHtml = desc ? '<p style="margin: 0 0 12px 0; color: #a8d8ff; font-size: 13px; line-height: 1.6;">' + applyBold(desc) + '</p>' : '';
                let bulletHtml = '';
                if (bullets) {
                    const lines = bullets.split(/\r?\n/).map(s => s.trim()).filter(Boolean);
                    if (lines.length) {
                        const inner = lines.map(l => {
                            // If line already starts with emoji, use as-is; else prefix with ✅
                            const startsWithEmoji = /^[\p{Emoji}\u2700-\u27BF\u2600-\u26FF\u2B00-\u2BFF\u{1F300}-\u{1FAFF}\u2705\u274C\u2728]/u.test(l);
                            return (startsWithEmoji ? '' : '✅ ') + applyBold(l);
                        }).join('<br>');
                        bulletHtml = '<div style="text-align: left; display: inline-block; color: #e8f4ff; font-size: 13px; line-height: 1.7; margin-bottom: 12px;">' + inner + '</div>';
                    }
                }
                const closeHtml = closing ? '<p style="margin: 0; color: #a8d8ff; font-size: 13px; line-height: 1.6;">' + applyBold(closing) + '</p>' : '';

                const cardInner = headHtml + subHtml + descHtml + bulletHtml + closeHtml;
                const cardHtml = cardInner
                    ? '<div style="background: rgba(0, 180, 255, 0.15); border: 1px solid rgba(0, 180, 255, 0.3); padding: 15px; border-radius: 8px;">' + cardInner + '</div>'
                    : '';

                return '<div style="text-align: center;">' + videoHtml + cardHtml + '</div>';
            }

            document.getElementById('ea_pb_generate').addEventListener('click', () => {
                const html = buildHtml();
                $contentField.value = html;
                $preview.innerHTML = html;
                $previewWrap.style.display = 'block';
                $previewWrap.scrollIntoView({ behavior: 'smooth', block: 'nearest' });
            });

            // Auto-rebuild preview on any field change (live mode)
            ['ea_pb_video','ea_pb_headline','ea_pb_subtitle','ea_pb_description','ea_pb_bullets','ea_pb_closing'].forEach(id => {
                const el = document.getElementById(id);
                if (!el) return;
                el.addEventListener('input', () => {
                    if ($previewWrap.style.display === 'block') {
                        const html = buildHtml();
                        $contentField.value = html;
                        $preview.innerHTML = html;
                    }
                });
            });
        })();
        </script>

        <div class="fi full" style="display:flex;gap:8px;justify-content:flex-end;margin-top:4px">
          <a href="?" class="btn bt">Batal</a>
          <button type="submit" class="btn bw">&#x270E; Simpan Perubahan</button>
        </div>
      </div>
    </form>
  </div>
<?php else: ?>
  <div class="card">
    <div class="ct">Tambah Aplikasi Baru</div>
    <form method="POST" enctype="multipart/form-data">
      <input type="hidden" name="action" value="add_app"/>
      <div class="fg">
        <div class="fi full"><label>Nama Aplikasi</label><input type="text" name="name" placeholder="contoh: Midjourney Web" required/></div>
        <div class="fi"><label>Maksimal Server (Slot)</label><input type="number" name="max_servers" value="1" min="1" max="20" required/></div>
        <div class="fi"><label>Upload Icon (Gambar)</label><input type="file" name="icon_file" accept=".png,.jpg,.jpeg,.gif,.svg"/></div>
        <div class="fi full"><label>URL Default (Tujuan Ekstensi)</label><input type="url" name="default_url" placeholder="https://target-app.com/login" required/></div>
        <div class="fi full"><label style="color: #ff4db8;">🔒 Sembunyikan URL Asli (Gunakan Redirect Aman)</label>
            <div style="display:flex; align-items:center; height:100%; background: rgba(255, 77, 184, 0.1); padding: 10px; border-radius: 8px; border: 1px solid rgba(255, 77, 184, 0.3);">
                <input type="checkbox" name="hide_url" value="1" style="width:20px;height:20px;cursor:pointer;accent-color:#ff4db8;">
                <span style="font-size:11px;color:var(--light);margin-left:10px;">Aktifkan untuk mengenkripsi URL tujuan sehingga tidak terlihat di ekstensi browser pengguna.</span>
            </div>
        </div>
        <div class="fi full">
          <label>Hidden Elements (CSS Selectors atau Teks)</label>
          <div style="display:flex; gap: 10px; align-items: stretch; margin-bottom: 8px;">
            <textarea id="html_analyzer_input_add" placeholder="âš¡ MAGIC EXTRACTOR: Paste kode HTML elemen (dari Inspect Element) di sini untuk menghasilkan aturan otomatis..." style="min-height: 60px; font-size: 11px; flex: 1; border-color: rgba(200, 50, 255, 0.4); background: rgba(50, 0, 80, 0.1);"></textarea>
            <button type="button" onclick="analyzeHtmlAdd()" class="btn" style="background: linear-gradient(135deg, #aa00ff, #ff00ff); color: white; border: none; padding: 0 15px;">&#10024; Generate</button>
          </div>
          <textarea id="hidden_elements_input_add" name="hidden_elements" rows="3" placeholder="Contoh CSS: .user-profile, #avatar&#10;Contoh Text: TEXT:1600 AI credits&#10;Contoh Exact Menu: EXACT:Veo 3.1 - Quality" style="min-height: 80px;"></textarea>
          <p style="font-size:10px;color:var(--muted);margin-top:4px;">Gunakan koma untuk memisahkan aturan. Gunakan <b>TEXT:</b> untuk teks umum, atau <b>EXACT:</b> khusus untuk menghapus tombol dropdown presisi tinggi (seperti "EXACT:Veo 3.1 - Quality").</p>
          <div class="app-chk" style="margin-top:10px;">
            <input type="checkbox" name="flow_lock_enabled" id="add_flow_lock_enabled" value="1" checked/>
            <label for="add_flow_lock_enabled" style="font-weight:bold;color:var(--light);">Aktifkan Lock/Hide Flow (Model & UI Restriction)</label>
          </div>
          <p style="font-size:10px;color:var(--muted);margin-top:4px;margin-left:24px;">Khusus halaman Google Flow. Nonaktifkan jika ingin semua opsi model tampil normal (tanpa kunci).</p>
          <div style="margin-top:8px; margin-left:24px; padding:10px; border:1px dashed rgba(124,58,237,.5); border-radius:8px; background:rgba(124,58,237,.08);">
            <label style="display:block; margin-bottom:8px; font-size:11px; color:#d8b4fe;">Unlock Parsial Model Veo</label>
            <div class="app-chk"><input type="checkbox" name="flow_unlock_lite" id="add_unlock_lite" value="1" checked/><label for="add_unlock_lite">Izinkan Lite</label></div>
            <div class="app-chk"><input type="checkbox" name="flow_unlock_fast" id="add_unlock_fast" value="1"/><label for="add_unlock_fast">Izinkan Fast</label></div>
            <div class="app-chk"><input type="checkbox" name="flow_unlock_quality" id="add_unlock_quality" value="1"/><label for="add_unlock_quality">Izinkan Quality</label></div>
            <div class="app-chk"><input type="checkbox" name="flow_unlock_lower_priority" id="add_unlock_lower" value="1" checked/><label for="add_unlock_lower">Izinkan Lower Priority</label></div>
            <div class="app-chk"><input type="checkbox" name="flow_unlock_omni_flash" id="add_unlock_omni_flash" value="1"/><label for="add_unlock_omni_flash">Izinkan Omni Flash</label></div>
            <div class="app-chk" style="margin-top:8px; padding-top:8px; border-top:1px dashed rgba(124,58,237,.3);"><input type="checkbox" name="flow_hide_other_projects" id="add_hide_projects" value="1" checked/><label for="add_hide_projects">Sembunyikan Project Milik Akun (Hanya tampilkan project user sendiri)</label></div>
          </div>
        </div>
        <div class="fi full">
          <div class="app-chk" style="margin-top:10px;">
            <input type="checkbox" name="requires_cookie" id="add_req_cookie" value="1" checked/>
            <label for="add_req_cookie" style="font-weight:bold;color:var(--light);">Membutuhkan Injeksi Cookie Otentikasi Terpusat</label>
          </div>
          <p style="font-size:10px;color:var(--muted);margin-top:4px;margin-left:24px;">Biarkan dicentang jika akan mengunggah cookie .json.</p>
        </div>
        <div class="fi full" style="display:flex;justify-content:flex-end;margin-top:4px">
          <button type="submit" class="btn bp">&#x2726; Tambah Aplikasi</button>
        </div>
      </div>
    </form>
  </div>
<?php endif; ?>

  <div class="card">
    <div class="ct">Daftar Aplikasi yang Tersedia</div>
    <div class="tw"><table class="app-table">
      <thead><tr><th>Aplikasi</th><th>Max Server</th><th>Auth Cookie</th><th>Icon</th><th>Status</th><th>Aksi</th></tr></thead>
      <tbody>
      <?php if (empty($allAppsForAdmin)): ?>
        <tr><td colspan="6" class="empty">Belum ada aplikasi.</td></tr>
      <?php else: foreach ($allAppsForAdmin as $app):
        $stCls = $app['is_active'] ? 'ba' : 'bn';
        $stLbl = $app['is_active'] ? 'AKTIF' : 'NONAKTIF';
      ?>
        <tr>
          <td data-label="Aplikasi"><strong><?php echo htmlspecialchars($app['name']); ?></strong><div style="font-size:10px;color:var(--muted);margin-top:2px;font-family:monospace;"><?php echo htmlspecialchars($app['id']); ?></div></td>
          <td data-label="Max Server"><code class="kd"><?php echo $app['max_servers']; ?> Slot</code></td>
          <td data-label="Auth Cookie"><?php if ($app['requires_cookie']): ?>
            <span class="badge" style="background:rgba(255,170,0,0.1);color:#ffaa00;border:1px solid rgba(255,170,0,0.3)">Diwajibkan</span>
          <?php else: ?>
            <span class="badge bn">Direct</span>
          <?php endif; ?></td>
          <td data-label="Icon"><div style="display:flex;align-items:center;gap:6px;">
            <?php if ($app['icon_type'] === 'image' && strpos($app['icon_value'], 'http') === 0): ?>
              <img src="<?php echo htmlspecialchars($app['icon_value']); ?>" alt="icon" style="width:24px;height:24px;object-fit:cover;border-radius:4px;" onerror="this.outerHTML='<div style=\'width:24px;height:24px;border-radius:4px;background:var(--glass);display:flex;align-items:center;justify-content:center;font-size:12px;border:1px solid var(--border);\'>?</div>'">
            <?php elseif ($app['icon_type'] === 'image'): ?>
              <div style="width:24px;height:24px;border-radius:4px;background:var(--glass);display:flex;align-items:center;justify-content:center;font-weight:bold;font-size:12px;border:1px solid var(--border);"><?php echo strtoupper(substr($app['name'],0,1)); ?></div>
            <?php else: ?>
              <span style="font-size:18px;"><?php echo htmlspecialchars($app['icon_value']); ?></span>
            <?php endif; ?>
          </div></td>
          <td data-label="Status"><span class="badge <?php echo $stCls; ?>"><?php echo $stLbl; ?></span></td>
          <td data-label="Aksi">
            <div class="act-dropdown" style="position: relative; overflow: visible;">
              <button type="button" class="act-btn" onclick="toggleMenu(this)">&#x270E; Aksi &#x25BC;</button>
              <div class="act-menu">
                <a href="?tab=apps&edit_app=<?php echo urlencode($app['id']); ?>" class="m-edit">&#x270E; Edit</a>
                <button type="button" onclick="submitFormAction('toggle_app', '<?php echo htmlspecialchars($app['id']); ?>')"><?php echo $app['is_active']?'&#x1F512; Matikan':'&#x1F513; Nyalakan'; ?></button>
                <button type="button" onclick="if(confirm('Hapus aplikasi beserta cookies-nya?')) submitFormAction('delete_app', '<?php echo htmlspecialchars($app['id']); ?>')" class="m-del">&#x1F5D1; Hapus</button>
              </div>
            </div>
          </td>
        </tr>
      <?php endforeach; endif; ?>
      </tbody>
    </table></div>
  </div>

  <!-- ============================ -->
  <!-- TOOLS-FLOW MANAGEMENT -->
  <!-- ============================ -->
  <?php
  $toolsFlowList = loadData('tools_flow.json');
  if (!is_array($toolsFlowList)) $toolsFlowList = [];
  $editingTool = null;
  if (isset($_GET['edit_tool_flow'])) {
      $etid = $_GET['edit_tool_flow'];
      foreach ($toolsFlowList as $t) {
          if (($t['id'] ?? '') === $etid) { $editingTool = $t; break; }
      }
  }
  // Build server name list from google-flow app (or fallback)
  $tfServerList = [];
  foreach ($allAppsForAdmin as $tfa) {
      if (!empty($tfa['custom_servers']) && is_array($tfa['custom_servers'])) {
          foreach ($tfa['custom_servers'] as $cs) {
              if (!empty($cs['name']) && !in_array($cs['name'], $tfServerList, true)) {
                  $tfServerList[] = $cs['name'];
              }
          }
      } else if (!empty($tfa['name']) && !empty($tfa['max_servers'])) {
          $cleanName = str_replace("\n", ' ', $tfa['name']);
          for ($i = 1; $i <= (int)$tfa['max_servers']; $i++) {
              $sname = $cleanName . ' ' . $i;
              if (!in_array($sname, $tfServerList, true)) $tfServerList[] = $sname;
          }
      }
  }
  $editingAllowed = ($editingTool && isset($editingTool['allowed_servers']) && is_array($editingTool['allowed_servers']))
      ? $editingTool['allowed_servers'] : [];
  ?>
  <div class="card" id="tools-flow" style="border-color: rgba(124,58,237,0.3);">
    <div class="ct" style="display:flex; align-items:center; gap:8px;">
      🔧 TOOLS-FLOW Directory
      <span style="font-size:10px; font-weight:500; padding:3px 8px; border-radius:4px; background:rgba(124,58,237,0.2); color:#c084fc; border:1px solid rgba(124,58,237,0.3);">For Extension Dropdown</span>
    </div>
    <p style="font-size:11px; color: var(--sub, #7aaed4); margin-bottom:14px; line-height:1.5;">
      Tools yang akan muncul di dropdown <strong>TOOLS-FLOW</strong> di panel "My Projects" extension. User akan diberi pilihan project saat klik salah satu tool.
    </p>

    <!-- Add / Edit form -->
    <form method="POST" style="background:rgba(124,58,237,0.05); border:1px solid rgba(124,58,237,0.2); border-radius:10px; padding:14px; margin-bottom:14px;">
      <input type="hidden" name="action" value="<?php echo $editingTool ? 'edit_tool_flow' : 'add_tool_flow'; ?>" />
      <?php if ($editingTool): ?>
        <input type="hidden" name="tf_id" value="<?php echo htmlspecialchars($editingTool['id']); ?>" />
      <?php endif; ?>
      <div class="fg" style="margin-bottom:0;">
        <div class="fi">
          <label>Nama Tool *</label>
          <input type="text" name="tf_name" required maxlength="80" placeholder="Contoh: UGC Generator" value="<?php echo htmlspecialchars($editingTool['name'] ?? ''); ?>" />
        </div>
        <div class="fi">
          <label>Tool Path *</label>
          <input type="text" name="tf_path" required placeholder="tool-version/xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx" value="<?php echo htmlspecialchars($editingTool['path'] ?? ''); ?>" />
        </div>
        <div class="fi full">
          <label>Deskripsi (Opsional)</label>
          <input type="text" name="tf_description" maxlength="160" placeholder="Tool untuk generate konten otomatis" value="<?php echo htmlspecialchars($editingTool['description'] ?? ''); ?>" />
        </div>
        <div class="fi full">
          <label>🎬 URL Tutorial (Opsional) <span style="color:var(--muted,#4a7a9b); font-weight:400; text-transform:none; letter-spacing:0;">— YouTube, Vimeo, MP4, atau halaman cPanel</span></label>
          <input type="url" name="tf_tutorial_url" maxlength="500" placeholder="https://youtu.be/xxxxxxxxxxx atau https://yourdomain.com/video.mp4" value="<?php echo htmlspecialchars($editingTool['tutorial_url'] ?? ''); ?>" />
          <div style="font-size:10px; color:var(--muted,#4a7a9b); margin-top:4px; line-height:1.4;">
            ✓ <strong>YouTube:</strong> <code style="background:rgba(0,0,0,.3); padding:1px 4px; border-radius:3px;">https://youtu.be/abc123</code> &nbsp;
            ✓ <strong>Vimeo:</strong> <code style="background:rgba(0,0,0,.3); padding:1px 4px; border-radius:3px;">https://vimeo.com/12345</code> &nbsp;
            ✓ <strong>Video langsung:</strong> file .mp4/.webm dari cPanel hosting
          </div>
        </div>
        <div class="fi full">
          <label>Akses Server <span style="color:var(--muted,#4a7a9b); font-weight:400; text-transform:none; letter-spacing:0;">(centang server yang boleh akses tool ini · kosong = semua server)</span></label>
          <?php if (empty($tfServerList)): ?>
            <div style="font-size:11px; color:var(--muted,#4a7a9b); padding:8px 10px; background:rgba(0,30,80,.3); border:1px solid var(--border); border-radius:6px;">⚠️ Belum ada server terdaftar di aplikasi. Tool akan dianggap tersedia di semua server.</div>
          <?php else: ?>
            <div style="display:grid; grid-template-columns:repeat(auto-fill, minmax(180px, 1fr)); gap:6px; padding:10px; background:rgba(0,30,80,.3); border:1px solid var(--border); border-radius:8px; max-height:180px; overflow-y:auto;">
              <?php foreach ($tfServerList as $sname):
                  $checked = in_array($sname, $editingAllowed, true) ? 'checked' : '';
              ?>
                <label style="display:flex; align-items:center; gap:6px; font-size:11px; color:var(--text); cursor:pointer; padding:4px 8px; border-radius:5px; transition:background .15s;" onmouseover="this.style.background='rgba(124,58,237,.1)'" onmouseout="this.style.background=''">
                  <input type="checkbox" name="tf_allowed_servers[]" value="<?php echo htmlspecialchars($sname); ?>" <?php echo $checked; ?> style="margin:0;" />
                  <span><?php echo htmlspecialchars($sname); ?></span>
                </label>
              <?php endforeach; ?>
            </div>
            <div style="display:flex; gap:6px; margin-top:6px;">
              <button type="button" onclick="document.querySelectorAll('input[name=\'tf_allowed_servers[]\']').forEach(c=>c.checked=true);" style="font-size:10px; padding:4px 10px; background:rgba(0,150,255,.15); border:1px solid rgba(0,150,255,.3); color:#4db8ff; border-radius:5px; cursor:pointer; font-family:inherit;">✓ Pilih Semua</button>
              <button type="button" onclick="document.querySelectorAll('input[name=\'tf_allowed_servers[]\']').forEach(c=>c.checked=false);" style="font-size:10px; padding:4px 10px; background:rgba(100,100,100,.15); border:1px solid #555; color:#aaa; border-radius:5px; cursor:pointer; font-family:inherit;">✕ Kosongkan</button>
            </div>
          <?php endif; ?>
        </div>
        <div class="fi full" style="display:flex; gap:8px; justify-content:flex-end; margin-top:6px;">
          <?php if ($editingTool): ?>
            <a href="?tab=apps#tools-flow" class="btn" style="background:rgba(100,100,100,.2); border:1px solid #555; color:#aaa;">Batal Edit</a>
          <?php endif; ?>
          <button type="submit" class="btn bp" style="background:linear-gradient(135deg,#7c3aed,#a855f7); border:none; color:#fff;">
            <?php echo $editingTool ? '💾 Simpan Perubahan' : '➕ Tambah Tool'; ?>
          </button>
        </div>
      </div>
      <div style="font-size:10px; color:var(--muted, #4a7a9b); margin-top:8px; line-height:1.4;">
        💡 <strong>Tips:</strong> Path bisa dipaste langsung dari URL Google Flow seperti <code style="background:rgba(0,0,0,.3); padding:1px 5px; border-radius:3px;">https://labs.google/fx/tools/flow/project/{ID}/tool-version/{TOOL_ID}</code> — sistem akan otomatis ekstrak bagian setelah project ID.
      </div>
    </form>

    <!-- Tools list -->
    <?php if (empty($toolsFlowList)): ?>
      <div style="text-align:center; padding:30px 20px; color: var(--muted, #4a7a9b); font-size:12px; background:rgba(0,30,80,.2); border-radius:10px;">
        <div style="font-size:32px; margin-bottom:8px; opacity:.4;">🔧</div>
        <div>Belum ada tool terdaftar.</div>
      </div>
    <?php else: ?>
      <div style="display:flex; flex-direction:column; gap:8px;">
        <?php foreach ($toolsFlowList as $t):
          $tid = htmlspecialchars($t['id'] ?? '');
          $tname = htmlspecialchars($t['name'] ?? '');
          $tpath = htmlspecialchars($t['path'] ?? '');
          $tdesc = htmlspecialchars($t['description'] ?? '');
          $ttutorial = htmlspecialchars($t['tutorial_url'] ?? '');
          $tactive = !empty($t['is_active']);
          $tcreated = htmlspecialchars($t['created_at'] ?? '');
          $tAllowed = isset($t['allowed_servers']) && is_array($t['allowed_servers']) ? $t['allowed_servers'] : [];
        ?>
          <div style="background:rgba(0,30,80,.4); border:1px solid <?php echo $tactive ? 'rgba(124,58,237,.4)' : 'rgba(100,100,100,.3)'; ?>; border-radius:10px; padding:12px 14px; display:flex; align-items:center; gap:12px; <?php echo $tactive ? '' : 'opacity:0.5;'; ?>">
            <div style="font-size:24px;"><?php echo $tactive ? '🔧' : '🔒'; ?></div>
            <div style="flex:1; min-width:0;">
              <div style="display:flex; align-items:center; gap:8px; margin-bottom:3px;">
                <span style="font-size:14px; font-weight:600; color:#fff;"><?php echo $tname; ?></span>
                <?php if (!$tactive): ?>
                  <span style="font-size:9px; padding:2px 6px; background:rgba(255,77,77,.15); color:#ff8080; border-radius:3px;">DISABLED</span>
                <?php endif; ?>
              </div>
              <div style="font-size:11px; color:var(--sub,#7aaed4); margin-bottom:4px;"><?php echo $tdesc ?: '<em style="opacity:.5">No description</em>'; ?></div>
              <div style="display:flex; flex-wrap:wrap; gap:4px; margin-bottom:4px;">
                <?php if (empty($tAllowed)): ?>
                  <span style="font-size:9px; padding:2px 7px; background:rgba(0,230,118,.15); color:#00e676; border:1px solid rgba(0,230,118,.3); border-radius:3px;">📡 ALL SERVERS</span>
                <?php else: ?>
                  <?php foreach ($tAllowed as $sn): ?>
                    <span style="font-size:9px; padding:2px 7px; background:rgba(124,58,237,.15); color:#c084fc; border:1px solid rgba(124,58,237,.3); border-radius:3px;">📡 <?php echo htmlspecialchars($sn); ?></span>
                  <?php endforeach; ?>
                <?php endif; ?>
              </div>
              <code style="font-size:10px; color:#7c3aed; background:rgba(0,0,0,.25); padding:2px 6px; border-radius:3px; word-break:break-all; display:inline-block;"><?php echo $tpath; ?></code>
              <?php if ($ttutorial): ?>
                <a href="<?php echo $ttutorial; ?>" target="_blank" rel="noopener" style="font-size:9px; padding:2px 7px; margin-left:4px; background:rgba(255,77,77,.15); color:#ff8080; border:1px solid rgba(255,77,77,.3); border-radius:3px; text-decoration:none; display:inline-block;">🎬 Tutorial</a>
              <?php endif; ?>
              <?php if ($tcreated): ?>
                <span style="font-size:9px; color:var(--muted,#4a7a9b); margin-left:6px;">· created <?php echo $tcreated; ?></span>
              <?php endif; ?>
            </div>
            <div style="display:flex; gap:6px; align-items:center;">
              <a href="?tab=apps&edit_tool_flow=<?php echo urlencode($t['id'] ?? ''); ?>#tools-flow" class="btn" style="padding:6px 10px; font-size:11px; background:rgba(0,150,255,.15); border:1px solid rgba(0,150,255,.3); color:#4db8ff;">✎ Edit</a>
              <form method="POST" style="margin:0;">
                <input type="hidden" name="action" value="toggle_tool_flow" />
                <input type="hidden" name="tf_id" value="<?php echo $tid; ?>" />
                <button type="submit" class="btn" style="padding:6px 10px; font-size:11px; background:<?php echo $tactive ? 'rgba(255,170,0,.15)' : 'rgba(0,230,118,.15)'; ?>; border:1px solid <?php echo $tactive ? 'rgba(255,170,0,.3)' : 'rgba(0,230,118,.3)'; ?>; color:<?php echo $tactive ? '#ffcc44' : '#00e676'; ?>;"><?php echo $tactive ? '⏸ Disable' : '▶ Enable'; ?></button>
              </form>
              <form method="POST" onsubmit="return confirm('Hapus tool: <?php echo htmlspecialchars(addslashes($t['name'] ?? ''), ENT_QUOTES); ?>?');" style="margin:0;">
                <input type="hidden" name="action" value="delete_tool_flow" />
                <input type="hidden" name="tf_id" value="<?php echo $tid; ?>" />
                <button type="submit" class="btn" style="padding:6px 10px; font-size:11px; background:rgba(255,77,77,.15); border:1px solid rgba(255,77,77,.3); color:#ff8080;">🗑</button>
              </form>
            </div>
          </div>
        <?php endforeach; ?>
      </div>
    <?php endif; ?>
  </div>

  <!-- ============================ -->
  <!-- FLOW LOCKS — Custom Element Lock by HTML Snippet -->
  <!-- ============================ -->
  <?php
  $flowLocksList = loadData('flow_locks.json');
  if (!is_array($flowLocksList)) $flowLocksList = [];
  $editingLock = null;
  if (isset($_GET['edit_flow_lock'])) {
      $eflid = $_GET['edit_flow_lock'];
      foreach ($flowLocksList as $L) {
          if (($L['id'] ?? '') === $eflid) { $editingLock = $L; break; }
      }
  }
  $flServerList = $tfServerList; // reuse server list from tools-flow
  $editingLockAllowed = ($editingLock && isset($editingLock['allowed_servers']) && is_array($editingLock['allowed_servers']))
      ? $editingLock['allowed_servers'] : [];
  ?>
  <div class="card" id="flow-locks" style="border-color: rgba(255,77,77,0.3);">
    <div class="ct" style="display:flex; align-items:center; gap:8px;">
      🔐 Aktifkan Lock/Hide Flow (Model & UI Restriction)
      <span style="font-size:10px; font-weight:500; padding:3px 8px; border-radius:4px; background:rgba(255,77,77,0.2); color:#ff8080; border:1px solid rgba(255,77,77,0.3);">Custom Element Lock</span>
    </div>
    <p style="font-size:11px; color: var(--sub, #7aaed4); margin-bottom:14px; line-height:1.5;">
      Paste HTML element dari Google Flow (klik kanan → <code style="background:rgba(0,0,0,.3); padding:1px 5px; border-radius:3px;">Inspect</code> → kanan-klik element → <code style="background:rgba(0,0,0,.3); padding:1px 5px; border-radius:3px;">Copy outerHTML</code>) — extension akan auto-detect & block element tersebut di halaman user.
    </p>

    <!-- ===== MASTER CONTROLS (Kill-switch + Bulk ops) ===== -->
    <?php
    $globalSettings = loadData('settings.json');
    $masterEnabled = !empty($globalSettings['flow_locks_master_enabled']);
    // Default: if key not yet set, treat as ENABLED (preserve old behavior)
    if (!isset($globalSettings['flow_locks_master_enabled'])) $masterEnabled = true;
    $totalLocks = count($flowLocksList);
    $activeLocks = 0;
    foreach ($flowLocksList as $L) { if (!empty($L['is_active'])) $activeLocks++; }
    ?>
    <div style="background: <?php echo $masterEnabled ? 'rgba(0,170,85,.08)' : 'rgba(255,170,0,.1)'; ?>; border:1px solid <?php echo $masterEnabled ? 'rgba(0,230,118,.3)' : 'rgba(255,170,0,.4)'; ?>; border-radius:10px; padding:14px; margin-bottom:14px;">
      <div style="display:flex; align-items:center; justify-content:space-between; gap:12px; flex-wrap:wrap;">
        <div style="flex:1; min-width:240px;">
          <div style="font-size:13px; font-weight:700; color:<?php echo $masterEnabled ? '#00e676' : '#ffcc44'; ?>; margin-bottom:4px; display:flex; align-items:center; gap:8px;">
            <?php echo $masterEnabled ? '🔐 Master Switch: AKTIF' : '🔓 Master Switch: OFF (semua lock dimatikan)'; ?>
          </div>
          <div style="font-size:11px; color:var(--sub,#7aaed4); line-height:1.5;">
            Total: <strong style="color:#fff;"><?php echo $totalLocks; ?></strong> lock terdaftar ·
            <strong style="color:#00e676;"><?php echo $activeLocks; ?></strong> aktif ·
            <strong style="color:#ff8080;"><?php echo $totalLocks - $activeLocks; ?></strong> disabled
          </div>
          <?php if (!$masterEnabled): ?>
            <div style="font-size:10px; color:#ffcc44; margin-top:6px;">⚠️ Saat OFF, extension akan abaikan semua lock — user bisa klik element yang tadinya dikunci.</div>
          <?php endif; ?>
        </div>
        <div style="display:flex; gap:6px; flex-wrap:wrap; justify-content:flex-end;">
          <form method="POST" style="margin:0;">
            <input type="hidden" name="action" value="master_toggle_flow_locks" />
            <button type="submit" class="btn" style="padding:8px 14px; font-size:11px; font-weight:600; background:<?php echo $masterEnabled ? 'linear-gradient(135deg,#ff8a00,#ff4d4d)' : 'linear-gradient(135deg,#00aa55,#00cc66)'; ?>; border:none; color:#fff;">
              <?php echo $masterEnabled ? '⏸ Matikan Semua' : '▶ Aktifkan Semua'; ?>
            </button>
          </form>
          <?php if ($totalLocks > 0): ?>
            <form method="POST" style="margin:0;" onsubmit="return confirm('Disable SEMUA <?php echo $totalLocks; ?> lock? Config tetap tersimpan dan bisa di-Enable lagi.');">
              <input type="hidden" name="action" value="bulk_disable_all_flow_locks" />
              <button type="submit" class="btn" style="padding:8px 14px; font-size:11px; background:rgba(255,170,0,.15); border:1px solid rgba(255,170,0,.35); color:#ffcc44;">⏸ Disable Semua</button>
            </form>
            <form method="POST" style="margin:0;" onsubmit="return confirm('Enable SEMUA <?php echo $totalLocks; ?> lock?');">
              <input type="hidden" name="action" value="bulk_enable_all_flow_locks" />
              <button type="submit" class="btn" style="padding:8px 14px; font-size:11px; background:rgba(0,230,118,.12); border:1px solid rgba(0,230,118,.3); color:#00e676;">▶ Enable Semua</button>
            </form>
            <form method="POST" style="margin:0;" onsubmit="return confirm('⚠️ HAPUS PERMANEN semua <?php echo $totalLocks; ?> lock? Tindakan ini tidak bisa dibatalkan!');">
              <input type="hidden" name="action" value="delete_all_flow_locks" />
              <button type="submit" class="btn" style="padding:8px 14px; font-size:11px; background:rgba(255,77,77,.18); border:1px solid rgba(255,77,77,.4); color:#ff8080; font-weight:600;">🗑 Hapus Semua</button>
            </form>
          <?php endif; ?>
        </div>
      </div>
    </div>

    <!-- Add / Edit form -->
    <form method="POST" style="background:rgba(255,77,77,0.05); border:1px solid rgba(255,77,77,0.2); border-radius:10px; padding:14px; margin-bottom:14px;">
      <input type="hidden" name="action" value="<?php echo $editingLock ? 'edit_flow_lock' : 'add_flow_lock'; ?>" />
      <?php if ($editingLock): ?>
        <input type="hidden" name="fl_id" value="<?php echo htmlspecialchars($editingLock['id']); ?>" />
      <?php endif; ?>
      <div class="fg" style="margin-bottom:0;">
        <div class="fi">
          <label>Nama Lock *</label>
          <input type="text" name="fl_name" required maxlength="80" placeholder="Contoh: Tombol Tools (apps_spark_2)" value="<?php echo htmlspecialchars($editingLock['name'] ?? ''); ?>" />
        </div>
        <div class="fi">
          <label>Mode Lock *</label>
          <select name="fl_mode" required>
            <?php $curMode = $editingLock['mode'] ?? 'overlay'; ?>
            <option value="overlay" <?php echo $curMode==='overlay'?'selected':''; ?>>🛡️ Overlay (block click, masih terlihat)</option>
            <option value="hide" <?php echo $curMode==='hide'?'selected':''; ?>>👁‍🗨 Hide (sembunyikan total)</option>
            <option value="disable" <?php echo $curMode==='disable'?'selected':''; ?>>⛔ Disable (grey-out + lock icon)</option>
          </select>
        </div>
        <div class="fi">
          <label>Apply On *</label>
          <select name="fl_apply_on" required>
            <?php $curApply = $editingLock['apply_on'] ?? 'both'; ?>
            <option value="both" <?php echo $curApply==='both'?'selected':''; ?>>Semua halaman Flow</option>
            <option value="list" <?php echo $curApply==='list'?'selected':''; ?>>Hanya halaman List Project</option>
            <option value="project" <?php echo $curApply==='project'?'selected':''; ?>>Hanya halaman Project</option>
          </select>
        </div>
        <div class="fi full">
          <label>Pesan saat di-klik (opsional)</label>
          <input type="text" name="fl_message" maxlength="160" placeholder="Default: 'Fitur ini dikunci oleh admin'" value="<?php echo htmlspecialchars($editingLock['message'] ?? ''); ?>" />
        </div>
        <div class="fi full">
          <label>Paste HTML Element <span style="color:#ff8080;">*</span> <span style="color:var(--muted,#4a7a9b); font-weight:400; text-transform:none; letter-spacing:0;">(Copy outerHTML dari DevTools)</span></label>
          <textarea name="fl_html" required rows="5" placeholder='<button data-state="closed" class="sc-e8425ea6-0 hOBPaw ..."><i class="google-symbols ...">apps_spark_2</i><span>Tools</span></button>' style="font-family:monospace; font-size:11px; resize:vertical; min-height:90px;"><?php echo htmlspecialchars($editingLock['signature']['raw'] ?? ''); ?></textarea>
          <div style="font-size:10px; color:var(--muted,#4a7a9b); margin-top:4px; line-height:1.4;">
            💡 Sistem akan extract: <strong>tag</strong>, <strong>class</strong>, <strong>text</strong>, <strong>icon name</strong>, <strong>data-attrs</strong>, <strong>aria-label</strong>, <strong>href</strong> — score-based matching agar tetap valid meski class hash berubah.
          </div>
          <?php if ($editingLock && !empty($editingLock['signature'])): $sig = $editingLock['signature']; ?>
            <div style="margin-top:8px; padding:8px 10px; background:rgba(0,30,80,.3); border:1px solid var(--border); border-radius:6px; font-size:10px; line-height:1.5;">
              <strong style="color:#4db8ff;">📋 Signature tersimpan:</strong><br>
              <span style="color:var(--muted,#7aaed4);">Tag:</span> <code style="color:#fff;"><?php echo htmlspecialchars($sig['tag'] ?? ''); ?></code>
              <?php if (!empty($sig['icon_text'])): ?>
                · <span style="color:var(--muted,#7aaed4);">Icon:</span> <code style="color:#ffcc44;"><?php echo htmlspecialchars($sig['icon_text']); ?></code>
              <?php endif; ?>
              <?php if (!empty($sig['text'])): ?>
                · <span style="color:var(--muted,#7aaed4);">Text:</span> <code style="color:#a5d8ff;"><?php echo htmlspecialchars(mb_substr($sig['text'], 0, 60)); ?></code>
              <?php endif; ?>
              <?php if (!empty($sig['aria_label'])): ?>
                · <span style="color:var(--muted,#7aaed4);">Aria:</span> <code style="color:#a5d8ff;"><?php echo htmlspecialchars($sig['aria_label']); ?></code>
              <?php endif; ?>
              <?php if (!empty($sig['classes'])): ?>
                <br><span style="color:var(--muted,#7aaed4);">Classes:</span> <code style="color:#c084fc;"><?php echo htmlspecialchars(implode(' ', array_slice($sig['classes'], 0, 6))); ?></code>
              <?php endif; ?>
            </div>
          <?php endif; ?>
        </div>
        <div class="fi full">
          <label>Akses Server <span style="color:var(--muted,#4a7a9b); font-weight:400; text-transform:none; letter-spacing:0;">(centang server yang TERAPKAN lock ini · kosong = semua server)</span></label>
          <?php if (empty($flServerList)): ?>
            <div style="font-size:11px; color:var(--muted,#4a7a9b); padding:8px 10px; background:rgba(0,30,80,.3); border:1px solid var(--border); border-radius:6px;">⚠️ Belum ada server terdaftar. Lock akan diterapkan di semua server.</div>
          <?php else: ?>
            <div style="display:grid; grid-template-columns:repeat(auto-fill, minmax(180px, 1fr)); gap:6px; padding:10px; background:rgba(0,30,80,.3); border:1px solid var(--border); border-radius:8px; max-height:180px; overflow-y:auto;">
              <?php foreach ($flServerList as $sname):
                  $checked = in_array($sname, $editingLockAllowed, true) ? 'checked' : '';
              ?>
                <label style="display:flex; align-items:center; gap:6px; font-size:11px; color:var(--text); cursor:pointer; padding:4px 8px; border-radius:5px;">
                  <input type="checkbox" name="fl_allowed_servers[]" value="<?php echo htmlspecialchars($sname); ?>" <?php echo $checked; ?> style="margin:0;" />
                  <span><?php echo htmlspecialchars($sname); ?></span>
                </label>
              <?php endforeach; ?>
            </div>
            <div style="display:flex; gap:6px; margin-top:6px;">
              <button type="button" onclick="document.querySelectorAll('input[name=\'fl_allowed_servers[]\']').forEach(c=>c.checked=true);" style="font-size:10px; padding:4px 10px; background:rgba(0,150,255,.15); border:1px solid rgba(0,150,255,.3); color:#4db8ff; border-radius:5px; cursor:pointer; font-family:inherit;">✓ Pilih Semua</button>
              <button type="button" onclick="document.querySelectorAll('input[name=\'fl_allowed_servers[]\']').forEach(c=>c.checked=false);" style="font-size:10px; padding:4px 10px; background:rgba(100,100,100,.15); border:1px solid #555; color:#aaa; border-radius:5px; cursor:pointer; font-family:inherit;">✕ Kosongkan</button>
            </div>
          <?php endif; ?>
        </div>
        <div class="fi full" style="display:flex; gap:8px; justify-content:flex-end; margin-top:6px;">
          <?php if ($editingLock): ?>
            <a href="?tab=apps#flow-locks" class="btn" style="background:rgba(100,100,100,.2); border:1px solid #555; color:#aaa;">Batal Edit</a>
          <?php endif; ?>
          <button type="submit" class="btn bp" style="background:linear-gradient(135deg,#ff4d4d,#cc0000); border:none; color:#fff;">
            <?php echo $editingLock ? '💾 Simpan Perubahan' : '🔐 Tambah Lock'; ?>
          </button>
        </div>
      </div>
    </form>

    <!-- Locks list -->
    <?php if (empty($flowLocksList)): ?>
      <div style="text-align:center; padding:30px 20px; color: var(--muted, #4a7a9b); font-size:12px; background:rgba(0,30,80,.2); border-radius:10px;">
        <div style="font-size:32px; margin-bottom:8px; opacity:.4;">🔐</div>
        <div>Belum ada lock terdaftar.</div>
      </div>
    <?php else: ?>
      <div style="display:flex; flex-direction:column; gap:8px;">
        <?php foreach ($flowLocksList as $L):
          $lid = htmlspecialchars($L['id'] ?? '');
          $lname = htmlspecialchars($L['name'] ?? '');
          $lmode = htmlspecialchars($L['mode'] ?? 'overlay');
          $lapply = htmlspecialchars($L['apply_on'] ?? 'both');
          $lmsg = htmlspecialchars($L['message'] ?? '');
          $lactive = !empty($L['is_active']);
          $lcreated = htmlspecialchars($L['created_at'] ?? '');
          $lAllowed = isset($L['allowed_servers']) && is_array($L['allowed_servers']) ? $L['allowed_servers'] : [];
          $lsig = $L['signature'] ?? [];
          $modeLabel = ['overlay'=>['🛡️ Overlay','#4db8ff'],'hide'=>['👁‍🗨 Hide','#c084fc'],'disable'=>['⛔ Disable','#ff8080']];
          $applyLabel = ['both'=>'Semua','list'=>'List Page','project'=>'Project Page'];
          [$mLab, $mColor] = $modeLabel[$lmode] ?? ['?','#aaa'];
        ?>
          <div style="background:rgba(0,30,80,.4); border:1px solid <?php echo $lactive ? 'rgba(255,77,77,.4)' : 'rgba(100,100,100,.3)'; ?>; border-radius:10px; padding:12px 14px; display:flex; align-items:center; gap:12px; <?php echo $lactive ? '' : 'opacity:0.5;'; ?>">
            <div style="font-size:24px;"><?php echo $lactive ? '🔐' : '🔓'; ?></div>
            <div style="flex:1; min-width:0;">
              <div style="display:flex; align-items:center; gap:8px; margin-bottom:3px; flex-wrap:wrap;">
                <span style="font-size:14px; font-weight:600; color:#fff;"><?php echo $lname; ?></span>
                <span style="font-size:9px; padding:2px 7px; background:rgba(<?php echo $lmode==='overlay'?'77,184,255':($lmode==='hide'?'192,132,252':'255,128,128'); ?>,.15); color:<?php echo $mColor; ?>; border:1px solid <?php echo $mColor; ?>55; border-radius:3px;"><?php echo $mLab; ?></span>
                <span style="font-size:9px; padding:2px 7px; background:rgba(124,58,237,.15); color:#c084fc; border:1px solid rgba(124,58,237,.3); border-radius:3px;">📍 <?php echo $applyLabel[$lapply] ?? $lapply; ?></span>
                <?php if (!$lactive): ?>
                  <span style="font-size:9px; padding:2px 6px; background:rgba(255,77,77,.15); color:#ff8080; border-radius:3px;">DISABLED</span>
                <?php endif; ?>
              </div>
              <?php if (!empty($lsig['tag'])): ?>
                <div style="font-size:11px; color:var(--sub,#7aaed4); margin-bottom:4px; word-break:break-all;">
                  <code style="background:rgba(0,0,0,.25); padding:1px 5px; border-radius:3px; color:#fff;">&lt;<?php echo htmlspecialchars($lsig['tag']); ?>&gt;</code>
                  <?php if (!empty($lsig['icon_text'])): ?>
                    · icon=<code style="color:#ffcc44;"><?php echo htmlspecialchars($lsig['icon_text']); ?></code>
                  <?php endif; ?>
                  <?php if (!empty($lsig['text'])): ?>
                    · text=<code style="color:#a5d8ff;"><?php echo htmlspecialchars(mb_substr($lsig['text'], 0, 40)); ?></code>
                  <?php endif; ?>
                  <?php if (!empty($lsig['aria_label'])): ?>
                    · aria=<code style="color:#a5d8ff;"><?php echo htmlspecialchars($lsig['aria_label']); ?></code>
                  <?php endif; ?>
                </div>
              <?php endif; ?>
              <?php if ($lmsg): ?>
                <div style="font-size:10px; color:#ffaa44; margin-top:3px;">💬 "<?php echo $lmsg; ?>"</div>
              <?php endif; ?>
              <div style="display:flex; flex-wrap:wrap; gap:4px; margin-top:5px;">
                <?php if (empty($lAllowed)): ?>
                  <span style="font-size:9px; padding:2px 7px; background:rgba(0,230,118,.15); color:#00e676; border:1px solid rgba(0,230,118,.3); border-radius:3px;">📡 ALL SERVERS</span>
                <?php else: ?>
                  <?php foreach ($lAllowed as $sn): ?>
                    <span style="font-size:9px; padding:2px 7px; background:rgba(124,58,237,.15); color:#c084fc; border:1px solid rgba(124,58,237,.3); border-radius:3px;">📡 <?php echo htmlspecialchars($sn); ?></span>
                  <?php endforeach; ?>
                <?php endif; ?>
              </div>
              <?php if ($lcreated): ?>
                <div style="font-size:9px; color:var(--muted,#4a7a9b); margin-top:3px;">· created <?php echo $lcreated; ?></div>
              <?php endif; ?>
            </div>
            <div style="display:flex; gap:6px; align-items:center;">
              <a href="?tab=apps&edit_flow_lock=<?php echo urlencode($L['id'] ?? ''); ?>#flow-locks" class="btn" style="padding:6px 10px; font-size:11px; background:rgba(0,150,255,.15); border:1px solid rgba(0,150,255,.3); color:#4db8ff;">✎ Edit</a>
              <form method="POST" style="margin:0;">
                <input type="hidden" name="action" value="toggle_flow_lock" />
                <input type="hidden" name="fl_id" value="<?php echo $lid; ?>" />
                <button type="submit" class="btn" style="padding:6px 10px; font-size:11px; background:<?php echo $lactive ? 'rgba(255,170,0,.15)' : 'rgba(0,230,118,.15)'; ?>; border:1px solid <?php echo $lactive ? 'rgba(255,170,0,.3)' : 'rgba(0,230,118,.3)'; ?>; color:<?php echo $lactive ? '#ffcc44' : '#00e676'; ?>;"><?php echo $lactive ? '⏸ Disable' : '▶ Enable'; ?></button>
              </form>
              <form method="POST" onsubmit="return confirm('Hapus lock: <?php echo htmlspecialchars(addslashes($L['name'] ?? ''), ENT_QUOTES); ?>?');" style="margin:0;">
                <input type="hidden" name="action" value="delete_flow_lock" />
                <input type="hidden" name="fl_id" value="<?php echo $lid; ?>" />
                <button type="submit" class="btn" style="padding:6px 10px; font-size:11px; background:rgba(255,77,77,.15); border:1px solid rgba(255,77,77,.3); color:#ff8080;">🗑</button>
              </form>
            </div>
          </div>
        <?php endforeach; ?>
      </div>
    <?php endif; ?>
  </div>

  <!-- ============================ -->
  <!-- FLOW URL BLOCKS — block specific URL patterns from being opened -->
  <!-- ============================ -->
  <?php
  $urlBlocksList = loadData('flow_url_blocks.json');
  if (!is_array($urlBlocksList)) $urlBlocksList = [];
  $editingUrlBlock = null;
  if (isset($_GET['edit_flow_url_block'])) {
      $eubid = $_GET['edit_flow_url_block'];
      foreach ($urlBlocksList as $R) {
          if (($R['id'] ?? '') === $eubid) { $editingUrlBlock = $R; break; }
      }
  }
  $urlBlockEditAllowed = ($editingUrlBlock && isset($editingUrlBlock['allowed_servers']) && is_array($editingUrlBlock['allowed_servers']))
      ? $editingUrlBlock['allowed_servers'] : [];
  $ublockMasterEnabled = !empty($globalSettings['flow_url_blocks_master_enabled']);
  if (!isset($globalSettings['flow_url_blocks_master_enabled'])) $ublockMasterEnabled = true;
  $totalUrlBlocks = count($urlBlocksList);
  $activeUrlBlocks = 0;
  foreach ($urlBlocksList as $R) { if (!empty($R['is_active'])) $activeUrlBlocks++; }
  ?>
  <div class="card" id="flow-url-blocks" style="border-color: rgba(255,170,0,0.3);">
    <div class="ct" style="display:flex; align-items:center; gap:8px;">
      🚫 Block URL Spesifik (Flow URL Filter)
      <span style="font-size:10px; font-weight:500; padding:3px 8px; border-radius:4px; background:rgba(255,170,0,0.2); color:#ffcc44; border:1px solid rgba(255,170,0,0.3);">URL Pattern Block</span>
    </div>
    <div class="cd" style="font-size:12px; color: var(--sub,#7aaed4); margin-top:6px;">
      Blokir URL spesifik (misal <code style="background:rgba(255,170,0,.1);padding:1px 5px;border-radius:3px;">tools?tab=GALLERY</code> atau <code style="background:rgba(255,170,0,.1);padding:1px 5px;border-radius:3px;">tools?tab=MY_APPS</code>) — user di-redirect ke project bare URL atau URL custom.
    </div>

    <!-- Master Switch -->
    <div style="background: <?php echo $ublockMasterEnabled ? 'rgba(0,170,85,.08)' : 'rgba(255,170,0,.1)'; ?>; border:1px solid <?php echo $ublockMasterEnabled ? 'rgba(0,230,118,.3)' : 'rgba(255,170,0,.4)'; ?>; border-radius:10px; padding:14px; margin-bottom:14px; margin-top:10px;">
      <div style="display:flex; justify-content:space-between; align-items:center; flex-wrap:wrap; gap:10px;">
        <div>
          <div style="font-size:13px; font-weight:600; color: <?php echo $ublockMasterEnabled ? '#00e676' : '#ffaa00'; ?>; margin-bottom:4px;">
            <?php if ($ublockMasterEnabled): ?>🔐 URL Block Master: AKTIF<?php else: ?>🔓 URL Block Master: OFF<?php endif; ?>
          </div>
          <div style="font-size:11px; color:var(--sub,#7aaed4); line-height:1.5;">
            Total: <strong style="color:#fff;"><?php echo $totalUrlBlocks; ?></strong> rule ·
            <strong style="color:#00e676;"><?php echo $activeUrlBlocks; ?></strong> aktif ·
            <strong style="color:#ff8080;"><?php echo $totalUrlBlocks - $activeUrlBlocks; ?></strong> disabled
          </div>
        </div>
        <form method="POST" style="margin:0;">
          <input type="hidden" name="action" value="master_toggle_flow_url_blocks" />
          <button type="submit" class="btn" style="padding:8px 14px; font-size:11px; font-weight:600; background:<?php echo $ublockMasterEnabled ? 'linear-gradient(135deg,#ff8a00,#ff4d4d)' : 'linear-gradient(135deg,#00aa55,#00cc66)'; ?>; border:none; color:#fff;">
            <?php echo $ublockMasterEnabled ? '⏸ Matikan Semua' : '▶ Aktifkan Semua'; ?>
          </button>
        </form>
      </div>
    </div>

    <!-- Add / Edit form -->
    <form method="POST" style="background:rgba(255,170,0,0.05); border:1px solid rgba(255,170,0,0.25); border-radius:10px; padding:14px; margin-bottom:14px;">
      <input type="hidden" name="action" value="<?php echo $editingUrlBlock ? 'edit_flow_url_block' : 'add_flow_url_block'; ?>" />
      <?php if ($editingUrlBlock): ?>
        <input type="hidden" name="fr_id" value="<?php echo htmlspecialchars($editingUrlBlock['id']); ?>" />
      <?php endif; ?>
      <div class="grid" style="display:grid; grid-template-columns: 1fr 1fr; gap:12px;">
        <div class="fi">
          <label style="font-size:11px; font-weight:600; color: var(--sub,#7aaed4);">NAMA RULE (OPSIONAL)</label>
          <input type="text" name="name" placeholder="contoh: Block Gallery Tab" value="<?php echo htmlspecialchars($editingUrlBlock['name'] ?? ''); ?>" style="width:100%; padding:9px 12px; font-size:12px; border-radius:6px; background:rgba(0,0,0,.3); border:1px solid rgba(255,170,0,.2); color:#fff;" />
        </div>
        <div class="fi">
          <label style="font-size:11px; font-weight:600; color: var(--sub,#7aaed4);">MODE MATCHING *</label>
          <select name="mode" required style="width:100%; padding:9px 12px; font-size:12px; border-radius:6px; background:rgba(0,0,0,.3); border:1px solid rgba(255,170,0,.2); color:#fff;">
            <option value="exact" <?php echo (($editingUrlBlock['mode'] ?? 'exact') === 'exact') ? 'selected' : ''; ?>>🎯 Exact — match URL persis (slash & query harus sama)</option>
            <option value="wildcard" <?php echo (($editingUrlBlock['mode'] ?? '') === 'wildcard') ? 'selected' : ''; ?>>🌟 Wildcard — pakai <code>xxx</code> atau <code>*</code> sebagai placeholder</option>
          </select>
        </div>
      </div>
      <div class="fi" style="margin-top:10px;">
        <label style="font-size:11px; font-weight:600; color: var(--sub,#7aaed4);">URL PATTERN *</label>
        <input type="text" name="pattern" required placeholder="https://labs.google/fx/tools/flow/project/xxx/tools?tab=GALLERY" value="<?php echo htmlspecialchars($editingUrlBlock['pattern'] ?? ''); ?>" style="width:100%; padding:9px 12px; font-size:12px; border-radius:6px; background:rgba(0,0,0,.3); border:1px solid rgba(255,170,0,.2); color:#fff; font-family: ui-monospace,monospace;" />
        <div style="font-size:10px; color: var(--muted,#4a7a9b); margin-top:4px;">
          💡 Wildcard mode: ganti project ID atau bagian dinamis dengan <code>xxx</code> atau <code>*</code><br>
          📍 Exact mode: paste URL exact, harus sama persis termasuk slash dan query parameter
        </div>
      </div>
      <div class="grid" style="display:grid; grid-template-columns: 1fr 1fr; gap:12px; margin-top:10px;">
        <div class="fi">
          <label style="font-size:11px; font-weight:600; color: var(--sub,#7aaed4);">REDIRECT URL (OPSIONAL)</label>
          <input type="text" name="redirect_url" placeholder="default: redirect ke /fx/tools/flow/project/<id>" value="<?php echo htmlspecialchars($editingUrlBlock['redirect_url'] ?? ''); ?>" style="width:100%; padding:9px 12px; font-size:12px; border-radius:6px; background:rgba(0,0,0,.3); border:1px solid rgba(255,170,0,.2); color:#fff;" />
          <div style="font-size:10px; color: var(--muted,#4a7a9b); margin-top:4px;">
            Kosongkan untuk auto-redirect ke project bare URL
          </div>
        </div>
        <div class="fi">
          <label style="font-size:11px; font-weight:600; color: var(--sub,#7aaed4);">PESAN (OPSIONAL)</label>
          <input type="text" name="message" placeholder="default: Halaman ini diblokir." value="<?php echo htmlspecialchars($editingUrlBlock['message'] ?? ''); ?>" style="width:100%; padding:9px 12px; font-size:12px; border-radius:6px; background:rgba(0,0,0,.3); border:1px solid rgba(255,170,0,.2); color:#fff;" />
        </div>
      </div>
      <div class="fi" style="margin-top:10px;">
        <label style="font-size:11px; font-weight:600; color: var(--sub,#7aaed4);">AKSES SERVER <span style="color:var(--muted,#4a7a9b); font-weight:400;">(centang server yang TERAPKAN block ini · kosong = semua server)</span></label>
        <div style="display:grid; grid-template-columns:repeat(auto-fill, minmax(180px, 1fr)); gap:6px; max-height:150px; overflow-y:auto; padding:10px; background:rgba(0,0,0,.2); border:1px solid rgba(255,170,0,.15); border-radius:6px;">
          <?php foreach ($tfServerList as $sname): ?>
            <label style="display:flex; align-items:center; gap:6px; cursor:pointer; font-size:11px; padding:5px 8px; border-radius:4px; background:rgba(0,0,0,.2); transition:background .15s;" onmouseover="this.style.background='rgba(255,170,0,.1)'" onmouseout="this.style.background='rgba(0,0,0,.2)'">
              <input type="checkbox" name="allowed_servers[]" value="<?php echo htmlspecialchars($sname); ?>" <?php echo in_array($sname, $urlBlockEditAllowed, true) ? 'checked' : ''; ?> />
              <span><?php echo htmlspecialchars($sname); ?></span>
            </label>
          <?php endforeach; ?>
        </div>
      </div>
      <div class="fi" style="display:flex; gap:8px; justify-content:flex-end; margin-top:10px;">
        <?php if ($editingUrlBlock): ?>
          <a href="?tab=apps#flow-url-blocks" class="btn" style="background:rgba(100,100,100,.2); border:1px solid #555; color:#aaa;">Batal Edit</a>
        <?php endif; ?>
        <button type="submit" class="btn bp" style="background:linear-gradient(135deg,#ff8a00,#ff4d4d); border:none; color:#fff;">
          <?php echo $editingUrlBlock ? '✓ Update Block' : '+ Tambah URL Block'; ?>
        </button>
      </div>
    </form>

    <!-- Rules list -->
    <?php if (empty($urlBlocksList)): ?>
      <div style="text-align:center; padding:30px 20px; color: var(--muted, #4a7a9b); font-size:12px; background:rgba(0,30,80,.2); border-radius:10px;">
        <div style="font-size:32px; margin-bottom:8px; opacity:.4;">🚫</div>
        <div>Belum ada URL Block. Tambah pattern di form di atas.</div>
      </div>
    <?php else: ?>
      <div style="display:flex; flex-direction:column; gap:8px;">
        <?php foreach ($urlBlocksList as $R):
          $rid = htmlspecialchars($R['id'] ?? '');
          $rname = htmlspecialchars($R['name'] ?? '(unnamed)');
          $rpattern = htmlspecialchars($R['pattern'] ?? '');
          $rmode = htmlspecialchars($R['mode'] ?? 'exact');
          $rredirect = htmlspecialchars($R['redirect_url'] ?? '');
          $ractive = !empty($R['is_active']);
          $rAllowed = isset($R['allowed_servers']) && is_array($R['allowed_servers']) ? $R['allowed_servers'] : [];
          $modeBadge = $rmode === 'wildcard' ? ['🌟 Wildcard', '#c084fc'] : ['🎯 Exact', '#4db8ff'];
        ?>
          <div style="background:rgba(0,30,80,.25); border:1px solid <?php echo $ractive ? 'rgba(255,170,0,.3)' : 'rgba(100,100,100,.3)'; ?>; border-radius:10px; padding:12px; display:flex; flex-wrap:wrap; gap:10px; align-items:center; opacity: <?php echo $ractive ? '1' : '.6'; ?>;">
            <div style="flex:1; min-width:280px;">
              <div style="display:flex; gap:8px; align-items:center; margin-bottom:4px; flex-wrap:wrap;">
                <span style="font-size:13px; font-weight:600; color:#fff;"><?php echo $rname; ?></span>
                <span style="font-size:9px; padding:2px 7px; border-radius:3px; background:rgba(<?php echo $modeBadge[1]==='#c084fc'?'124,58,237':'0,150,255'; ?>,.15); color:<?php echo $modeBadge[1]; ?>; border:1px solid <?php echo $modeBadge[1]; ?>55;"><?php echo $modeBadge[0]; ?></span>
                <span style="font-size:9px; padding:2px 7px; border-radius:3px; background:<?php echo $ractive ? 'rgba(0,230,118,.15)' : 'rgba(150,150,150,.15)'; ?>; color:<?php echo $ractive ? '#00e676' : '#999'; ?>; border:1px solid <?php echo $ractive ? 'rgba(0,230,118,.3)' : 'rgba(150,150,150,.3)'; ?>;">
                  <?php echo $ractive ? '✓ AKTIF' : '⏸ DISABLED'; ?>
                </span>
              </div>
              <div style="font-family: ui-monospace,monospace; font-size:11px; color:#ffcc44; word-break:break-all; line-height:1.4;"><?php echo $rpattern; ?></div>
              <?php if ($rredirect): ?>
                <div style="font-size:10px; color: var(--muted,#4a7a9b); margin-top:3px;">↪ Redirect: <code style="color:#7aaed4;"><?php echo $rredirect; ?></code></div>
              <?php endif; ?>
              <div style="display:flex; flex-wrap:wrap; gap:4px; margin-top:5px;">
                <?php if (empty($rAllowed)): ?>
                  <span style="font-size:9px; padding:2px 7px; background:rgba(0,230,118,.15); color:#00e676; border:1px solid rgba(0,230,118,.3); border-radius:3px;">📡 ALL SERVERS</span>
                <?php else: ?>
                  <?php foreach ($rAllowed as $sn): ?>
                    <span style="font-size:9px; padding:2px 7px; background:rgba(124,58,237,.15); color:#c084fc; border:1px solid rgba(124,58,237,.3); border-radius:3px;">📡 <?php echo htmlspecialchars($sn); ?></span>
                  <?php endforeach; ?>
                <?php endif; ?>
              </div>
            </div>
            <div style="display:flex; gap:6px; align-items:center;">
              <a href="?tab=apps&edit_flow_url_block=<?php echo urlencode($R['id'] ?? ''); ?>#flow-url-blocks" class="btn" style="padding:6px 10px; font-size:11px; background:rgba(0,150,255,.15); border:1px solid rgba(0,150,255,.3); color:#4db8ff;">✎ Edit</a>
              <form method="POST" style="margin:0;">
                <input type="hidden" name="action" value="toggle_flow_url_block" />
                <input type="hidden" name="fr_id" value="<?php echo $rid; ?>" />
                <button type="submit" class="btn" style="padding:6px 10px; font-size:11px; background:rgba(<?php echo $ractive?'255,170,0':'0,230,118'; ?>,.15); border:1px solid rgba(<?php echo $ractive?'255,170,0':'0,230,118'; ?>,.3); color:<?php echo $ractive?'#ffcc44':'#00e676'; ?>;"><?php echo $ractive ? '⏸ Pause' : '▶ Aktifkan'; ?></button>
              </form>
              <form method="POST" style="margin:0;" onsubmit="return confirm('Hapus URL Block ini?');">
                <input type="hidden" name="action" value="delete_flow_url_block" />
                <input type="hidden" name="fr_id" value="<?php echo $rid; ?>" />
                <button type="submit" class="btn" style="padding:6px 10px; font-size:11px; background:rgba(255,77,77,.15); border:1px solid rgba(255,77,77,.3); color:#ff8080;">🗑</button>
              </form>
            </div>
          </div>
        <?php endforeach; ?>
      </div>
    <?php endif; ?>
  </div>
</div>
<?php endif; ?>

<!-- DASHBOARD MITRA TAB -->
<?php if ($role === 'mitra'): ?>
<div id="tab-mitradashboard" class="tab-content <?php echo $tab==='mitradashboard'?'active':''; ?>">
  <div class="card">
    <div class="ct">Laporan Pendapatan Komisi</div>
    <div class="stats" style="grid-template-columns: repeat(4, 1fr);">
        <div class="sc t">
            <?php 
                $rate_config = $_SESSION['commission_rate'] ?? [];
                if (!is_array($rate_config)) {
                    $rate_config = ['basic' => (int)$rate_config, 'pro' => (int)$rate_config, 'ultimate' => (int)$rate_config];
                }
            ?>
            <div class="sv" style="font-size:14px; line-height:1.2;">
              B: Rp <?php echo number_format($rate_config['basic'] ?? 0, 0, ',', '.'); ?><br>
              P: Rp <?php echo number_format($rate_config['pro'] ?? 0, 0, ',', '.'); ?><br>
              U: Rp <?php echo number_format($rate_config['ultimate'] ?? 0, 0, ',', '.'); ?>
            </div>
            <div class="sl">Komisi per Transaksi</div>
        </div>
        <div class="sc e">
            <div class="sv">Rp <?php echo number_format($totalSales, 0, ',', '.'); ?></div>
            <div class="sl">Total Penjualan (Gross)</div>
        </div>
        <div class="sc a" style="background: linear-gradient(135deg, rgba(0,230,118,0.1), rgba(0,200,100,0.1)); border-color: rgba(0,230,118,0.3);">
            <div class="sv" style="color: #00e676; font-size: 20px;">Rp <?php echo number_format($totalRevenue, 0, ',', '.'); ?></div>
            <div class="sl" style="color: #00e676;">Total Komisi Didapat</div>
        </div>
        <div class="sc r">
            <div class="sv" style="color: var(--bright); font-size: 20px;">Rp <?php echo number_format($_SESSION['balance'] ?? 0, 0, ',', '.'); ?></div>
            <div class="sl" style="color: var(--bright);">Saldo Tersedia</div>
        </div>
    </div>
    
    <div style="margin-top:20px; padding-top:20px; border-top:1px solid var(--border);">
        <h3 style="font-size:14px; margin-bottom:10px; color:var(--light);">Tarik Saldo (Withdraw)</h3>
        <p style="font-size:11px; color:var(--muted); margin-bottom:15px;">Fitur penarikan saldo saat ini sedang dalam tahap pengembangan (Coming Soon). Total saldo di atas dihitung berdasarkan seluruh member aktif yang Anda daftarkan.</p>
        <button class="btn bp" disabled style="opacity:0.5; cursor:not-allowed;">Request Penarikan</button>
    </div>
  </div>
  
  <div class="card" style="border-color: rgba(255,170,0,0.3); box-shadow: 0 0 20px rgba(255,170,0,0.1);">
    <div class="ct" style="color: #ffaa00;">🎟️ Buat Voucher Trial Khusus</div>
    <p style="font-size:12px; color:var(--muted); margin-bottom:15px;">Buat voucher trial (uji coba) gratis selama <strong>2 hari</strong> untuk calon client Anda. Transaksi ini akan tercatat dengan kepemilikan (konteks) Mitra Anda dan tidak akan memotong saldo komisi Anda.</p>
    
    <form method="POST">
        <input type="hidden" name="action" value="add_trial" />
        <div class="fg" style="margin-bottom:0;">
            <div class="fi full">
                <label style="color:#ffaa00;">Nama Client / Calon Pembeli (Opsional)</label>
                <input type="text" name="name" placeholder="Biarkan kosong untuk auto-generate nama Trial Acak" style="border-color: rgba(255,170,0,0.3);" />
            </div>
            <div class="fi full" style="display:flex; justify-content:flex-end;">
                <button type="submit" class="btn bp" style="background: linear-gradient(135deg, #cc8800, #ffaa00); color:#000; font-weight:800; border:none; box-shadow:0 4px 15px rgba(255,170,0,0.3);">⚡ Generate Voucher Trial (2 Hari)</button>
            </div>
        </div>
    </form>
  </div>

</div>
<?php endif; ?>

<!-- INJECT COOKIES TAB -->
<div id="tab-cookies" class="tab-content <?php echo $tab==='cookies'?'active':''; ?>">
  <div class="card">
    <div class="ct">Inject Cookies Server</div>
    <div id="c-form">
      <div class="fg">
        <div class="fi">
          <label>Pilih Aplikasi</label>
          <select id="c-app" required>
            <option value="">-- Pilih Aplikasi --</option>
            <?php foreach ($APP_LABELS as $aid => $lbl): ?>
              <option value="<?php echo $aid; ?>"><?php echo $lbl; ?></option>
            <?php endforeach; ?>
          </select>
        </div>
        <div class="fi">
          <label>Pilih Server</label>
          <select id="c-server" required>
            <option value="">-- Pilih Server --</option>
          </select>
        </div>
        <div class="fi full" style="margin-top:10px;">
          <label>URL Tujuan Aplikasi (Opsional)</label>
          <input type="url" id="c-url" placeholder="Biarkan kosong jika tetap memakai URL bawaan" style="width:100%;box-sizing:border-box;margin-bottom:10px;">
          
          <div style="display:flex; justify-content:space-between; align-items:center; margin-bottom:10px;">
            <label style="margin:0;">Paste JSON Payload (J2TEAM / EditThisCookie)</label>
            <button type="button" class="btn" style="padding:4px 10px; font-size:11px; background:var(--glass); color:var(--light); border:1px solid var(--border);" onclick="addCookiePayloadField()">+ Tambah Payload Cookies</button>
          </div>
          
          <div id="cookie-payloads-container" style="display:flex; flex-direction:column; gap:10px;">
            <div class="cookie-payload-group" style="position:relative;">
                <div style="font-size:10px; color:var(--light); margin-bottom:4px; font-weight:bold;">Payload 1</div>
                <textarea class="c-data-input" placeholder='[{"name":"session_id","value":"xyz","domain":".google.com",...}]' required></textarea>
                <button type="button" onclick="this.parentElement.remove(); updatePayloadLabels();" style="position:absolute; top:0; right:0; background:none; border:none; color:var(--err); cursor:pointer; font-size:12px; font-weight:bold;">✕ Hapus</button>
            </div>
          </div>
        </div>
        <div class="fi full">
           <div id="c-info" style="font-size:11.5px; margin-top:5px; margin-bottom:5px; background: rgba(255,255,255,0.05); padding: 8px; border-radius: 6px; display: none;"></div>
           <div id="c-msg" style="font-size:12px;font-weight:bold;margin-top:5px;margin-bottom:5px;"></div>
        </div>
        <div class="fi full" style="display:flex;justify-content:flex-end;margin-top:4px">
          <button type="button" class="btn bp" id="c-submit-btn" onclick="saveC()">&#x1F4BE; Simpan & Inject Sessions</button>
        </div>
      </div>
    </div>
  </div>
</div>

<!-- PACKAGES CONFIG TAB -->
<div id="tab-packages" class="tab-content <?php echo $tab==='packages'?'active':''; ?>">
  <div class="card">
    <div class="ct">Konfigurasi Paket Akses Aplikasi</div>
    <div style="font-size:12px; color:var(--muted); margin-bottom: 20px;">Atur aplikasi apa saja dan berapa jumlah server yang didapatkan untuk masing-masing paket (Basic, Pro, Ultimate). Konfigurasi ini dapat dibedakan antara Server Asli dan masing-masing Mitra.</div>
    
    <div class="fg" style="margin-bottom: 20px; padding: 15px; background: rgba(0,100,255,0.05); border: 1px solid rgba(0,150,255,0.2); border-radius: 8px;">
      <div class="fi full" style="margin: 0;">
        <label style="color: var(--bright); font-weight: bold; margin-bottom: 8px; display: block;">Pilih Target Pengaturan</label>
        <select id="pkg_target" onchange="loadPkgConfig(this.value)" style="width: 100%; max-width: 400px; padding: 10px; font-size: 14px; background: var(--deep); border: 1px solid var(--border); color: var(--text); border-radius: 6px;">
          <option value="main" <?php echo (!isset($_GET['target']) || $_GET['target'] === 'main') ? 'selected' : ''; ?>>Server Asli (Default)</option>
          <?php
          $users = loadData('users.json');
          $currentTarget = $_GET['target'] ?? 'main';
          foreach ($users as $u) {
              if ($u['role'] === 'mitra') {
                  $val = 'mitra_' . $u['id'];
                  $sel = ($currentTarget === $val) ? 'selected' : '';
                  echo '<option value="' . $val . '" ' . $sel . '>Mitra: ' . htmlspecialchars($u['name']) . '</option>';
              }
          }
          
          // Get specific prices for this target
          $target_prices = $PACKAGES_CONFIG[$currentTarget . '_prices'] ?? $pkg_prices;
          ?>
        </select>
      </div>
    </div>

    <form method="POST">
      <input type="hidden" name="action" value="save_packages">
      <input type="hidden" name="target_id" id="pkg_form_target" value="<?php echo htmlspecialchars($currentTarget); ?>">
      
      <div style="display: grid; grid-template-columns: repeat(auto-fit, minmax(280px, 1fr)); gap: 20px;">
        
        <?php foreach (['basic' => 'Basic', 'pro' => 'Pro', 'ultimate' => 'Ultimate', 'trial' => 'Trial (Uji Coba)'] as $pkgKey => $pkgName): ?>
        <div style="background: var(--glass); border: 1px solid var(--border); border-radius: 12px; padding: 15px;">
          <h3 style="margin-top: 0; color: #00e676; text-align: center; padding-bottom: 10px; border-bottom: 1px dashed rgba(255,255,255,0.1);"><?php echo $pkgName; ?></h3>
          
          <div style="margin-bottom: 15px; padding-bottom: 10px; border-bottom: 1px dashed rgba(255,255,255,0.1);">
            <label style="font-size: 11px; color: var(--bright); display: block; margin-bottom: 4px;">Harga Paket (Rp)</label>
            <input type="number" id="pkg_price_<?php echo $pkgKey; ?>" name="price_<?php echo $pkgKey; ?>" value="<?php echo htmlspecialchars($target_prices[$pkgKey] ?? 0); ?>" placeholder="0" style="width: 100%; padding: 8px; background: rgba(0,0,0,0.2); border: 1px solid var(--border); border-radius: 6px; color: #00e676; font-weight: bold;">
          </div>
          
          <div style="max-height: 400px; overflow-y: auto; padding-right: 5px;">
            <?php foreach ($allAppsForAdmin as $app): if (!$app['is_active']) continue; ?>
            <div style="display: flex; align-items: center; justify-content: space-between; padding: 8px 0; border-bottom: 1px solid rgba(255,255,255,0.05);">
              <div style="display: flex; align-items: center; gap: 8px;">
                <input type="checkbox" id="pkg_<?php echo $pkgKey; ?>_<?php echo $app['id']; ?>" name="pkg[<?php echo $pkgKey; ?>][<?php echo $app['id']; ?>][checked]" value="1">
                <label for="pkg_<?php echo $pkgKey; ?>_<?php echo $app['id']; ?>" style="font-size: 13px; cursor: pointer;"><?php echo htmlspecialchars($app['name']); ?></label>
              </div>
              <div style="display: flex; align-items: center; gap: 5px;">
                <label style="font-size: 10px; color: var(--muted);">Srv:</label>
                <input type="number" id="pkg_<?php echo $pkgKey; ?>_<?php echo $app['id']; ?>_srv" name="pkg[<?php echo $pkgKey; ?>][<?php echo $app['id']; ?>][srv]" min="1" value="1" style="width: 50px; padding: 4px; text-align: center; margin: 0;">
              </div>
            </div>
            <?php endforeach; ?>
          </div>
        </div>
        <?php endforeach; ?>
        
      </div>
      
      <div style="margin-top: 25px; text-align: right;">
        <button type="submit" class="btn bp" style="padding: 12px 30px; font-size: 14px; font-weight: bold;">&#x1F4BE; Simpan Konfigurasi Paket & Harga</button>
      </div>
    </form>
  </div>
</div>

<script>
const MITRA_ID_FOR_JS = <?php echo json_encode($_SESSION['admin_role'] === 'mitra' ? $_SESSION['user_id'] : null); ?>;
const PACKAGES_CONFIG = <?php echo json_encode($PACKAGES_CONFIG); ?>;
const ACTIVE_APPS = <?php echo json_encode(array_values(array_filter($allAppsForAdmin, function($a){return $a['is_active'];}))); ?>;

function loadPkgConfig(target) {
    document.getElementById('pkg_form_target').value = target;
    const config = PACKAGES_CONFIG[target] || PACKAGES_CONFIG['main'] || {};
    
    // Default prices are stored globally in PHP, but let's see if we can get them dynamically
    // For now, we will reload the page to get the correct prices from PHP for this target
    // Instead of doing full AJAX, we can just redirect if the target changes
    const currentUrl = new URL(window.location.href);
    // Only redirect if we are explicitly changing the target via the dropdown
    // and it differs from what's currently in the URL (or default 'main' if not in URL)
    const urlTarget = currentUrl.searchParams.get('target') || 'main';
    if (urlTarget !== target) {
        currentUrl.searchParams.set('target', target);
        currentUrl.searchParams.set('tab', 'packages');
        window.location.href = currentUrl.toString();
        return;
    }
    
    ['basic', 'pro', 'ultimate'].forEach(pkg => {
        const pkgData = config[pkg] || {};
        ACTIVE_APPS.forEach(app => {
            const chk = document.getElementById(`pkg_${pkg}_${app.id}`);
            const srv = document.getElementById(`pkg_${pkg}_${app.id}_srv`);
            if (chk) {
                if (pkgData[app.id]) {
                    chk.checked = true;
                    if (srv) srv.value = pkgData[app.id];
                } else {
                    chk.checked = false;
                    if (srv) srv.value = 1;
                }
            }
        });
    });
}

// Initial load for packages tab
window.addEventListener('load', () => {
    const urlParams = new URLSearchParams(window.location.search);
    const target = urlParams.get('target') || 'main';
    const selectEl = document.getElementById('pkg_target');
    if (selectEl && selectEl.value !== target) {
        selectEl.value = target;
    }
    // Call this to initialize checkboxes (will not redirect because target matches URL)
    loadPkgConfig(target);
});
</script>

<?php if ($role === 'owner' || !empty($user_perms['tab_settings'])): ?>
<!-- SETTINGS TAB -->
<div id="tab-settings" class="tab-content <?php echo $tab==='settings'?'active':''; ?>">
  <!-- Theme Manager Quick-Link -->
  <div class="card" style="background: linear-gradient(135deg, rgba(0,170,85,.12), rgba(77,184,255,.08)); border-color: rgba(77,184,255,.3); margin-bottom: 18px;">
    <div class="ct" style="display:flex; align-items:center; gap:8px;">
      🎨 Pengaturan Tema (Rainy Window FX)
      <span style="font-size:10px; padding:3px 8px; background:rgba(77,184,255,.2); color:#4db8ff; border:1px solid rgba(77,184,255,.4); border-radius:4px; font-weight:500;">Admin Only</span>
    </div>
    <p style="font-size:12px; color: var(--sub, #7aaed4); margin: 8px 0 14px; line-height: 1.6;">
      Kelola background, blur, brightness, intensitas hujan, hue, suara ambient, dan tampilan widget glassmorph untuk halaman <code style="background:rgba(0,0,0,.3); padding:1px 6px; border-radius:3px;">remote_app.php</code> yang dilihat user. Pengaturan akan langsung apply ke semua user setelah disimpan.
    </p>
    <div style="display:flex; gap:10px; flex-wrap:wrap;">
      <a href="theme_admin.php" class="btn bp" style="padding:10px 20px; background:linear-gradient(135deg,#0066ff,#0099ff); border:none; color:#fff; text-decoration:none; font-weight:700;">⚙️ Buka Panel Tema</a>
      <a href="remote_app.php" target="_blank" class="btn" style="padding:10px 20px; background:rgba(0,230,118,.12); border:1px solid rgba(0,230,118,.3); color:#00e676; text-decoration:none; font-weight:600;">🚀 Lihat Halaman User</a>
    </div>
  </div>
  <div class="card">
    <div class="ct">Pengaturan Ekstensi & Harga Paket</div>
    <?php
      if ($_SERVER['REQUEST_METHOD'] === 'POST' && isset($_POST['action']) && $_POST['action'] === 'save_settings') {
          $settings['catalog_url'] = trim($_POST['catalog_url'] ?? '');
          
          // Pengaturan Branding Halaman Login
          $settings['login_logo_url'] = trim($_POST['login_logo_url'] ?? 'https://test.texaproject.com/inject/app_icons/default.png');
          $settings['login_brand_name'] = trim($_POST['login_brand_name'] ?? 'TEKNO-APPS');
          $settings['login_brand_subtitle'] = trim($_POST['login_brand_subtitle'] ?? 'Premium AI Workflow Suite');
          $settings['login_catalog_text'] = trim($_POST['login_catalog_text'] ?? 'Full Katalog AI Tools');
          $settings['login_input_label'] = trim($_POST['login_input_label'] ?? 'Access Code');
          $settings['login_input_placeholder'] = trim($_POST['login_input_placeholder'] ?? 'Enter access code...');
          $settings['login_error_text'] = trim($_POST['login_error_text'] ?? 'Kode akses tidak valid.');
          $settings['login_btn_text'] = trim($_POST['login_btn_text'] ?? 'Masuk');
          $settings['login_takeover_text'] = trim($_POST['login_takeover_text'] ?? 'Ambil Alih Sesi');
          $settings['login_footer_text'] = trim($_POST['login_footer_text'] ?? 'TEXA.STUDIO © 2026 copyright.');
          $settings['login_page_title'] = trim($_POST['login_page_title'] ?? 'TEKNO-APPS');
          $settings['login_dash_name'] = trim($_POST['login_dash_name'] ?? 'TEKNO-APPS');
          $settings['mitra_lockout_minutes'] = (int)($_POST['mitra_lockout_minutes'] ?? 15);
          $settings['mitra_max_attempts'] = (int)($_POST['mitra_max_attempts'] ?? 5);
          $settings['mitra_wa_group'] = trim($_POST['mitra_wa_group'] ?? '');
          $settings['desktop_grid_columns'] = (int)($_POST['desktop_grid_columns'] ?? 4);
          // Harga paket disimpan ke packages.json (main_prices) sebagai sumber tunggal
          $new_prices = [
              'basic' => (int)($_POST['price_basic'] ?? 50000),
              'pro' => (int)($_POST['price_pro'] ?? 100000),
              'ultimate' => (int)($_POST['price_ultimate'] ?? 150000),
              'custom' => (int)($_POST['price_custom'] ?? 0),
          ];
          $settings['pkg_prices'] = $new_prices; // backward compat
          
          // Juga simpan ke packages.json main_prices
          $allPkgData = loadData('packages.json');
          $allPkgData['main_prices'] = $new_prices;
          saveData('packages.json', $allPkgData);
          $settings['refund_admin_fee_percent'] = (int)($_POST['refund_admin_fee_percent'] ?? 25);
          $settings['mitra_trial_enabled'] = isset($_POST['mitra_trial_enabled']) ? 1 : 0;
          $settings['mitra_trial_days'] = (int)($_POST['mitra_trial_days'] ?? 2);
          $settings['kick_logo'] = trim($_POST['kick_logo'] ?? '⚠️');
          $settings['kick_title'] = trim($_POST['kick_title'] ?? 'Sesi Berakhir.!!!');
          $settings['kick_desc1'] = trim($_POST['kick_desc1'] ?? 'tunggu admin TEXA refresh server.');
          $settings['kick_desc2'] = trim($_POST['kick_desc2'] ?? 'Cek secara berkala dan pastikan report ke grup WA. Terimakasih!');
          $settings['kick_wa_btn'] = trim($_POST['kick_wa_btn'] ?? 'Whatssap GRUP');
          $settings['kick_wa_link'] = trim($_POST['kick_wa_link'] ?? 'https://chat.whatsapp.com/FAg698uVEZOAbOpVLG0FhC');
          $settings['kick_close_btn'] = trim($_POST['kick_close_btn'] ?? 'Tutup & Kembali');

          // Pengaturan Kick Out Khusus Member Mitra
          $settings['mitra_kick_logo'] = trim($_POST['mitra_kick_logo'] ?? '⚠️');
          $settings['mitra_kick_title'] = trim($_POST['mitra_kick_title'] ?? 'Sesi Berakhir.!!!');
          $settings['mitra_kick_desc1'] = trim($_POST['mitra_kick_desc1'] ?? 'tunggu admin Mitra refresh server.');
          $settings['mitra_kick_desc2'] = trim($_POST['mitra_kick_desc2'] ?? 'Cek secara berkala dan pastikan report ke grup WA Mitra. Terimakasih!');
          $settings['mitra_kick_wa_btn'] = trim($_POST['mitra_kick_wa_btn'] ?? 'Whatssap Mitra');
          $settings['mitra_kick_wa_link'] = trim($_POST['mitra_kick_wa_link'] ?? 'https://chat.whatsapp.com/');
          $settings['mitra_kick_close_btn'] = trim($_POST['mitra_kick_close_btn'] ?? 'Tutup & Kembali');

          // Pengaturan Notifikasi Expiry (Masa Aktif H-3)
          $settings['exp_trigger_days'] = (int)($_POST['exp_trigger_days'] ?? 3);
          $settings['exp_logo'] = trim($_POST['exp_logo'] ?? '⏳');
          $settings['exp_title'] = trim($_POST['exp_title'] ?? 'Masa Aktif Hampir Habis!');
          $settings['exp_text'] = trim($_POST['exp_text'] ?? 'Masa aktif voucher Anda tersisa {hari} hari lagi. Segera perpanjang agar akses tidak terputus.');
          $settings['exp_btn_text'] = trim($_POST['exp_btn_text'] ?? 'Perpanjang Sekarang');
          $settings['exp_btn_link'] = trim($_POST['exp_btn_link'] ?? 'https://wa.me/628xxx');

          $settings['mitra_exp_logo'] = trim($_POST['mitra_exp_logo'] ?? '⏳');
          $settings['mitra_exp_title'] = trim($_POST['mitra_exp_title'] ?? 'Masa Aktif Hampir Habis!');
          $settings['mitra_exp_text'] = trim($_POST['mitra_exp_text'] ?? 'Masa aktif voucher Mitra Anda tersisa {hari} hari lagi. Segera hubungi Mitra Anda.');
          $settings['mitra_exp_btn_text'] = trim($_POST['mitra_exp_btn_text'] ?? 'Hubungi Mitra');
          $settings['mitra_exp_btn_link'] = trim($_POST['mitra_exp_btn_link'] ?? 'https://wa.me/628yyy');

          // ========== PROMO POPUP SETTINGS ==========
          $settings['promo_active'] = !empty($_POST['promo_active']) ? 1 : 0;
          $settings['promo_video_url'] = trim($_POST['promo_video_url'] ?? '');
          $settings['promo_title'] = trim($_POST['promo_title'] ?? '');
          $settings['promo_desc'] = trim($_POST['promo_desc'] ?? '');
          $settings['promo_btn_text'] = trim($_POST['promo_btn_text'] ?? '');
          $promo_btn_link = trim($_POST['promo_btn_link'] ?? '');
          $promo_auto_slug = !empty($_POST['promo_auto_slug']) ? 1 : 0;
          $settings['promo_auto_slug'] = $promo_auto_slug;
          if ($promo_auto_slug && !empty($promo_btn_link) && strpos($promo_btn_link, 'http') !== 0) {
              $_proto = (!empty($_SERVER['HTTPS']) && $_SERVER['HTTPS'] !== 'off') ? 'https' : 'http';
              $_hst = $_SERVER['HTTP_HOST'] ?? 'localhost';
              $promo_btn_link = $_proto . '://' . $_hst . '/' . ltrim($promo_btn_link, '/');
          }
          $settings['promo_btn_link'] = $promo_btn_link;

          // Mitra Promo Popup
          $settings['mitra_promo_active'] = !empty($_POST['mitra_promo_active']) ? 1 : 0;
          $settings['mitra_promo_video_url'] = trim($_POST['mitra_promo_video_url'] ?? '');
          $settings['mitra_promo_title'] = trim($_POST['mitra_promo_title'] ?? '');
          $settings['mitra_promo_desc'] = trim($_POST['mitra_promo_desc'] ?? '');
          $settings['mitra_promo_btn_text'] = trim($_POST['mitra_promo_btn_text'] ?? '');
          $mitra_promo_btn_link = trim($_POST['mitra_promo_btn_link'] ?? '');
          $mitra_promo_auto_slug = !empty($_POST['mitra_promo_auto_slug']) ? 1 : 0;
          $settings['mitra_promo_auto_slug'] = $mitra_promo_auto_slug;
          if ($mitra_promo_auto_slug && !empty($mitra_promo_btn_link) && strpos($mitra_promo_btn_link, 'http') !== 0) {
              $_proto = (!empty($_SERVER['HTTPS']) && $_SERVER['HTTPS'] !== 'off') ? 'https' : 'http';
              $_hst = $_SERVER['HTTP_HOST'] ?? 'localhost';
              $mitra_promo_btn_link = $_proto . '://' . $_hst . '/' . ltrim($mitra_promo_btn_link, '/');
          }
          $settings['mitra_promo_btn_link'] = $mitra_promo_btn_link;

          // ========== EXTENSION VERSION UPDATE SETTINGS ==========
          $settings['ext_update_active'] = !empty($_POST['ext_update_active']) ? 1 : 0;
          // Hanya update manual jika auto-detect TIDAK aktif
          $ev_file_check = DATA_DIR . '/ext_version.json';
          if (!file_exists($ev_file_check)) {
              $settings['ext_latest_version'] = trim($_POST['ext_latest_version'] ?? '1.0.0');
          }
          $settings['ext_update_title']    = trim($_POST['ext_update_title']    ?? '');
          $settings['ext_update_desc']     = trim($_POST['ext_update_desc']     ?? '');
          $settings['ext_update_btn_text'] = trim($_POST['ext_update_btn_text'] ?? '');
          $settings['ext_update_btn_link'] = trim($_POST['ext_update_btn_link'] ?? '');

          // Check if Mitra UI settings are selected for a specific mitra
          $target_mitra_ui = $_POST['target_mitra_ui'] ?? 'all';
          if ($target_mitra_ui !== 'all') {
              if (!isset($settings['mitra_ui'])) $settings['mitra_ui'] = [];
              if (!isset($settings['mitra_ui'][$target_mitra_ui])) $settings['mitra_ui'][$target_mitra_ui] = [];
              
              $settings['mitra_ui'][$target_mitra_ui]['mitra_kick_logo'] = $settings['mitra_kick_logo'];
              $settings['mitra_ui'][$target_mitra_ui]['mitra_kick_title'] = $settings['mitra_kick_title'];
              $settings['mitra_ui'][$target_mitra_ui]['mitra_kick_desc1'] = $settings['mitra_kick_desc1'];
              $settings['mitra_ui'][$target_mitra_ui]['mitra_kick_desc2'] = $settings['mitra_kick_desc2'];
              $settings['mitra_ui'][$target_mitra_ui]['mitra_kick_wa_btn'] = $settings['mitra_kick_wa_btn'];
              $settings['mitra_ui'][$target_mitra_ui]['mitra_kick_wa_link'] = $settings['mitra_kick_wa_link'];
              $settings['mitra_ui'][$target_mitra_ui]['mitra_kick_close_btn'] = $settings['mitra_kick_close_btn'];
              
              $settings['mitra_ui'][$target_mitra_ui]['mitra_exp_logo'] = $settings['mitra_exp_logo'];
              $settings['mitra_ui'][$target_mitra_ui]['mitra_exp_title'] = $settings['mitra_exp_title'];
              $settings['mitra_ui'][$target_mitra_ui]['mitra_exp_text'] = $settings['mitra_exp_text'];
              $settings['mitra_ui'][$target_mitra_ui]['mitra_exp_btn_text'] = $settings['mitra_exp_btn_text'];
              $settings['mitra_ui'][$target_mitra_ui]['mitra_exp_btn_link'] = $settings['mitra_exp_btn_link'];
              
              // We restore the original global settings so they don't get overwritten
              $orig_settings = loadData('settings.json');
              $settings['mitra_kick_logo'] = $orig_settings['mitra_kick_logo'] ?? '⚠️';
              $settings['mitra_kick_title'] = $orig_settings['mitra_kick_title'] ?? 'Sesi Berakhir.!!!';
              $settings['mitra_kick_desc1'] = $orig_settings['mitra_kick_desc1'] ?? 'tunggu admin Mitra refresh server.';
              $settings['mitra_kick_desc2'] = $orig_settings['mitra_kick_desc2'] ?? 'Cek secara berkala dan pastikan report ke grup WA Mitra. Terimakasih!';
              $settings['mitra_kick_wa_btn'] = $orig_settings['mitra_kick_wa_btn'] ?? 'Whatssap Mitra';
              $settings['mitra_kick_wa_link'] = $orig_settings['mitra_kick_wa_link'] ?? 'https://chat.whatsapp.com/';
              $settings['mitra_kick_close_btn'] = $orig_settings['mitra_kick_close_btn'] ?? 'Tutup & Kembali';
              
              $settings['mitra_exp_logo'] = $orig_settings['mitra_exp_logo'] ?? '⏳';
              $settings['mitra_exp_title'] = $orig_settings['mitra_exp_title'] ?? 'Masa Aktif Hampir Habis!';
              $settings['mitra_exp_text'] = $orig_settings['mitra_exp_text'] ?? 'Masa aktif voucher Mitra Anda tersisa {hari} hari lagi. Segera hubungi Mitra Anda.';
              $settings['mitra_exp_btn_text'] = $orig_settings['mitra_exp_btn_text'] ?? 'Hubungi Mitra';
              $settings['mitra_exp_btn_link'] = $orig_settings['mitra_exp_btn_link'] ?? 'https://wa.me/628yyy';
          }

          saveData('settings.json', $settings);
          // Reload pkg_prices setelah save agar input menampilkan data terbaru dari packages.json
    $allPkgDataReload = loadData('packages.json');
    $pkg_prices = $allPkgDataReload['main_prices'] ?? $settings['pkg_prices'] ?? $pkg_prices;
          $_SESSION['flash_msg'] = 'Pengaturan berhasil disimpan.';
          $_SESSION['flash_msgType'] = 'success';
          header("Location: ?tab=settings");
          exit();
      }
    ?>
    <form method="POST">
      <input type="hidden" name="action" value="save_settings"/>
      <div class="fg">
        <div class="fi full" style="margin-bottom: 15px; border-bottom: 1px solid var(--border); padding-bottom: 15px;">
          <label style="font-size: 12px; color: var(--bright); margin-bottom: 8px; display: block;">&#128181; Pengaturan Harga Paket</label>
          <div style="display:flex; gap:10px; flex-wrap: wrap;">
            <div style="flex:1; min-width: 150px;">
              <label>Harga Paket Basic (Rp)</label>
              <input type="number" name="price_basic" value="<?php echo htmlspecialchars($pkg_prices['basic'] ?? 50000); ?>" placeholder="50000" />
            </div>
            <div style="flex:1; min-width: 150px;">
              <label>Harga Paket Pro (Rp)</label>
              <input type="number" name="price_pro" value="<?php echo htmlspecialchars($pkg_prices['pro'] ?? 100000); ?>" placeholder="100000" />
            </div>
            <div style="flex:1; min-width: 150px;">
              <label>Harga Paket Ultimate (Rp)</label>
              <input type="number" name="price_ultimate" value="<?php echo htmlspecialchars($pkg_prices['ultimate'] ?? 150000); ?>" placeholder="150000" />
            </div>
            <div style="flex:1; min-width: 150px;">
              <label>Harga Paket Custom (Rp)</label>
              <input type="number" name="price_custom" value="<?php echo htmlspecialchars($pkg_prices['custom'] ?? 0); ?>" placeholder="0" />
            </div>
          </div>
          <p style="font-size:10px;color:var(--muted);margin-top:8px;">Harga ini <strong>tersinkronisasi otomatis</strong> dengan tab "Konfigurasi Paket" (Server Asli). Untuk harga per-Mitra, atur di tab Konfigurasi Paket.</p>
          
          <div style="margin-top: 15px; padding-top: 15px; border-top: 1px dashed rgba(255,255,255,0.1);">
            <label style="display:block; margin-bottom:8px;">Potongan Biaya Admin Refund (%)</label>
            <input type="number" name="refund_admin_fee_percent" value="<?php echo htmlspecialchars($settings['refund_admin_fee_percent'] ?? 25); ?>" placeholder="25" min="0" max="100" style="max-width: 200px;" />
            <p style="font-size:10px;color:var(--muted);margin-top:4px;">Persentase potongan yang dikenakan saat member melakukan refund pengembalian dana.</p>
          </div>
        </div>



        <div class="fi full" style="margin-bottom: 15px; border-bottom: 1px solid var(--border); padding-bottom: 15px;">
          <label style="font-size: 12px; color: var(--bright); margin-bottom: 8px; display: block;">&#128272; Keamanan & Portal Mitra</label>
          <div style="display:flex; gap:10px; flex-wrap: wrap;">
            <div style="flex:1; min-width: 150px;">
              <label>Maksimal Gagal Login (Kali)</label>
              <input type="number" name="mitra_max_attempts" value="<?php echo htmlspecialchars($settings['mitra_max_attempts'] ?? 5); ?>" placeholder="5" min="1" />
            </div>
            <div style="flex:1; min-width: 150px;">
              <label>Durasi Blokir / Lockout (Menit)</label>
              <input type="number" name="mitra_lockout_minutes" value="<?php echo htmlspecialchars($settings['mitra_lockout_minutes'] ?? 15); ?>" placeholder="15" min="1" />
            </div>
          </div>
          <div style="margin-top: 10px;">
            <label>Link Join Grup WhatsApp Mitra</label>
            <input type="url" name="mitra_wa_group" value="<?php echo htmlspecialchars($settings['mitra_wa_group'] ?? ''); ?>" placeholder="https://chat.whatsapp.com/..." />
            <p style="font-size:10px;color:var(--muted);margin-top:4px;">Link ini akan muncul di halaman login portal mitra. Biarkan kosong jika tidak ada grup.</p>
          </div>
          <div style="margin-top: 15px; padding-top: 15px; border-top: 1px dashed rgba(255,255,255,0.1);">
            <label style="font-size: 12px; color: var(--custom); margin-bottom: 8px; display: block;">&#127915; Fitur Voucher Trial Khusus</label>
            <div style="display:flex; gap:10px; align-items:center;">
                <label style="font-size: 12px; cursor: pointer;">
                    <input type="checkbox" name="mitra_trial_enabled" value="1" <?php echo !isset($settings['mitra_trial_enabled']) || $settings['mitra_trial_enabled'] ? 'checked' : ''; ?> />
                    Aktifkan Fitur Pembuatan Voucher Trial untuk Mitra
                </label>
            </div>
            <div style="margin-top: 10px;">
                <label>Durasi Masa Aktif Trial (Hari)</label>
                <input type="number" name="mitra_trial_days" value="<?php echo htmlspecialchars($settings['mitra_trial_days'] ?? 2); ?>" placeholder="2" min="1" style="max-width: 150px;" />
            </div>
          </div>
        </div>

        <div class="fi full" style="margin-bottom: 15px; border-bottom: 1px solid var(--border); padding-bottom: 15px;">
          <label style="font-size: 12px; color: var(--bright); margin-bottom: 8px; display: block;">&#127912; Branding Halaman Login & Dashboard</label>
          <p style="font-size:10px;color:var(--muted);margin-bottom:12px;">Kustomisasi tampilan halaman login dan dashboard App Launcher. Perubahan langsung berlaku setelah simpan.</p>
          
          <div style="display:flex; gap:10px; flex-wrap: wrap; margin-bottom: 10px;">
            <div style="flex:2; min-width: 250px;">
              <label>URL Logo (Gambar)</label>
              <input type="url" name="login_logo_url" value="<?php echo htmlspecialchars($settings['login_logo_url'] ?? 'https://test.texaproject.com/inject/app_icons/default.png'); ?>" placeholder="https://test.texaproject.com/inject/app_icons/default.png" />
              <p style="font-size:10px;color:var(--muted);margin-top:4px;">URL gambar logo. Upload ke app_icons/ atau gunakan URL eksternal. Disarankan ukuran 80x80px PNG/WebP.</p>
            </div>
            <div style="flex:1; min-width: 150px;">
              <label>Judul Halaman (Tab Browser)</label>
              <input type="text" name="login_page_title" value="<?php echo htmlspecialchars($settings['login_page_title'] ?? 'TEKNO-APPS'); ?>" placeholder="TEKNO-APPS" />
            </div>
          </div>

          <div style="display:flex; gap:10px; flex-wrap: wrap; margin-bottom: 10px;">
            <div style="flex:1; min-width: 200px;">
              <label>Nama Brand (Heading)</label>
              <input type="text" name="login_brand_name" value="<?php echo htmlspecialchars($settings['login_brand_name'] ?? 'TEKNO-APPS'); ?>" placeholder="TEKNO-APPS" />
            </div>
            <div style="flex:1; min-width: 200px;">
              <label>Subtitle Brand</label>
              <input type="text" name="login_brand_subtitle" value="<?php echo htmlspecialchars($settings['login_brand_subtitle'] ?? 'Premium AI Workflow Suite'); ?>" placeholder="Premium AI Workflow Suite" />
            </div>
          </div>

          <div style="display:flex; gap:10px; flex-wrap: wrap; margin-bottom: 10px;">
            <div style="flex:1; min-width: 200px;">
              <label>Nama Dashboard Header</label>
              <input type="text" name="login_dash_name" value="<?php echo htmlspecialchars($settings['login_dash_name'] ?? 'TEKNO-APPS'); ?>" placeholder="TEKNO-APPS" />
              <p style="font-size:10px;color:var(--muted);margin-top:4px;">Text logo di header dashboard setelah login.</p>
            </div>
            <div style="flex:1; min-width: 200px;">
              <label>Teks Tombol Katalog</label>
              <input type="text" name="login_catalog_text" value="<?php echo htmlspecialchars($settings['login_catalog_text'] ?? 'Full Katalog AI Tools'); ?>" placeholder="Full Katalog AI Tools" />
            </div>
          </div>

          <div style="display:flex; gap:10px; flex-wrap: wrap; margin-bottom: 10px;">
            <div style="flex:1; min-width: 150px;">
              <label>Label Input Code</label>
              <input type="text" name="login_input_label" value="<?php echo htmlspecialchars($settings['login_input_label'] ?? 'Access Code'); ?>" placeholder="Access Code" />
            </div>
            <div style="flex:1; min-width: 200px;">
              <label>Placeholder Input</label>
              <input type="text" name="login_input_placeholder" value="<?php echo htmlspecialchars($settings['login_input_placeholder'] ?? 'Enter access code...'); ?>" placeholder="Enter access code..." />
            </div>
            <div style="flex:1; min-width: 200px;">
              <label>Pesan Error Login</label>
              <input type="text" name="login_error_text" value="<?php echo htmlspecialchars($settings['login_error_text'] ?? 'Kode akses tidak valid.'); ?>" placeholder="Kode akses tidak valid." />
            </div>
          </div>

          <div style="display:flex; gap:10px; flex-wrap: wrap; margin-bottom: 10px;">
            <div style="flex:1; min-width: 150px;">
              <label>Teks Tombol Login</label>
              <input type="text" name="login_btn_text" value="<?php echo htmlspecialchars($settings['login_btn_text'] ?? 'Masuk'); ?>" placeholder="Masuk" />
            </div>
            <div style="flex:1; min-width: 150px;">
              <label>Teks Tombol Takeover</label>
              <input type="text" name="login_takeover_text" value="<?php echo htmlspecialchars($settings['login_takeover_text'] ?? 'Ambil Alih Sesi'); ?>" placeholder="Ambil Alih Sesi" />
            </div>
            <div style="flex:2; min-width: 250px;">
              <label>Teks Footer</label>
              <input type="text" name="login_footer_text" value="<?php echo htmlspecialchars($settings['login_footer_text'] ?? 'TEXA.STUDIO © 2026 copyright.'); ?>" placeholder="TEXA.STUDIO © 2026 copyright." />
            </div>
          </div>
        </div>

        <div class="fi full">
          <label style="font-size: 12px; color: var(--bright); margin-bottom: 8px; display: block;">&#128279; URL Full Katalog AI Tools</label>
          <input type="url" name="catalog_url" value="<?php echo htmlspecialchars($settings['catalog_url'] ?? ''); ?>" placeholder="https://test.texaproject.com/katalog" />
          <p style="font-size:10px;color:var(--muted);margin-top:4px;">Link ini akan muncul di halaman login ekstensi (di atas form access code). Biarkan kosong jika ingin menyembunyikannya.</p>
        </div>

        <div class="fi full" style="margin-top: 15px;">
          <label style="font-size: 12px; color: var(--bright); margin-bottom: 8px; display: block;">&#128187; Tampilan Launcher (Desktop)</label>
          <div style="display:flex; gap:10px; flex-wrap: wrap;">
            <div style="flex:1; min-width: 150px;">
              <label>Jumlah Kolom Grid App (Misal 4 untuk 4x4)</label>
              <input type="number" name="desktop_grid_columns" value="<?php echo htmlspecialchars($settings['desktop_grid_columns'] ?? 4); ?>" placeholder="4" min="2" max="12" />
              <p style="font-size:10px;color:var(--muted);margin-top:4px;">Mengatur bentuk grid icon aplikasi di App Launcher pada mode layar lebar / desktop. (Default: 4)</p>
            </div>
          </div>
        </div>

        <div class="fi full" style="margin-top: 15px; border-top: 1px solid var(--border); padding-top: 15px;">
          <label style="font-size: 12px; color: var(--bright); margin-bottom: 8px; display: block;">&#128683; Pengaturan Tampilan Sesi Berakhir (Kick Out) - MEMBER UTAMA</label>
          
          <div style="display:flex; gap:10px; flex-wrap: wrap; margin-bottom: 10px;">
            <div style="flex:1; min-width: 150px;">
              <label>Logo / Emoji Alert</label>
              <input type="text" name="kick_logo" value="<?php echo htmlspecialchars($settings['kick_logo'] ?? '⚠️'); ?>" placeholder="⚠️" />
            </div>
            <div style="flex:2; min-width: 250px;">
              <label>Judul Alert</label>
              <input type="text" name="kick_title" value="<?php echo htmlspecialchars($settings['kick_title'] ?? 'Sesi Berakhir.!!!'); ?>" placeholder="Sesi Berakhir.!!!" />
            </div>
          </div>

          <div style="margin-bottom: 10px;">
            <label>Deskripsi Baris 1</label>
            <input type="text" name="kick_desc1" value="<?php echo htmlspecialchars($settings['kick_desc1'] ?? 'tunggu admin TEXA refresh server.'); ?>" placeholder="tunggu admin TEXA refresh server." />
          </div>
          
          <div style="margin-bottom: 10px;">
            <label>Deskripsi Baris 2</label>
            <input type="text" name="kick_desc2" value="<?php echo htmlspecialchars($settings['kick_desc2'] ?? 'Cek secara berkala dan pastikan report ke grup WA. Terimakasih!'); ?>" placeholder="Cek secara berkala dan pastikan report ke grup WA. Terimakasih!" />
          </div>

          <div style="display:flex; gap:10px; flex-wrap: wrap; margin-bottom: 10px;">
            <div style="flex:1; min-width: 150px;">
              <label>Teks Tombol WhatsApp</label>
              <input type="text" name="kick_wa_btn" value="<?php echo htmlspecialchars($settings['kick_wa_btn'] ?? 'Whatssap GRUP'); ?>" placeholder="Whatssap GRUP" />
            </div>
            <div style="flex:2; min-width: 250px;">
              <label>Link Grup WhatsApp</label>
              <input type="url" name="kick_wa_link" value="<?php echo htmlspecialchars($settings['kick_wa_link'] ?? 'https://chat.whatsapp.com/FAg698uVEZOAbOpVLG0FhC'); ?>" placeholder="https://chat.whatsapp.com/..." />
            </div>
          </div>

          <div style="margin-bottom: 10px;">
            <label>Teks Tombol Tutup</label>
            <input type="text" name="kick_close_btn" value="<?php echo htmlspecialchars($settings['kick_close_btn'] ?? 'Tutup & Kembali'); ?>" placeholder="Tutup & Kembali" />
          </div>
        </div>

        <div class="fi full" style="margin-top: 15px; border-top: 1px dashed var(--border); padding-top: 15px;">
          <div style="display:flex; justify-content:space-between; align-items:center; margin-bottom: 8px;">
            <label style="font-size: 12px; color: var(--custom); display: block;">&#128683; Pengaturan UI Alerts (Kick Out & Expiry) - KHUSUS MEMBER MITRA</label>
            <select name="target_mitra_ui" id="target_mitra_ui" onchange="loadMitraUISettings(this.value)" style="padding: 6px 12px; font-size: 12px; background: var(--deep); border: 1px solid var(--border); color: var(--text); border-radius: 6px;">
              <option value="all">Semua Mitra (Default)</option>
              <?php
              $users = loadData('users.json');
              foreach ($users as $u) {
                  if ($u['role'] === 'mitra') {
                      echo '<option value="' . $u['id'] . '">Mitra: ' . htmlspecialchars($u['name']) . '</option>';
                  }
              }
              ?>
            </select>
          </div>
          
          <div style="display:flex; gap:10px; flex-wrap: wrap; margin-bottom: 10px;">
            <div style="flex:1; min-width: 150px;">
              <label>Logo / Emoji Alert (Mitra)</label>
              <input type="text" name="mitra_kick_logo" id="mitra_kick_logo" value="<?php echo htmlspecialchars($settings['mitra_kick_logo'] ?? '⚠️'); ?>" placeholder="⚠️" />
            </div>
            <div style="flex:2; min-width: 250px;">
              <label>Judul Alert Kick Out (Mitra)</label>
              <input type="text" name="mitra_kick_title" id="mitra_kick_title" value="<?php echo htmlspecialchars($settings['mitra_kick_title'] ?? 'Sesi Berakhir.!!!'); ?>" placeholder="Sesi Berakhir.!!!" />
            </div>
          </div>

          <div style="margin-bottom: 10px;">
            <label>Deskripsi Baris 1 (Mitra)</label>
            <input type="text" name="mitra_kick_desc1" id="mitra_kick_desc1" value="<?php echo htmlspecialchars($settings['mitra_kick_desc1'] ?? 'tunggu admin Mitra refresh server.'); ?>" placeholder="tunggu admin Mitra refresh server." />
          </div>
          
          <div style="margin-bottom: 10px;">
            <label>Deskripsi Baris 2 (Mitra)</label>
            <input type="text" name="mitra_kick_desc2" id="mitra_kick_desc2" value="<?php echo htmlspecialchars($settings['mitra_kick_desc2'] ?? 'Cek secara berkala dan pastikan report ke grup WA Mitra. Terimakasih!'); ?>" placeholder="Cek secara berkala dan pastikan report ke grup WA Mitra. Terimakasih!" />
          </div>

          <div style="display:flex; gap:10px; flex-wrap: wrap; margin-bottom: 10px;">
            <div style="flex:1; min-width: 150px;">
              <label>Teks Tombol WhatsApp (Mitra)</label>
              <input type="text" name="mitra_kick_wa_btn" id="mitra_kick_wa_btn" value="<?php echo htmlspecialchars($settings['mitra_kick_wa_btn'] ?? 'Whatssap Mitra'); ?>" placeholder="Whatssap Mitra" />
            </div>
            <div style="flex:2; min-width: 250px;">
              <label>Link Grup WhatsApp (Mitra)</label>
              <input type="url" name="mitra_kick_wa_link" id="mitra_kick_wa_link" value="<?php echo htmlspecialchars($settings['mitra_kick_wa_link'] ?? 'https://chat.whatsapp.com/'); ?>" placeholder="https://chat.whatsapp.com/..." />
            </div>
          </div>

          <div style="margin-bottom: 10px;">
            <label>Teks Tombol Tutup (Mitra)</label>
            <input type="text" name="mitra_kick_close_btn" id="mitra_kick_close_btn" value="<?php echo htmlspecialchars($settings['mitra_kick_close_btn'] ?? 'Tutup & Kembali'); ?>" placeholder="Tutup & Kembali" />
            <p style="font-size:10px;color:var(--muted);margin-top:4px;">Teks ini dan logo beserta isinya akan tampil saat pengguna DARI MITRA tertendang dari sesi.</p>
          </div>
        </div>

        <!-- NEW: EXPIRY NOTIFICATION SETTINGS -->
        <div class="fi full" style="margin-top: 15px; border-top: 1px solid var(--border); padding-top: 15px;">
          <label style="font-size: 12px; color: var(--bright); margin-bottom: 8px; display: block;">&#128338; Pengaturan Notifikasi Masa Aktif (Expiry H-3) - MEMBER UTAMA</label>
          
          <div style="display:flex; gap:10px; flex-wrap: wrap; margin-bottom: 10px;">
            <div style="flex:1; min-width: 150px;">
              <label>Waktu Trigger (H- Hari)</label>
              <input type="number" name="exp_trigger_days" value="<?php echo htmlspecialchars($settings['exp_trigger_days'] ?? 3); ?>" placeholder="3" min="1" />
            </div>
            <div style="flex:1; min-width: 150px;">
              <label>Logo / Emoji Alert</label>
              <input type="text" name="exp_logo" value="<?php echo htmlspecialchars($settings['exp_logo'] ?? '⏳'); ?>" placeholder="⏳" />
            </div>
            <div style="flex:2; min-width: 250px;">
              <label>Judul Alert</label>
              <input type="text" name="exp_title" value="<?php echo htmlspecialchars($settings['exp_title'] ?? 'Masa Aktif Hampir Habis!'); ?>" placeholder="Masa Aktif Hampir Habis!" />
            </div>
          </div>

          <div style="margin-bottom: 10px;">
            <label>Teks Notifikasi (Gunakan {hari} untuk sisa hari)</label>
            <input type="text" name="exp_text" value="<?php echo htmlspecialchars($settings['exp_text'] ?? 'Masa aktif voucher Anda tersisa {hari} hari lagi. Segera perpanjang agar akses tidak terputus.'); ?>" />
          </div>

          <div style="display:flex; gap:10px; flex-wrap: wrap; margin-bottom: 10px;">
            <div style="flex:1; min-width: 150px;">
              <label>Teks Tombol Perpanjang</label>
              <input type="text" name="exp_btn_text" value="<?php echo htmlspecialchars($settings['exp_btn_text'] ?? 'Perpanjang Sekarang'); ?>" placeholder="Perpanjang Sekarang" />
            </div>
            <div style="flex:2; min-width: 250px;">
              <label>Link Perpanjang (WhatsApp / Order)</label>
              <input type="url" name="exp_btn_link" value="<?php echo htmlspecialchars($settings['exp_btn_link'] ?? 'https://wa.me/628xxx'); ?>" placeholder="https://wa.me/..." />
            </div>
          </div>
        </div>

        <div class="fi full" style="margin-top: 15px; border-top: 1px dashed var(--border); padding-top: 15px;">
          <label style="font-size: 12px; color: var(--custom); margin-bottom: 8px; display: block;">&#128338; Pengaturan Notifikasi Masa Aktif (Expiry H-3) - KHUSUS MEMBER MITRA</label>
          
          <div style="display:flex; gap:10px; flex-wrap: wrap; margin-bottom: 10px;">
            <div style="flex:1; min-width: 150px;">
              <label>Logo / Emoji Alert (Mitra)</label>
              <input type="text" name="mitra_exp_logo" id="mitra_exp_logo" value="<?php echo htmlspecialchars($settings['mitra_exp_logo'] ?? '⏳'); ?>" placeholder="⏳" />
            </div>
            <div style="flex:2; min-width: 250px;">
              <label>Judul Alert Expiry (Mitra)</label>
              <input type="text" name="mitra_exp_title" id="mitra_exp_title" value="<?php echo htmlspecialchars($settings['mitra_exp_title'] ?? 'Masa Aktif Hampir Habis!'); ?>" placeholder="Masa Aktif Hampir Habis!" />
            </div>
          </div>

          <div style="margin-bottom: 10px;">
            <label>Teks Notifikasi (Gunakan {hari} untuk sisa hari)</label>
            <input type="text" name="mitra_exp_text" id="mitra_exp_text" value="<?php echo htmlspecialchars($settings['mitra_exp_text'] ?? 'Masa aktif voucher Mitra Anda tersisa {hari} hari lagi. Segera hubungi Mitra Anda.'); ?>" />
          </div>

          <div style="display:flex; gap:10px; flex-wrap: wrap; margin-bottom: 10px;">
            <div style="flex:1; min-width: 150px;">
              <label>Teks Tombol Perpanjang (Mitra)</label>
              <input type="text" name="mitra_exp_btn_text" id="mitra_exp_btn_text" value="<?php echo htmlspecialchars($settings['mitra_exp_btn_text'] ?? 'Hubungi Mitra'); ?>" placeholder="Hubungi Mitra" />
            </div>
            <div style="flex:2; min-width: 250px;">
              <label>Link Perpanjang (WhatsApp Mitra)</label>
              <input type="url" name="mitra_exp_btn_link" id="mitra_exp_btn_link" value="<?php echo htmlspecialchars($settings['mitra_exp_btn_link'] ?? 'https://wa.me/628yyy'); ?>" placeholder="https://wa.me/..." />
            </div>
          </div>
          <p style="font-size:10px;color:var(--muted);margin-top:4px;">Popup Notifikasi ini akan muncul di atas App Launcher jika masa aktif <= Waktu Trigger yang diatur.</p>
        </div>

        <!-- ========== PROMO POPUP SETTINGS ========== -->
        <div class="fi full" style="margin-top: 15px; border-top: 2px solid rgba(0,212,255,0.3); padding-top: 15px;">
          <label style="font-size: 13px; color: #00d4ff; margin-bottom: 8px; display: block; font-weight: 700;">📢 Popup Promo / Informasi — MEMBER UTAMA (Server Asli)</label>
          <p style="font-size:10px;color:var(--muted);margin-bottom:12px;">Popup ini muncul saat user berhasil login ke App Launcher. Cocok untuk promo, pengumuman, atau informasi layanan.</p>
          
          <div style="display:flex; gap:10px; flex-wrap: wrap; margin-bottom: 10px; align-items:center;">
            <div style="flex:0 0 auto;">
              <label style="display:flex;align-items:center;gap:6px;cursor:pointer;">
                <input type="checkbox" name="promo_active" value="1" <?php echo !empty($settings['promo_active']) ? 'checked' : ''; ?> style="width:16px;height:16px;" />
                <span style="font-weight:600;color:#00e676;">Aktifkan Popup</span>
              </label>
            </div>
          </div>

          <div style="margin-bottom: 10px;">
            <label>🎬 URL Video (YouTube, Facebook, TikTok, IG, atau URL langsung)</label>
            <input type="url" name="promo_video_url" value="<?php echo htmlspecialchars($settings['promo_video_url'] ?? ''); ?>" placeholder="https://www.youtube.com/watch?v=xxxxx" />
            <p style="font-size:10px;color:var(--muted);margin-top:3px;">Dukung: YouTube, Facebook, TikTok, Instagram, atau URL video direct (.mp4). Akan di-embed otomatis.</p>
          </div>

          <div style="margin-bottom: 10px;">
            <label>📌 Judul Promo (Bold & Menarik)</label>
            <input type="text" name="promo_title" value="<?php echo htmlspecialchars($settings['promo_title'] ?? ''); ?>" placeholder="🔥 PROMO SPESIAL BULAN INI!" />
          </div>

          <div style="margin-bottom: 10px;">
            <label>📝 Deskripsi Promo (mendukung HTML untuk styling)</label>
            <textarea name="promo_desc" rows="4" placeholder="Dapatkan DISKON 50% untuk perpanjangan paket PRO dan ULTIMATE! Berlaku hingga akhir bulan ini." style="width:100%;padding:8px;background:var(--input-bg,rgba(0,20,50,0.6));border:1px solid var(--border);border-radius:6px;color:var(--text);font-family:inherit;resize:vertical;"><?php echo htmlspecialchars($settings['promo_desc'] ?? ''); ?></textarea>
          </div>

          <div style="display:flex; gap:10px; flex-wrap: wrap; margin-bottom: 10px;">
            <div style="flex:1; min-width: 150px;">
              <label>🔘 Teks Tombol CTA</label>
              <input type="text" name="promo_btn_text" value="<?php echo htmlspecialchars($settings['promo_btn_text'] ?? ''); ?>" placeholder="Lihat Detail Promo" />
            </div>
            <div style="flex:2; min-width: 250px;">
              <label>🔗 Link Tombol (URL lengkap atau slug)</label>
              <input type="text" name="promo_btn_link" value="<?php echo htmlspecialchars($settings['promo_btn_link'] ?? ''); ?>" placeholder="promo-detail  atau  https://wa.me/628xxx" />
            </div>
          </div>
          <div style="margin-bottom:10px;">
            <label style="display:flex;align-items:center;gap:6px;cursor:pointer;">
              <input type="checkbox" name="promo_auto_slug" value="1" <?php echo !empty($settings['promo_auto_slug']) ? 'checked' : ''; ?> style="width:14px;height:14px;" />
              <span style="font-size:11px;">Auto-generate link dari domain hosting (slug → <code style="color:#00d4ff;">https://domain.com/slug</code>)</span>
            </label>
          </div>
        </div>

        <!-- MITRA PROMO POPUP -->
        <div class="fi full" style="margin-top: 15px; border-top: 2px dashed rgba(255,170,0,0.3); padding-top: 15px;">
          <label style="font-size: 13px; color: #ffaa00; margin-bottom: 8px; display: block; font-weight: 700;">📢 Popup Promo / Informasi — KHUSUS MEMBER MITRA</label>
          <p style="font-size:10px;color:var(--muted);margin-bottom:12px;">Popup ini muncul HANYA untuk user yang menggunakan voucher dari Mitra. Jika tidak diaktifkan, member mitra tidak akan melihat popup.</p>
          
          <div style="display:flex; gap:10px; flex-wrap: wrap; margin-bottom: 10px; align-items:center;">
            <div style="flex:0 0 auto;">
              <label style="display:flex;align-items:center;gap:6px;cursor:pointer;">
                <input type="checkbox" name="mitra_promo_active" value="1" <?php echo !empty($settings['mitra_promo_active']) ? 'checked' : ''; ?> style="width:16px;height:16px;" />
                <span style="font-weight:600;color:#ffaa00;">Aktifkan Popup Mitra</span>
              </label>
            </div>
          </div>

          <div style="margin-bottom: 10px;">
            <label>🎬 URL Video (Mitra)</label>
            <input type="url" name="mitra_promo_video_url" value="<?php echo htmlspecialchars($settings['mitra_promo_video_url'] ?? ''); ?>" placeholder="https://www.youtube.com/watch?v=xxxxx" />
          </div>

          <div style="margin-bottom: 10px;">
            <label>📌 Judul Promo Mitra</label>
            <input type="text" name="mitra_promo_title" value="<?php echo htmlspecialchars($settings['mitra_promo_title'] ?? ''); ?>" placeholder="🎉 INFO PENTING UNTUK MEMBER MITRA!" />
          </div>

          <div style="margin-bottom: 10px;">
            <label>📝 Deskripsi Promo Mitra</label>
            <textarea name="mitra_promo_desc" rows="4" placeholder="Hubungi mitra Anda untuk dapatkan promo eksklusif..." style="width:100%;padding:8px;background:var(--input-bg,rgba(0,20,50,0.6));border:1px solid var(--border);border-radius:6px;color:var(--text);font-family:inherit;resize:vertical;"><?php echo htmlspecialchars($settings['mitra_promo_desc'] ?? ''); ?></textarea>
          </div>

          <div style="display:flex; gap:10px; flex-wrap: wrap; margin-bottom: 10px;">
            <div style="flex:1; min-width: 150px;">
              <label>🔘 Teks Tombol CTA (Mitra)</label>
              <input type="text" name="mitra_promo_btn_text" value="<?php echo htmlspecialchars($settings['mitra_promo_btn_text'] ?? ''); ?>" placeholder="Hubungi Mitra" />
            </div>
            <div style="flex:2; min-width: 250px;">
              <label>🔗 Link Tombol (Mitra)</label>
              <input type="text" name="mitra_promo_btn_link" value="<?php echo htmlspecialchars($settings['mitra_promo_btn_link'] ?? ''); ?>" placeholder="https://wa.me/628xxx" />
            </div>
          </div>
          <div style="margin-bottom:10px;">
            <label style="display:flex;align-items:center;gap:6px;cursor:pointer;">
              <input type="checkbox" name="mitra_promo_auto_slug" value="1" <?php echo !empty($settings['mitra_promo_auto_slug']) ? 'checked' : ''; ?> style="width:14px;height:14px;" />
              <span style="font-size:11px;">Auto-generate link dari domain hosting (slug → <code style="color:#ffaa00;">https://domain.com/slug</code>)</span>
            </label>
          </div>
        </div>

        <!-- ========== EXTENSION VERSION UPDATE SETTINGS ========== -->
        <div style="margin:20px 0 10px; padding:18px; background:rgba(220, 38, 38, 0.06); border:1px solid rgba(220, 38, 38, 0.25); border-radius:12px;">
          <h3 style="margin:0 0 6px 0; font-size:16px; color:#ef4444;">🔄 Notifikasi Update Ekstensi</h3>
          <p style="font-size:12px; color:#9ca3af; margin:0 0 14px;">Sistem otomatis mendeteksi versi extension. Upload <code style="color:#ef4444;">ext_version.json</code> setiap kali rilis baru — server akan otomatis memberi tahu user yang masih pakai versi lama.</p>

          <?php
            // Baca status auto-detect
            $ev_file = DATA_DIR . '/ext_version.json';
            $ev_data = file_exists($ev_file) ? json_decode(file_get_contents($ev_file), true) : null;
            $auto_ver = $ev_data ? ($ev_data['version'] ?? null) : null;
            $auto_built = $ev_data ? ($ev_data['built_at'] ?? null) : null;
          ?>

          <!-- STATUS CARD: AUTO DETECT -->
          <?php if ($auto_ver): ?>
          <div style="display:flex;align-items:center;gap:12px;padding:12px 16px;background:rgba(0,230,118,0.08);border:1px solid rgba(0,230,118,0.3);border-radius:10px;margin-bottom:14px;">
            <div style="font-size:24px;">✅</div>
            <div style="flex:1;">
              <div style="font-weight:700;color:#00e676;font-size:14px;">Auto-Detect Aktif</div>
              <div style="font-size:12px;color:#9ca3af;">Versi terbaru: <strong style="color:#fff;">v<?php echo htmlspecialchars($auto_ver); ?></strong>
                <?php if ($auto_built): ?> &nbsp;·&nbsp; Build: <?php echo date('d M Y H:i', strtotime($auto_built)); ?><?php endif; ?>
              </div>
            </div>
            <form method="POST" onsubmit="return confirm('Hapus file auto-detect? Mode manual akan digunakan.');" style="margin:0;">
              <input type="hidden" name="action_delete_ext_version" value="1">
              <button type="submit" style="background:rgba(255,60,60,0.15);border:1px solid rgba(255,60,60,0.3);color:#ff8080;padding:4px 10px;border-radius:6px;cursor:pointer;font-size:11px;">Hapus</button>
            </form>
          </div>
          <?php else: ?>
          <div style="display:flex;align-items:center;gap:12px;padding:12px 16px;background:rgba(255,170,0,0.08);border:1px solid rgba(255,170,0,0.3);border-radius:10px;margin-bottom:14px;">
            <div style="font-size:24px;">⚠️</div>
            <div>
              <div style="font-weight:700;color:#ffcc44;font-size:14px;">Mode Manual</div>
              <div style="font-size:12px;color:#9ca3af;">Upload <code>ext_version.json</code> dari folder PUBLISH untuk aktifkan auto-detect</div>
            </div>
          </div>
          <?php endif; ?>

          <!-- UPLOAD ext_version.json -->
          <div style="margin-bottom:16px;padding:14px;background:rgba(0,100,255,0.06);border:1px solid rgba(0,100,255,0.2);border-radius:10px;">
            <label style="font-weight:700;color:#4db8ff;font-size:12px;letter-spacing:0.5px;display:block;margin-bottom:8px;">📤 UPLOAD ext_version.json (dari folder PUBLISH)</label>
            <div style="display:flex;gap:8px;align-items:center;flex-wrap:wrap;">
              <form method="POST" enctype="multipart/form-data" style="display:flex;gap:8px;flex:1;align-items:center;flex-wrap:wrap;">
                <input type="file" name="ext_version_file" accept=".json" style="flex:1;min-width:200px;padding:6px 10px;background:rgba(0,20,50,0.6);border:1px solid rgba(0,100,255,0.3);border-radius:6px;color:#e8f4ff;font-size:13px;" required>
                <button type="submit" name="upload_ext_version" style="padding:8px 16px;background:linear-gradient(135deg,#0055cc,#0088ff);border:none;border-radius:8px;color:#fff;font-weight:700;cursor:pointer;font-size:13px;white-space:nowrap;">⬆ Upload & Aktifkan</button>
              </form>
            </div>
            <small style="color:#6b7280;display:block;margin-top:6px;">File <code>ext_version.json</code> otomatis dibuat saat menjalankan <code>node build-extension.js</code> — ada di folder <code>exstension B - PUBLISH/</code></small>
          </div>

          <div style="margin-bottom:12px;">
            <label style="display:flex;align-items:center;gap:8px;cursor:pointer;">
              <input type="checkbox" name="ext_update_active" value="1" <?php echo !empty($settings['ext_update_active']) ? 'checked' : ''; ?> style="width:16px;height:16px;" />
              <span style="font-weight:bold; color:#ef4444;">Aktifkan Notifikasi (Mode Manual — tidak perlu jika auto-detect sudah aktif)</span>
            </label>
          </div>

          <div style="display:flex; gap:10px; flex-wrap:wrap; margin-bottom:10px;">
            <div style="flex:1; min-width:120px;">
              <label>📦 Versi Terbaru (Manual Fallback)</label>
              <input type="text" name="ext_latest_version" value="<?php echo htmlspecialchars($auto_ver ?? ($settings['ext_latest_version'] ?? '1.0.0')); ?>" placeholder="1.1.0" style="font-weight:bold; color:#ef4444;" <?php echo $auto_ver ? 'readonly' : ''; ?> />
              <?php if ($auto_ver): ?><small style="color:#00e676;">✅ Otomatis dari ext_version.json</small><?php endif; ?>
            </div>
            <div style="flex:2; min-width:200px;">
              <label>📝 Judul Popup Update</label>
              <input type="text" name="ext_update_title" value="<?php echo htmlspecialchars($settings['ext_update_title'] ?? 'Update Tersedia!'); ?>" placeholder="Update Tersedia!" />
            </div>
          </div>

          <div style="margin-bottom:10px;">
            <label>📋 Deskripsi Popup Update</label>
            <textarea name="ext_update_desc" rows="3" placeholder="Versi terbaru {version} sudah tersedia. Segera update untuk menikmati fitur terbaru." style="width:100%;padding:8px;background:var(--input-bg,rgba(0,20,50,0.6));border:1px solid var(--border);border-radius:6px;color:var(--text);font-family:inherit;resize:vertical;"><?php echo htmlspecialchars($settings['ext_update_desc'] ?? 'Versi terbaru {version} sudah tersedia. Segera update untuk menikmati fitur dan layanan terbaru TEKNO APPS.'); ?></textarea>
            <small style="color:#6b7280;">Gunakan <code style="color:#ef4444;">{version}</code> untuk menampilkan nomor versi terbaru secara otomatis.</small>
          </div>

          <div style="display:flex; gap:10px; flex-wrap:wrap; margin-bottom:10px;">
            <div style="flex:1; min-width:150px;">
              <label>🔘 Teks Tombol Unduh</label>
              <input type="text" name="ext_update_btn_text" value="<?php echo htmlspecialchars($settings['ext_update_btn_text'] ?? 'Unduh Sekarang'); ?>" placeholder="Unduh Sekarang" />
            </div>
            <div style="flex:2; min-width:250px;">
              <label>🔗 Link Unduh Ekstensi</label>
              <input type="text" name="ext_update_btn_link" value="<?php echo htmlspecialchars($settings['ext_update_btn_link'] ?? ''); ?>" placeholder="https://drive.google.com/file/d/xxx" />
            </div>
          </div>
        </div>


        <div class="fi full" style="display:flex;justify-content:flex-end;margin-top:20px">
          <button type="submit" class="btn bp">&#x1F4BE; Simpan Pengaturan</button>
        </div>
      </div>
    </form>
  </div>
</div>

<script>
const MITRA_UI_SETTINGS = <?php echo json_encode($settings['mitra_ui'] ?? []); ?>;
const DEFAULT_MITRA_UI = {
    mitra_kick_logo: <?php echo json_encode($settings['mitra_kick_logo'] ?? '⚠️'); ?>,
    mitra_kick_title: <?php echo json_encode($settings['mitra_kick_title'] ?? 'Sesi Berakhir.!!!'); ?>,
    mitra_kick_desc1: <?php echo json_encode($settings['mitra_kick_desc1'] ?? 'tunggu admin Mitra refresh server.'); ?>,
    mitra_kick_desc2: <?php echo json_encode($settings['mitra_kick_desc2'] ?? 'Cek secara berkala dan pastikan report ke grup WA Mitra. Terimakasih!'); ?>,
    mitra_kick_wa_btn: <?php echo json_encode($settings['mitra_kick_wa_btn'] ?? 'Whatssap Mitra'); ?>,
    mitra_kick_wa_link: <?php echo json_encode($settings['mitra_kick_wa_link'] ?? 'https://chat.whatsapp.com/'); ?>,
    mitra_kick_close_btn: <?php echo json_encode($settings['mitra_kick_close_btn'] ?? 'Tutup & Kembali'); ?>,
    mitra_exp_logo: <?php echo json_encode($settings['mitra_exp_logo'] ?? '⏳'); ?>,
    mitra_exp_title: <?php echo json_encode($settings['mitra_exp_title'] ?? 'Masa Aktif Hampir Habis!'); ?>,
    mitra_exp_text: <?php echo json_encode($settings['mitra_exp_text'] ?? 'Masa aktif voucher Mitra Anda tersisa {hari} hari lagi. Segera hubungi Mitra Anda.'); ?>,
    mitra_exp_btn_text: <?php echo json_encode($settings['mitra_exp_btn_text'] ?? 'Hubungi Mitra'); ?>,
    mitra_exp_btn_link: <?php echo json_encode($settings['mitra_exp_btn_link'] ?? 'https://wa.me/628yyy'); ?>
};

function loadMitraUISettings(mitraId) {
    let data = DEFAULT_MITRA_UI;
    if (mitraId !== 'all' && MITRA_UI_SETTINGS[mitraId]) {
        data = Object.assign({}, DEFAULT_MITRA_UI, MITRA_UI_SETTINGS[mitraId]);
    }
    
    document.getElementById('mitra_kick_logo').value = data.mitra_kick_logo;
    document.getElementById('mitra_kick_title').value = data.mitra_kick_title;
    document.getElementById('mitra_kick_desc1').value = data.mitra_kick_desc1;
    document.getElementById('mitra_kick_desc2').value = data.mitra_kick_desc2;
    document.getElementById('mitra_kick_wa_btn').value = data.mitra_kick_wa_btn;
    document.getElementById('mitra_kick_wa_link').value = data.mitra_kick_wa_link;
    document.getElementById('mitra_kick_close_btn').value = data.mitra_kick_close_btn;
    
    document.getElementById('mitra_exp_logo').value = data.mitra_exp_logo;
    document.getElementById('mitra_exp_title').value = data.mitra_exp_title;
    document.getElementById('mitra_exp_text').value = data.mitra_exp_text;
    document.getElementById('mitra_exp_btn_text').value = data.mitra_exp_btn_text;
    document.getElementById('mitra_exp_btn_link').value = data.mitra_exp_btn_link;
}
</script>
<?php endif; ?>

<?php if ($role === 'owner' || !empty($user_perms['tab_audit'])): ?>
<!-- AUDIT TAB -->
<div id="tab-audit" class="tab-content <?php echo $tab==='audit'?'active':''; ?>">
  <div class="card">
    <div class="ct">Histori Log Sistem</div>
    <div style="font-size:12px; color:var(--muted); margin-bottom: 20px;">Catatan aktivitas krusial seperti penambahan/penghapusan admin, refund member, dan perubahan password.</div>
    <div class="table-responsive">
      <table class="table">
        <thead>
          <tr>
            <th>WAKTU</th>
            <th>AKSI</th>
            <th>OLEH (USER ID/NAMA)</th>
            <th>TARGET (ID)</th>
            <th>DETAIL</th>
          </tr>
        </thead>
        <tbody>
          <?php
          $auditFile = DATA_DIR . '/audit.json';
          $auditLogs = file_exists($auditFile) ? json_decode(file_get_contents($auditFile), true) : [];
          $auditLogs = array_reverse($auditLogs); // Show newest first
          if (empty($auditLogs)):
          ?>
          <tr><td colspan="5" style="text-align:center; padding: 20px;">Belum ada histori log.</td></tr>
          <?php else: foreach ($auditLogs as $log): ?>
          <tr>
            <td data-label="WAKTU"><?php echo $log['time'] ?? '-'; ?></td>
            <td data-label="AKSI"><span style="background: rgba(255,255,255,0.1); padding: 4px 8px; border-radius: 4px; font-size: 11px; font-weight: bold;"><?php echo strtoupper(str_replace('_', ' ', $log['action'] ?? '-')); ?></span></td>
            <td data-label="OLEH (USER ID/NAMA)"><?php echo htmlspecialchars($log['by'] ?? '-'); ?></td>
            <td data-label="TARGET (ID)"><?php echo htmlspecialchars($log['target_user_id'] ?? $log['member_id'] ?? '-'); ?>
                <?php if (!empty($log['member_name'])) echo '<br><span style="font-size:10px;color:var(--muted);">'.htmlspecialchars($log['member_name']).'</span>'; ?>
            </td>
            <td data-label="DETAIL">
              <?php 
              if (isset($log['refund_amount'])) {
                  echo 'Refund: <span style="color:var(--err);">Rp ' . number_format($log['refund_amount'], 0, ',', '.') . '</span>';
                  if (!empty($log['reason'])) {
                      echo '<br><span style="font-size:11px;color:var(--muted);">Alasan: ' . htmlspecialchars($log['reason']) . '</span>';
                  }
              } elseif (isset($log['price_added'])) {
                  echo 'Upgrade: Rp ' . number_format($log['price_added'], 0, ',', '.');
                  if (isset($log['commission'])) echo '<br><span style="font-size:10px;color:#00e676;">Komisi: +Rp '.number_format($log['commission'], 0, ',', '.').'</span>';
              } elseif (isset($log['price'])) {
                  echo 'Penjualan: Rp ' . number_format($log['price'], 0, ',', '.');
                  if (isset($log['commission'])) echo '<br><span style="font-size:10px;color:#00e676;">Komisi: +Rp '.number_format($log['commission'], 0, ',', '.').'</span>';
              } elseif (isset($log['amount_reset'])) {
                  echo 'Reset Saldo: <span style="color:var(--err);">-Rp ' . number_format($log['amount_reset'], 0, ',', '.') . '</span>';
              } else {
                  echo '-';
              }
              
              if (!empty($log['mitra_id'])) {
                  $mitraName = 'Mitra ID: ' . $log['mitra_id'];
                  $usersData = file_exists('data/users.json') ? json_decode(file_get_contents('data/users.json'), true) : [];
                  foreach ($usersData as $u) {
                      if ($u['id'] == $log['mitra_id']) {
                          $mitraName = $u['name'];
                          break;
                      }
                  }
                  echo '<br><span style="font-size:10px;color:var(--custom); border: 1px solid var(--custom); padding: 1px 4px; border-radius: 4px; margin-top: 4px; display: inline-block;">Via Mitra: ' . htmlspecialchars($mitraName) . '</span>';
              }
              ?>
            </td>
          </tr>
          <?php endforeach; endif; ?>
        </tbody>
      </table>
    </div>
  </div>
</div>
<?php endif; ?>

<?php if ($role === 'owner' || !empty($user_perms['tab_users']) || !empty($user_perms['tab_mitras'])): ?>
<!-- USERS TAB -->
<div id="tab-users" class="tab-content <?php echo $tab==='users'?'active':''; ?>">
  <div class="card">
    <div class="ct">Manajemen User (Admin & Owner)</div>
    <?php
      $users = loadData('users.json');
    ?>
    <div class="tw"><table>
      <thead><tr><th>ID</th><th>Nama Profil</th><th>Role</th><th>Dibuat Pada</th><th>Aksi</th></tr></thead>
      <tbody>
      <?php foreach($users as $u): ?>
        <tr>
          <td data-label="ID"><?php echo $u['id']; ?></td>
          <td data-label="Nama Profil"><strong><?php echo htmlspecialchars($u['name'] ?? ucfirst($u['role'])); ?></strong></td>
          <td data-label="Role"><span class="badge <?php echo $u['role']==='owner'?'pb-ultimate':($u['role']==='mitra'?'pb-custom':'pb-basic'); ?>"><?php echo strtoupper($u['role']); ?></span></td>
          <td data-label="Dibuat Pada"><?php echo $u['created_at']; ?></td>
          <td data-label="Aksi" style="display:flex;gap:5px;flex-wrap:wrap;justify-content:flex-end;align-items:center;">
            <form method="POST" style="margin:0;display:flex;gap:5px;align-items:center;">
              <input type="hidden" name="action" value="change_pass"/>
              <input type="hidden" name="user_id" value="<?php echo $u['id']; ?>"/>
              <input type="text" name="new_pass" placeholder="Password Baru" required style="width:120px;padding:4px 8px;margin:0;"/>
              <button type="submit" class="btn bp" style="padding:4px 8px;font-size:10px;">Ubah</button>
            </form>
            <?php if ($u['role'] === 'admin'): 
                // Admin can only change other users' permissions if they are the owner, or if they somehow have permission but usually only owners should change permissions
                // Actually let's restrict permissions button to owner only, or allow admin if they have tab_users (but then they can give themselves all perms)
                // If the user wants admin to manage users, they can give them 'tab_users' permission. So an admin can change permissions of other admins.
                // But an admin shouldn't change owner's permissions (owner doesn't have permissions editable here anyway since it checks role===admin).
            ?>
            <button type="button" class="btn bt" style="padding:4px 8px;font-size:10px;margin-left:5px;" onclick="document.getElementById('perm_form_<?php echo $u['id']; ?>').style.display='table-row'">Izin Akses</button>
            <?php endif; ?>
            <?php if ($u['role'] === 'mitra'): ?>
            <button type="button" class="btn bt" style="padding:4px 8px;font-size:10px;margin-left:5px;" onclick="document.getElementById('edit_mitra_form_<?php echo $u['id']; ?>').style.display='table-row'">Edit Detail</button>
            <?php endif; ?>
            <form method="POST" style="margin:0;" onsubmit="return confirm('Hapus user ini?');">
              <input type="hidden" name="action" value="delete_user"/>
              <input type="hidden" name="user_id" value="<?php echo $u['id']; ?>"/>
              <button type="submit" class="btn bd" style="padding:4px 8px;font-size:10px;margin-left:5px;">X</button>
            </form>
          </td>
        </tr>
        <?php if ($u['role'] === 'admin'): 
            // Normalize legacy permissions
            $p = $u['permissions'] ?? [];
            if (!isset($p['tab_members'])) $p['tab_members'] = true;
            if (!isset($p['tab_cookies']) && isset($p['inject_cookies'])) $p['tab_cookies'] = $p['inject_cookies'];
        ?>
        <tr id="perm_form_<?php echo $u['id']; ?>" style="display:none; background:rgba(0,50,100,0.1);">
          <td colspan="5" style="padding: 15px;">
            <form method="POST" style="margin:0; display:flex; flex-direction:column; gap:10px;">
               <input type="hidden" name="action" value="update_perms"/>
               <input type="hidden" name="user_id" value="<?php echo $u['id']; ?>"/>
               <strong style="color:var(--bright);font-size:11px; margin-bottom: 5px; display:block;">Izin Akses Tab Admin:</strong>
               <div style="display:flex; gap:15px; align-items:center; flex-wrap:wrap; margin-bottom:10px;">
                 <label style="font-size:11px;"><input type="checkbox" name="perm_tab_members" <?php echo !empty($p['tab_members']) ? 'checked' : ''; ?>> Kelola Member</label>
                 <label style="font-size:11px;"><input type="checkbox" name="perm_tab_apps" <?php echo !empty($p['tab_apps']) ? 'checked' : ''; ?>> Kelola Aplikasi</label>
                 <label style="font-size:11px;"><input type="checkbox" name="perm_tab_cookies" <?php echo !empty($p['tab_cookies']) ? 'checked' : ''; ?>> Inject Cookies</label>
                 <label style="font-size:11px;"><input type="checkbox" name="perm_tab_packages" <?php echo !empty($p['tab_packages']) ? 'checked' : ''; ?>> Konfigurasi Paket</label>
                 <label style="font-size:11px;"><input type="checkbox" name="perm_tab_settings" <?php echo !empty($p['tab_settings']) ? 'checked' : ''; ?>> Pengaturan</label>
                 <label style="font-size:11px;"><input type="checkbox" name="perm_tab_users" <?php echo !empty($p['tab_users']) ? 'checked' : ''; ?>> Manajemen User</label>
                 <label style="font-size:11px;"><input type="checkbox" name="perm_tab_mitras" <?php echo !empty($p['tab_mitras']) ? 'checked' : ''; ?>> Manajemen Mitra</label>
                 <label style="font-size:11px;"><input type="checkbox" name="perm_tab_audit" <?php echo !empty($p['tab_audit']) ? 'checked' : ''; ?>> Histori Log</label>
              <label style="font-size:11px;"><input type="checkbox" name="perm_tab_notepad" <?php echo !empty($p['tab_notepad']) ? 'checked' : ''; ?>> Notepad & Akun</label>
               </div>
               
               <strong style="color:var(--bright);font-size:11px; margin-bottom: 5px; display:block;">Izin Aksi Spesifik (Member):</strong>
               <div style="display:flex; gap:15px; align-items:center; flex-wrap:wrap;">
                 <label style="font-size:11px;"><input type="checkbox" name="perm_add_member" <?php echo ($p['add_member'] ?? true) ? 'checked' : ''; ?>> Tambah Member</label>
                 <label style="font-size:11px;"><input type="checkbox" name="perm_edit_member" <?php echo ($p['edit_member'] ?? true) ? 'checked' : ''; ?>> Edit/Hapus Member</label>
                 <label style="font-size:11px;"><input type="checkbox" name="perm_view_stats" <?php echo ($p['view_stats'] ?? true) ? 'checked' : ''; ?>> Lihat Pendapatan</label>
                 <div style="flex:1;"></div>
                 <button type="submit" class="btn bp" style="padding:6px 12px;font-size:10px;">Simpan Izin</button>
                 <button type="button" class="btn bd" style="padding:6px 12px;font-size:10px;" onclick="document.getElementById('perm_form_<?php echo $u['id']; ?>').style.display='none'">Batal</button>
               </div>
            </form>
          </td>
        </tr>
        <?php endif; ?>
        <?php if ($u['role'] === 'mitra'): ?>
        <tr id="edit_mitra_form_<?php echo $u['id']; ?>" style="display:none; background:rgba(0,50,100,0.1);">
          <td colspan="5" style="padding: 15px;">
            <form method="POST" style="margin:0; display:flex; gap:10px; align-items:flex-end; flex-wrap:wrap;">
               <input type="hidden" name="action" value="update_mitra_detail"/>
               <input type="hidden" name="user_id" value="<?php echo $u['id']; ?>"/>
               <div style="flex:1; min-width:140px;"><label style="font-size:10px;color:var(--muted);display:block;margin-bottom:4px;">Nama Mitra</label><input type="text" name="m_name" value="<?php echo htmlspecialchars($u['name'] ?? ''); ?>" required style="width:100%;margin:0;"/></div>
               <div style="flex:1; min-width:140px;"><label style="font-size:10px;color:var(--muted);display:block;margin-bottom:4px;">Email</label><input type="text" name="m_email" value="<?php echo htmlspecialchars($u['email'] ?? ''); ?>" style="width:100%;margin:0;"/></div>
               <div style="flex:1; min-width:120px;"><label style="font-size:10px;color:var(--muted);display:block;margin-bottom:4px;">No. Telp</label><input type="text" name="m_phone" value="<?php echo htmlspecialchars($u['phone'] ?? ''); ?>" style="width:100%;margin:0;"/></div>
<?php 
                  $c_basic = is_array($u['commission_rate'] ?? null) ? ($u['commission_rate']['basic'] ?? 0) : ($u['commission_rate'] ?? 0);
                  $c_pro = is_array($u['commission_rate'] ?? null) ? ($u['commission_rate']['pro'] ?? 0) : ($u['commission_rate'] ?? 0);
                  $c_ultimate = is_array($u['commission_rate'] ?? null) ? ($u['commission_rate']['ultimate'] ?? 0) : ($u['commission_rate'] ?? 0);
                ?>
                <div style="flex:1; min-width:80px;"><label style="font-size:10px;color:var(--muted);display:block;margin-bottom:4px;">Komisi Basic (Rp)</label><input type="number" name="m_comm_basic" value="<?php echo htmlspecialchars($c_basic); ?>" required style="width:100%;margin:0;"/></div>
                <div style="flex:1; min-width:80px;"><label style="font-size:10px;color:var(--muted);display:block;margin-bottom:4px;">Komisi Pro (Rp)</label><input type="number" name="m_comm_pro" value="<?php echo htmlspecialchars($c_pro); ?>" required style="width:100%;margin:0;"/></div>
                <div style="flex:1; min-width:80px;"><label style="font-size:10px;color:var(--muted);display:block;margin-bottom:4px;">Komisi Ult (Rp)</label><input type="number" name="m_comm_ultimate" value="<?php echo htmlspecialchars($c_ultimate); ?>" required style="width:100%;margin:0;"/></div>
               <div style="display:flex; gap:5px; padding-bottom:0px; flex-wrap:wrap; margin-top:14px;">
                 <button type="submit" class="btn bp" style="padding:6px 12px;font-size:10px;margin:0;white-space:nowrap;">Simpan</button>
                 <button type="button" class="btn bd" style="padding:6px 12px;font-size:10px;margin:0;white-space:nowrap;" onclick="document.getElementById('edit_mitra_form_<?php echo $u['id']; ?>').style.display='none'">Batal</button>
               </div>
            </form>
          </td>
        </tr>
        <?php endif; ?>
      <?php endforeach; ?>
      </tbody>
    </table></div>

    <div style="margin-top: 30px; border-top: 1px solid var(--border); padding-top: 20px;">
      <h3 style="font-size:14px; margin-bottom: 10px;">Tambah Admin Kasir Baru</h3>
      <form method="POST" style="display:flex; flex-direction:column; gap:10px;">
        <input type="hidden" name="action" value="add_admin"/>
        <div style="display:flex; gap:10px; flex-wrap:wrap;">
          <input type="text" name="new_admin_name" placeholder="Nama Profil Admin" required style="width:200px; margin:0;"/>
          <input type="text" name="new_admin_pass" placeholder="Password Admin Baru" required style="width:200px; margin:0;"/>
        </div>
        
        <div style="background:rgba(0,0,0,0.2); padding:10px; border-radius:8px; border:1px solid var(--border);">
           <strong style="color:var(--bright); font-size:11px; margin-bottom: 5px; display:block;">Izin Akses Tab Admin:</strong>
           <div style="display:flex; gap:15px; align-items:center; flex-wrap:wrap; margin-bottom:10px;">
             <label style="font-size:11px;"><input type="checkbox" name="perm_tab_members" checked> Kelola Member</label>
             <label style="font-size:11px;"><input type="checkbox" name="perm_tab_apps"> Kelola Aplikasi</label>
             <label style="font-size:11px;"><input type="checkbox" name="perm_tab_cookies"> Inject Cookies</label>
             <label style="font-size:11px;"><input type="checkbox" name="perm_tab_packages"> Konfigurasi Paket</label>
             <label style="font-size:11px;"><input type="checkbox" name="perm_tab_settings"> Pengaturan</label>
             <label style="font-size:11px;"><input type="checkbox" name="perm_tab_users"> Manajemen User</label>
             <label style="font-size:11px;"><input type="checkbox" name="perm_tab_mitras"> Manajemen Mitra</label>
             <label style="font-size:11px;"><input type="checkbox" name="perm_tab_audit"> Histori Log</label>
          <label style="font-size:11px;"><input type="checkbox" name="perm_tab_notepad"> Notepad & Akun</label>
           </div>

           <strong style="color:var(--bright); font-size:11px; margin-bottom: 5px; display:block;">Izin Aksi Spesifik (Member):</strong>
           <div style="display:flex; gap:15px; align-items:center; flex-wrap:wrap;">
             <label style="font-size:11px;"><input type="checkbox" name="perm_add_member" checked> Tambah Member</label>
             <label style="font-size:11px;"><input type="checkbox" name="perm_edit_member" checked> Edit/Hapus Member</label>
             <label style="font-size:11px;"><input type="checkbox" name="perm_view_stats" checked> Lihat Pendapatan</label>
           </div>
        </div>
        <button type="submit" class="btn bp" style="margin:0; width:fit-content; padding: 10px 20px;">+ Tambah Admin</button>
      </form>
    </div>
  </div>
</div>

<!-- MANAJEMEN MITRA TAB -->
<div id="tab-mitras" class="tab-content <?php echo $tab==='mitras'?'active':''; ?>">
  <div class="card">
    <div class="ct">Manajemen Mitra / Reseller</div>
    
    <?php 
    $mitras = array_filter($users, function($u) { return $u['role'] === 'mitra'; });
    $all_members = loadData('members.json');
    $minusCount = 0;
    $totalDeposit = 0;
    foreach ($mitras as &$mm) { 
        $db = $mm['deposit_balance'] ?? 0; 
        $totalDeposit += $db;
        if ($db < 0) $minusCount++; 
        
        $omset = 0;
        foreach ($all_members as $mem) {
            if (($mem['mitra_id'] ?? null) == $mm['id']) {
                $revenue = (int)($mem['price_paid'] ?? 0);
                $pkg = $mem['package'] ?? 'basic';
                
                // Hitung durasi paket untuk proporsi komisi
                $created = !empty($mem['created_at']) ? strtotime($mem['created_at']) : time();
                $expiry = !empty($mem['expiry_date']) ? strtotime($mem['expiry_date']) : time() + 86400;
                $days = max(1, round(($expiry - $created) / 86400));

                $rate_config = $mm['commission_rate'] ?? [];
                if (!is_array($rate_config)) {
                    $rate_config = ['basic' => (int)$rate_config, 'pro' => (int)$rate_config, 'ultimate' => (int)$rate_config];
                }
                $base_komisi = $rate_config[$pkg] ?? $rate_config['basic'] ?? 0;
                $komisi = $base_komisi; // Komisi flat per paket

                // Omset owner = Harga Jual (Revenue) - Komisi Mitra
                $omset += max(0, $revenue - $komisi);
            }
        }
        $mm['total_omset'] = $omset;
    }
    unset($mm);
    ?>
    <div class="stats" style="grid-template-columns: repeat(4, 1fr); margin-bottom: 20px;">
        <div class="sc t"><div class="sv"><?php echo count($mitras); ?></div><div class="sl">Total Mitra</div></div>
        <div class="sc a"><div class="sv" style="color:#00e676;">Rp <?php echo number_format($totalDeposit, 0, ',', '.'); ?></div><div class="sl">Total Deposit</div></div>
        <div class="sc e"><div class="sv"><?php echo $minusCount; ?></div><div class="sl">Saldo Minus</div></div>
        <div class="sc r" style="background:rgba(150,0,255,0.1);border-color:rgba(150,0,255,0.3);"><div class="sv" style="color:#aa88ff;"><?php $tp=0; foreach($mitras as $mm){$tp+=($mm['points']??0);} echo $tp; ?></div><div class="sl">Total Poin</div></div>
    </div>

    <div class="tw">
    <table class="member-table">
      <thead><tr><th>ID</th><th>Nama Perusahaan</th><th>Kontak</th><th>Komisi</th><th>Saldo Komisi</th><th>Deposit (Saldo Belanja)</th><th>Total Omset Mitra</th><th>Aksi</th></tr></thead>
      <tbody>
      <?php if (empty($mitras)): ?>
        <tr><td colspan="8" class="empty">Belum ada mitra terdaftar.</td></tr>
      <?php else: foreach($mitras as $m): 
        $dep_bal = $m['deposit_balance'] ?? 0;
        $dep_color = $dep_bal < 0 ? '#ff4d4d' : '#00e676';
        $minus_lim = $m['deposit_minus_limit'] ?? -500000;
      ?>
        <tr>
          <td data-label="ID"><?php echo $m['id']; ?></td>
          <td data-label="Nama Perusahaan"><strong><?php echo htmlspecialchars($m['name']); ?></strong>
            <div style="margin-top:4px;">
              <?php 
                $lvl = $m['mitra_level'] ?? 'bronze';
                $lvlColor = $lvl === 'gold' ? '#ffcc00' : ($lvl === 'silver' ? '#c0c0c0' : '#cd7f32');
              ?>
              <span style="display:inline-block; padding:1px 6px; border-radius:4px; font-size:9px; font-weight:bold; background:<?php echo $lvlColor; ?>20; color:<?php echo $lvlColor; ?>; border:1px solid <?php echo $lvlColor; ?>; text-transform:uppercase;"><?php echo htmlspecialchars($lvl); ?></span>
            </div>
            <div style="font-size:9px;color:var(--muted);margin-top:4px;"><?php echo $m['is_active'] ? '<span style="color:#00e676">● Aktif</span>' : '<span style="color:#ff4d4d">● Nonaktif</span>'; ?></div>
          </td>
          <td data-label="Kontak">
            <div style="font-size:10px; color:var(--muted);"><?php echo htmlspecialchars($m['email'] ?? '-'); ?></div>
            <div style="font-size:10px; color:var(--muted);"><?php echo htmlspecialchars($m['phone'] ?? '-'); ?></div>
          </td>
          <td data-label="Komisi">
               <span class="badge pb-pro" style="display:inline-block; text-align:left; line-height:1.2;">
                   B: Rp <?php echo number_format(is_array($m['commission_rate'] ?? null) ? ($m['commission_rate']['basic'] ?? 0) : ($m['commission_rate'] ?? 0), 0, ',', '.'); ?><br>
                   P: Rp <?php echo number_format(is_array($m['commission_rate'] ?? null) ? ($m['commission_rate']['pro'] ?? 0) : ($m['commission_rate'] ?? 0), 0, ',', '.'); ?><br>
                   U: Rp <?php echo number_format(is_array($m['commission_rate'] ?? null) ? ($m['commission_rate']['ultimate'] ?? 0) : ($m['commission_rate'] ?? 0), 0, ',', '.'); ?>
               </span>
           </td>
          <td data-label="Saldo Komisi" style="color:var(--bright); font-weight:bold;">Rp <?php echo number_format($m['balance'] ?? 0, 0, ',', '.'); ?></td>
          <td data-label="Deposit">
            <div style="font-weight:800; color:<?php echo $dep_color; ?>; font-size:14px;">Rp <?php echo number_format($dep_bal, 0, ',', '.'); ?></div>
            <div style="font-size:9px; color:var(--muted);">Limit: Rp <?php echo number_format($minus_lim, 0, ',', '.'); ?></div>
            <button type="button" class="btn bp bsm" style="margin-top:4px;padding:3px 8px;font-size:9px;" onclick="showTopupModal(<?php echo $m['id']; ?>, '<?php echo htmlspecialchars($m['name']); ?>')">💰 Top Up</button>
          </td>
          <td data-label="Total Omset Mitra">
            <div style="font-size:14px;font-weight:bold;color:#00e676;">Rp <?php echo number_format($m['total_omset'] ?? 0, 0, ',', '.'); ?></div>
          </td>
          <td data-label="Aksi" style="white-space:nowrap;">
            <div style="display:flex; gap:4px; flex-wrap:wrap;">
              <button type="button" class="btn bsm bt" style="font-size:9px;padding:3px 6px;" onclick="showMitraConfigModal(<?php echo $m['id']; ?>, <?php echo $minus_lim; ?>, '<?php echo $m['mitra_level'] ?? 'bronze'; ?>')">⚙️ Config</button>
              <button type="button" class="btn bsm" style="font-size:9px;padding:3px 6px;background:rgba(255,150,0,0.2);color:#ffcc00;border:1px solid rgba(255,150,0,0.5);" onclick="promptResetMitra(<?php echo $m['id']; ?>)">Reset</button>
              <button type="button" class="btn bd bsm" style="font-size:9px;padding:3px 6px;" onclick="deleteMitra(<?php echo $m['id']; ?>, '<?php echo htmlspecialchars($m['name'], ENT_QUOTES); ?>')">X</button>
              <form method="POST" action="?tab=mitras" style="margin:0;">
                <input type="hidden" name="action" value="login_as_mitra"/>
                <input type="hidden" name="mitra_id" value="<?php echo $m['id']; ?>"/>
                <button type="submit" class="btn bp bsm" style="font-size:9px;padding:3px 6px;background:linear-gradient(135deg, #0099ff, #00ccff);">👁 Dashboard</button>
              </form>
            </div>
          </td>
        </tr>
      <?php endforeach; endif; ?>
      </tbody>
    </table>
    </div>

    <!-- Top Up Deposit Modal (Hidden by default) -->
    <div id="topup-modal" style="display:none; position:fixed; top:0; left:0; width:100%; height:100%; background:rgba(0,0,0,0.7); z-index:9999; display:none; align-items:center; justify-content:center;">
      <div style="background:var(--deep); border:1px solid var(--border); border-radius:15px; padding:25px; max-width:400px; width:90%; backdrop-filter:blur(16px);">
        <h3 style="margin-bottom:15px; color:var(--light);">💰 Top Up Deposit Mitra</h3>
        <p id="topup-mitra-name" style="font-size:12px; color:var(--muted); margin-bottom:15px;"></p>
        <form method="POST" action="?tab=mitras" enctype="multipart/form-data">
          <input type="hidden" name="action" value="topup_deposit"/>
          <input type="hidden" name="mitra_id" id="topup-mitra-id"/>
          <div style="margin-bottom:12px;">
            <label>Jumlah Top Up (Rp)</label>
            <input type="number" name="topup_amount" min="1000" step="1000" required placeholder="Contoh: 2000000" style="font-size:16px; font-weight:bold;"/>
          </div>
          <div style="margin-bottom:12px;">
            <label>Catatan (Opsional)</label>
            <input type="text" name="topup_note" placeholder="Contoh: Transfer BCA 15 April"/>
          </div>
          <div style="margin-bottom:15px;">
            <label>📎 Bukti Transfer (Opsional, maks 10 MB)</label>
            <input type="file" name="topup_proof" accept="image/*,.pdf" style="width:100%; padding:8px; background:rgba(0,20,50,.6); border:1px solid var(--border); border-radius:8px; color:var(--text); font-size:12px; margin-top:4px;"/>
            <p style="font-size:9px; color:var(--muted); margin-top:4px;">Format: JPG, PNG, GIF, WEBP, atau PDF. Maksimal 10 MB.</p>
          </div>
          <div style="display:flex; gap:10px;">
            <button type="button" class="btn bt" onclick="closeTopupModal()" style="flex:1;">Batal</button>
            <button type="submit" class="btn bp" style="flex:1;">✅ Konfirmasi Top Up</button>
          </div>
        </form>
      </div>
    </div>

    <!-- Mitra Config Modal -->
    <div id="mitra-config-modal" style="display:none; position:fixed; top:0; left:0; width:100%; height:100%; background:rgba(0,0,0,0.7); z-index:9999; align-items:center; justify-content:center;">
      <div style="background:var(--deep); border:1px solid var(--border); border-radius:15px; padding:25px; max-width:400px; width:90%;">
        <h3 style="margin-bottom:15px; color:var(--light);">⚙️ Konfigurasi Mitra</h3>
        <form method="POST" action="?tab=mitras">
          <input type="hidden" name="action" value="update_mitra_deposit"/>
          <input type="hidden" name="mitra_id" id="config-mitra-id"/>
          <div style="margin-bottom:12px;">
            <label>Batas Minus Deposit (Rp)</label>
            <input type="number" name="minus_limit" id="config-minus-limit" max="0" step="50000" required/>
            <p style="font-size:10px; color:var(--muted); margin-top:4px;">Contoh: -1000000 = mitra boleh minus sampai Rp 1 juta</p>
          </div>
          <div style="margin-bottom:15px;">
            <label>Level Mitra</label>
            <select name="mitra_level" id="config-mitra-level" style="width:100%; padding:10px; border-radius:8px; background:rgba(0,20,50,.6); color:var(--text); border:1px solid var(--border);">
              <option value="bronze">Bronze</option>
              <option value="silver">Silver</option>
              <option value="gold">Gold</option>
            </select>
          </div>
          <div style="display:flex; gap:10px;">
            <button type="button" class="btn bt" onclick="closeMitraConfigModal()" style="flex:1;">Batal</button>
            <button type="submit" class="btn bp" style="flex:1;">💾 Simpan</button>
          </div>
        </form>
      </div>
    </div>

    <!-- Reset Mitra Confirmation Modal -->
    <div id="reset-mitra-modal" style="display:none; position:fixed; top:0; left:0; width:100%; height:100%; background:rgba(0,0,0,0.7); z-index:9999; align-items:center; justify-content:center;">
      <div style="background:var(--deep); border:1px solid rgba(255,60,60,0.4); border-radius:15px; padding:25px; max-width:420px; width:90%;">
        <h3 style="margin-bottom:10px; color:#ff4d4d;">⚠️ Reset Data Mitra</h3>
        <p style="font-size:12px; color:var(--muted); margin-bottom:15px; line-height:1.6;">
          <strong style="color:#ffcc00;">PERINGATAN:</strong> Aksi ini akan mereset <strong>seluruh data</strong> mitra termasuk:
        </p>
        <ul style="font-size:11px; color:var(--muted); margin-bottom:15px; padding-left:20px; line-height:1.8;">
          <li>💰 Saldo Komisi → Rp 0</li>
          <li>💳 Saldo Deposit → Rp 0</li>
          <li>🎯 Poin Cashback → 0</li>
          <li>🎰 Jumlah Spin → 0</li>
          <li>👥 Semua Member milik mitra ini akan dihapus</li>
          <li>📋 Riwayat deposit, poin, dan spin dihapus</li>
        </ul>
        <form method="POST" action="?tab=mitras" id="reset-mitra-form">
          <input type="hidden" name="action" value="reset_data_mitra"/>
          <input type="hidden" name="mitra_id" id="reset-mitra-id"/>
          <div style="margin-bottom:15px;">
            <label style="color:#ffcc00;">Masukkan Password Owner untuk konfirmasi:</label>
            <input type="password" name="owner_pwd" id="reset-owner-pwd" required placeholder="Password Owner" style="font-size:14px; border-color:rgba(255,60,60,0.4);"/>
          </div>
          <div style="display:flex; gap:10px;">
            <button type="button" class="btn bt" onclick="closeResetModal()" style="flex:1;">Batal</button>
            <button type="submit" class="btn bd" style="flex:1; background:rgba(255,40,40,0.2); color:#ff4d4d; border-color:rgba(255,60,60,0.5);">🗑 Reset Semua Data</button>
          </div>
        </form>
      </div>
    </div>

    <!-- Delete Mitra Confirmation Modal -->
    <div id="delete-mitra-modal" style="display:none; position:fixed; top:0; left:0; width:100%; height:100%; background:rgba(0,0,0,0.7); z-index:9999; align-items:center; justify-content:center;">
      <div style="background:var(--deep); border:1px solid rgba(255,60,60,0.4); border-radius:15px; padding:25px; max-width:400px; width:90%;">
        <h3 style="margin-bottom:10px; color:#ff4d4d;">🗑 Hapus Mitra</h3>
        <p style="font-size:12px; color:var(--muted); margin-bottom:15px; line-height:1.6;">
          Apakah Anda yakin ingin menghapus mitra <strong id="delete-mitra-name" style="color:#ffcc00;"></strong>?
        </p>
        <p style="font-size:11px; color:#ff6666; margin-bottom:15px;">⚠️ Semua data termasuk member, deposit, poin, spin, dan riwayat akan dihapus permanen.</p>
        <form method="POST" action="?tab=mitras" id="delete-mitra-form">
          <input type="hidden" name="action" value="delete_user"/>
          <input type="hidden" name="user_id" id="delete-mitra-id"/>
          <div style="margin-bottom:15px;">
            <label style="display:block; font-size:11px; margin-bottom:5px; color:#ffcc00;">Masukkan Password Owner untuk Autentikasi Hapus</label>
            <input type="password" name="owner_pwd" id="delete-owner-pwd" required placeholder="Password Owner" style="font-size:14px; border-color:rgba(255,60,60,0.4);"/>
          </div>
          <div style="display:flex; gap:10px;">
            <button type="button" class="btn bt" onclick="closeDeleteModal()" style="flex:1;">Batal</button>
            <button type="submit" class="btn bd" style="flex:1; background:rgba(255,40,40,0.2); color:#ff4d4d; border-color:rgba(255,60,60,0.5);">🗑 Hapus Permanen</button>
          </div>
        </form>
      </div>
    </div>

    <!-- RIWAYAT DEPOSIT SECTION -->
    <div style="margin-top: 30px; border-top: 1px solid var(--border); padding-top: 20px;">
      <div style="display:flex; justify-content:space-between; align-items:center; margin-bottom:15px;">
        <h3 style="font-size:14px; margin:0;">📜 Riwayat Saldo & Deposit</h3>
        <a href="?action=export_deposit_history" class="btn" style="font-size:11px; padding:6px 12px; background: rgba(0,150,255,0.1); border: 1px solid rgba(0,150,255,0.3); color:#0099ff; border-radius:4px; text-decoration:none;">📥 Export CSV Semua Transaksi</a>
      </div>
      <div class="tw">
        <table class="member-table">
          <thead><tr><th>Tanggal</th><th>Mitra</th><th>Jumlah</th><th>Saldo Sebelum</th><th>Saldo Sesudah</th><th>Catatan</th><th>Bukti</th><th>Oleh</th></tr></thead>
          <tbody>
          <?php
          $dh = loadData('deposit_history.json');
          $dh = array_reverse(array_values($dh));
          if (empty($dh)): ?>
            <tr><td colspan="8" class="empty">Belum ada riwayat transaksi.</td></tr>
          <?php else: foreach(array_slice($dh, 0, 50) as $d): 
            $mitra_name = '-';
            foreach($users as $u) { if($u['id'] === $d['mitra_id']) { $mitra_name = $u['name']; break; } }
          ?>
            <tr>
              <td data-label="Tanggal"><?php echo $d['date']; ?></td>
              <td data-label="Mitra"><strong><?php echo htmlspecialchars($mitra_name); ?></strong></td>
              <td data-label="Jumlah" style="color:<?php echo ($d['amount'] > 0) ? '#00e676' : '#ff4d4d'; ?>; font-weight:bold;">
                <?php echo ($d['amount'] > 0 ? '+' : '') . 'Rp ' . number_format($d['amount'], 0, ',', '.'); ?>
              </td>
              <td data-label="Sebelum" style="color:<?php echo ($d['balance_before'] < 0) ? '#ff4d4d' : 'var(--sub)'; ?>;">Rp <?php echo number_format($d['balance_before'], 0, ',', '.'); ?></td>
              <td data-label="Sesudah" style="color:<?php echo ($d['balance_after'] < 0) ? '#ff4d4d' : '#00e676'; ?>;">Rp <?php echo number_format($d['balance_after'], 0, ',', '.'); ?></td>
              <td data-label="Catatan" style="color:var(--muted);"><?php echo htmlspecialchars($d['note'] ?? '-'); ?></td>
              <td data-label="Bukti">
                <?php if (!empty($d['proof'])): ?>
                  <a href="<?php echo htmlspecialchars($d['proof']); ?>" target="_blank" style="color:#0099ff; text-decoration:none; font-size:11px;">📎 Lihat</a>
                <?php else: ?>
                  <span style="color:var(--muted); font-size:11px;">-</span>
                <?php endif; ?>
              </td>
              <td data-label="Oleh"><?php echo htmlspecialchars($d['by'] ?? '-'); ?></td>
            </tr>
          <?php endforeach; endif; ?>
          </tbody>
        </table>
      </div>
    </div>

    <!-- RANKING MITRA SECTION -->
    <div style="margin-top: 30px; border-top: 1px solid var(--border); padding-top: 20px;">
      <h3 style="font-size:14px; margin-bottom:15px;">🏆 Ranking Mitra (Berdasarkan Spender/Omset)</h3>
      <p style="font-size:11px; color:var(--muted); margin-bottom:15px;">Daftar peringkat mitra berdasarkan total omset penjualan.</p>
      <div class="tw">
        <table class="member-table">
          <thead><tr><th>Peringkat</th><th>Nama Mitra</th><th>Level</th><th>Total Omset</th></tr></thead>
          <tbody>
          <?php
          $ranked_mitras = $mitras;
          usort($ranked_mitras, function($a, $b) {
              return ($b['total_omset'] ?? 0) <=> ($a['total_omset'] ?? 0);
          });
          $rank = 1;
          foreach($ranked_mitras as $p): 
              $lvl = $p['mitra_level'] ?? 'bronze';
              $lvlColor = $lvl === 'gold' ? '#ffcc00' : ($lvl === 'silver' ? '#c0c0c0' : '#cd7f32');
          ?>
            <tr>
              <td data-label="Peringkat" style="font-weight:bold; font-size:14px; color:#aa88ff;">#<?php echo $rank++; ?></td>
              <td data-label="Nama Mitra" style="font-weight:bold;"><?php echo htmlspecialchars($p['name']); ?></td>
              <td data-label="Level"><span style="display:inline-block; padding:2px 8px; border-radius:4px; font-size:10px; font-weight:bold; background:<?php echo $lvlColor; ?>20; color:<?php echo $lvlColor; ?>; border:1px solid <?php echo $lvlColor; ?>; text-transform:uppercase;"><?php echo htmlspecialchars($lvl); ?></span></td>
              <td data-label="Total Omset" style="font-weight:bold; color:#00e676;">Rp <?php echo number_format($p['total_omset'] ?? 0, 0, ',', '.'); ?></td>
            </tr>
          <?php endforeach; if(empty($ranked_mitras)): ?>
            <tr><td colspan="4" class="empty">Belum ada mitra.</td></tr>
          <?php endif; ?>
          </tbody>
        </table>
      </div>
    </div>

    <!-- COOKIE SERVER STATUS -->
    <div style="margin-top: 30px; border-top: 1px solid var(--border); padding-top: 20px;">
      <h3 style="font-size:14px; margin-bottom:15px;">🍪 Status Cookie Server</h3>
      <p style="font-size:11px; color:var(--muted); margin-bottom:15px;">Status cookies yang terinjeksi. Monitoring keaktifen sesi per server.</p>
      <div style="display:grid; grid-template-columns:repeat(auto-fill, minmax(280px, 1fr)); gap:12px;">
      <?php
      $cookiesData = loadData('cookies.json');
      $allApps = loadData('applications.json');
      $appNames = [];
      foreach($allApps as $a) { $appNames[$a['id']] = $a['name']; }
      
      if (empty($cookiesData)): ?>
        <div style="grid-column:1/-1;text-align:center;padding:20px;color:var(--muted);font-size:13px;">Belum ada cookie yang diinjeksi.</div>
      <?php else: foreach($cookiesData as $c):
        $app_name = $appNames[$c['app_id']] ?? $c['app_id'];
        $updated = $c['updated_at'] ?? 'Unknown';
        $updated_by = $c['updated_by'] ?? 'System';
        
        $hours_ago = 999;
        if ($updated !== 'Unknown') {
            $diff_s = time() - strtotime($updated);
            $hours_ago = round($diff_s / 3600, 1);
        }
        
        if ($hours_ago < 6) { $status_color = '#00e676'; $status_text = 'Active'; $status_icon = '🟢'; }
        elseif ($hours_ago < 18) { $status_color = '#ffaa00'; $status_text = 'Expiring'; $status_icon = '🟡'; }
        else { $status_color = '#ff4d4d'; $status_text = 'Expired'; $status_icon = '🔴'; }
      ?>
        <div style="background:var(--glass); border:1px solid var(--border); border-radius:10px; padding:14px; border-left:3px solid <?php echo $status_color; ?>;">
          <div style="display:flex; justify-content:space-between; align-items:center; margin-bottom:8px;">
            <strong style="font-size:12px;"><?php echo htmlspecialchars($app_name); ?> #<?php echo $c['server_index']; ?></strong>
            <span style="font-size:10px; color:<?php echo $status_color; ?>; font-weight:bold;"><?php echo $status_icon; ?> <?php echo $status_text; ?></span>
          </div>
          <div style="font-size:10px; color:var(--muted);">Diperbarui: <?php echo $updated; ?></div>
          <div style="font-size:10px; color:var(--muted);">Oleh: <?php echo htmlspecialchars($updated_by); ?></div>
          <div style="font-size:10px; color:<?php echo $status_color; ?>; margin-top:4px;" id="countdown-<?php echo $c['app_id'].'_'.$c['server_index']; ?>" data-updated="<?php echo $updated; ?>">-</div>
        </div>
      <?php endforeach; endif; ?>
      </div>
    </div>

    <!-- REGISTRASI MITRA BARU -->
    <div style="margin-top: 30px; border-top: 1px solid var(--border); padding-top: 20px;">
      <h3 style="font-size:14px; margin-bottom: 10px;">Registrasi Mitra Baru</h3>
      <form method="POST" style="display:flex; flex-direction:column; gap:10px;">
        <input type="hidden" name="action" value="add_mitra"/>
        <div style="display:flex; gap:10px; flex-wrap:wrap;">
            <div style="flex:1; min-width:200px;"><label style="font-size:10px;color:var(--muted);">Nama Perusahaan / Mitra</label><input type="text" name="new_mitra_name" required/></div>
            <div style="flex:1; min-width:200px;"><label style="font-size:10px;color:var(--muted);">Email</label><input type="email" name="new_mitra_email" required/></div>
            <div style="flex:1; min-width:200px;"><label style="font-size:10px;color:var(--muted);">No. Telepon / WhatsApp</label><input type="text" name="new_mitra_phone" required/></div>
        </div>
        <div style="display:flex; gap:10px; flex-wrap:wrap; align-items:flex-end; margin-top:10px;">
            <div style="flex:2; min-width:200px;"><label style="font-size:10px;color:var(--muted);">Alamat Lengkap</label><input type="text" name="new_mitra_address"/></div>
            <div style="flex:1; min-width:120px;"><label style="font-size:10px;color:var(--muted);">Komisi Basic (Rp)</label><input type="number" name="new_mitra_commission_basic" min="0" value="10000" required/></div>
            <div style="flex:1; min-width:120px;"><label style="font-size:10px;color:var(--muted);">Komisi Pro (Rp)</label><input type="number" name="new_mitra_commission_pro" min="0" value="20000" required/></div>
            <div style="flex:1; min-width:120px;"><label style="font-size:10px;color:var(--muted);">Komisi Ult (Rp)</label><input type="number" name="new_mitra_commission_ultimate" min="0" value="30000" required/></div>
            <div style="flex:1; min-width:150px;"><label style="font-size:10px;color:var(--muted);">Batas Minus</label><input type="number" name="new_mitra_minus_limit" max="0" step="50000" value="-500000"/></div>
            <div style="flex:1; min-width:150px;"><label style="font-size:10px;color:var(--muted);">Level Mitra</label><select name="new_mitra_level" style="padding:11px; border-radius:6px; background:rgba(0,20,50,.6); color:var(--text); border:1px solid var(--border); width:100%;"><option value="bronze">Bronze</option><option value="silver">Silver</option><option value="gold">Gold</option></select></div>
            <div style="flex:1; min-width:150px;"><label style="font-size:10px;color:var(--muted);">Password Akun</label><input type="text" name="new_mitra_pass" required/></div>
            <button type="submit" class="btn bp" style="margin:0; height:fit-content; padding: 11px 20px;">+ Daftarkan Mitra</button>
        </div>
      </form>
    </div>
  </div>
</div>
<?php endif; ?>

<!-- NOTEPAD & ACCOUNT MANAGER TAB -->
<div id="tab-notepad" class="tab-content <?php echo $tab==='notepad'?'active':''; ?>">
<?php
// =============================================
// NOTEPAD & ACCOUNTS - Backend Handlers
// =============================================
$notepad_file = DATA_DIR . '/notepad.json';
$accounts_file = DATA_DIR . '/accounts.json';

// Load data
$notepad_data = file_exists($notepad_file) ? json_decode(file_get_contents($notepad_file), true) : ['content' => '', 'updated_at' => null, 'updated_by' => null];
$accounts_data = file_exists($accounts_file) ? json_decode(file_get_contents($accounts_file), true) : [];

// Handle POST actions
if ($_SERVER['REQUEST_METHOD'] === 'POST' && isset($_POST['action'])) {
    $np_action = $_POST['action'];
    
    if ($np_action === 'save_note') {
        $notepad_data['content'] = $_POST['note_content'] ?? '';
        $notepad_data['updated_at'] = date('Y-m-d H:i:s');
        $notepad_data['updated_by'] = $_SESSION['user_name'] ?? 'System';
        file_put_contents($notepad_file, json_encode($notepad_data, JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE));
        $msg = 'Catatan berhasil disimpan.'; $msgType = 'success';
    }
    
    if ($np_action === 'save_account') {
        $acc = [
            'id' => uniqid('acc_'),
            'label' => trim($_POST['acc_label'] ?? ''),
            'email' => trim($_POST['acc_email'] ?? ''),
            'password' => trim($_POST['acc_password'] ?? ''),
            'url' => trim($_POST['acc_url'] ?? ''),
            'notes' => trim($_POST['acc_notes'] ?? ''),
            'created_at' => date('Y-m-d H:i:s'),
            'created_by' => $_SESSION['user_name'] ?? 'System'
        ];
        if (!empty($acc['label']) && !empty($acc['email'])) {
            $accounts_data[] = $acc;
            file_put_contents($accounts_file, json_encode($accounts_data, JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE));
            $msg = 'Akun "' . htmlspecialchars($acc['label']) . '" berhasil disimpan.'; $msgType = 'success';
        }
    }
    
    if ($np_action === 'delete_account') {
        $del_id = $_POST['acc_id'] ?? '';
        $accounts_data = array_values(array_filter($accounts_data, function($a) use ($del_id) { return ($a['id'] ?? '') !== $del_id; }));
        file_put_contents($accounts_file, json_encode($accounts_data, JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE));
        $msg = 'Akun berhasil dihapus.'; $msgType = 'info';
    }
    
    // Reload data after save
    $notepad_data = file_exists($notepad_file) ? json_decode(file_get_contents($notepad_file), true) : ['content' => '', 'updated_at' => null, 'updated_by' => null];
    $accounts_data = file_exists($accounts_file) ? json_decode(file_get_contents($accounts_file), true) : [];
}
?>

  <!-- NOTEPAD SECTION -->
  <div class="card">
    <div class="ct">📝 Notepad Pribadi</div>
    <div style="font-size:11px; color:var(--muted); margin-bottom:15px;">
      Catatan pribadi untuk Owner & Admin. Hanya bisa diakses dari dashboard ini.
      <?php if ($notepad_data['updated_at']): ?>
        <span style="float:right; color:var(--muted); font-size:10px;">Terakhir disimpan: <?php echo $notepad_data['updated_at']; ?> oleh <?php echo htmlspecialchars($notepad_data['updated_by'] ?? '-'); ?></span>
      <?php endif; ?>
    </div>
    <form method="POST" action="?tab=notepad">
      <input type="hidden" name="action" value="save_note"/>
      <textarea name="note_content" id="notepad_content" style="width:100%; min-height:250px; background:rgba(0,15,40,.8); border:1px solid var(--border); border-radius:10px; padding:16px; color:var(--text); font-family:'Inter',monospace; font-size:13px; line-height:1.7; resize:vertical; outline:none; transition:border-color .2s;" placeholder="Tulis catatan di sini... (bisa untuk tracking, todo list, info penting, dll)"><?php echo htmlspecialchars($notepad_data['content'] ?? ''); ?></textarea>
      <div style="display:flex; justify-content:space-between; align-items:center; margin-top:10px;">
        <span id="notepad_status" style="font-size:10px; color:var(--muted);"></span>
        <button type="submit" class="btn bp" style="padding:8px 20px;">💾 Simpan Catatan</button>
      </div>
    </form>
  </div>

  <!-- SAVED ACCOUNTS SECTION -->
  <div class="card">
    <div class="ct">🔐 Akun Tersimpan</div>
    <div style="font-size:11px; color:var(--muted); margin-bottom:15px;">
      Simpan detail akun (email, password, URL login) untuk referensi cepat. Semua data tersimpan di server dan terenkripsi secara lokal.
    </div>

    <!-- Add New Account Form -->
    <div style="background:rgba(0,100,255,0.06); border:1px solid rgba(0,100,255,0.15); border-radius:12px; padding:18px; margin-bottom:20px;">
      <h4 style="font-size:12px; color:var(--bright); margin-bottom:12px; font-weight:700;">➕ Tambah Akun Baru</h4>
      <form method="POST" action="?tab=notepad">
        <input type="hidden" name="action" value="save_account"/>
        <div style="display:grid; grid-template-columns:1fr 1fr; gap:10px;">
          <div>
            <label style="font-size:9px;">Label / Nama Layanan</label>
            <input type="text" name="acc_label" placeholder="Contoh: Google Flow Akun 1" required/>
          </div>
          <div>
            <label style="font-size:9px;">URL Login</label>
            <input type="url" name="acc_url" placeholder="https://example.com/login"/>
          </div>
          <div>
            <label style="font-size:9px;">Email / Username</label>
            <input type="text" name="acc_email" placeholder="email@gmail.com" required/>
          </div>
          <div>
            <label style="font-size:9px;">Password</label>
            <input type="text" name="acc_password" placeholder="Password akun"/>
          </div>
          <div style="grid-column:1/-1;">
            <label style="font-size:9px;">Catatan Tambahan (Opsional)</label>
            <input type="text" name="acc_notes" placeholder="Recovery email, 2FA info, dll"/>
          </div>
        </div>
        <div style="margin-top:12px; text-align:right;">
          <button type="submit" class="btn bp" style="padding:8px 18px;">➕ Simpan Akun</button>
        </div>
      </form>
    </div>

    <!-- Account Cards -->
    <?php if (empty($accounts_data)): ?>
      <div style="text-align:center; padding:40px; color:var(--muted);">
        <div style="font-size:40px; margin-bottom:10px; opacity:0.3;">🔐</div>
        <div style="font-size:13px;">Belum ada akun tersimpan.</div>
        <div style="font-size:11px; margin-top:5px;">Gunakan form di atas untuk menyimpan detail akun.</div>
      </div>
    <?php else: ?>
      <div style="display:grid; grid-template-columns:repeat(auto-fill, minmax(320px, 1fr)); gap:14px;">
        <?php foreach ($accounts_data as $acc): ?>
          <div class="acc-card" style="background:linear-gradient(135deg, rgba(0,40,100,.4), rgba(0,20,60,.6)); border:1px solid var(--border); border-radius:12px; padding:16px; position:relative; transition:all .2s; border-left:3px solid var(--bright);">
            <!-- Header -->
            <div style="display:flex; justify-content:space-between; align-items:flex-start; margin-bottom:12px;">
              <div>
                <div style="font-size:14px; font-weight:800; color:var(--text); margin-bottom:2px;"><?php echo htmlspecialchars($acc['label'] ?? '-'); ?></div>
                <div style="font-size:9px; color:var(--muted);">Ditambahkan: <?php echo $acc['created_at'] ?? '-'; ?></div>
              </div>
              <form method="POST" action="?tab=notepad" style="margin:0;" onsubmit="return confirm('Hapus akun ini?')">
                <input type="hidden" name="action" value="delete_account"/>
                <input type="hidden" name="acc_id" value="<?php echo htmlspecialchars($acc['id'] ?? ''); ?>"/>
                <button type="submit" style="background:rgba(255,60,60,.15); border:1px solid rgba(255,60,60,.3); color:#ff4d4d; padding:4px 8px; border-radius:6px; cursor:pointer; font-size:10px; font-family:inherit;">🗑</button>
              </form>
            </div>

            <!-- URL -->
            <?php if (!empty($acc['url'])): ?>
            <div style="margin-bottom:8px;">
              <div style="font-size:9px; color:var(--muted); text-transform:uppercase; letter-spacing:.5px; margin-bottom:3px;">🌐 URL Login</div>
              <div style="display:flex; align-items:center; gap:6px; background:rgba(0,10,30,.5); padding:7px 10px; border-radius:6px; border:1px solid rgba(255,255,255,.05);">
                <a href="<?php echo htmlspecialchars($acc['url']); ?>" target="_blank" style="flex:1; color:var(--bright); font-size:12px; text-decoration:none; word-break:break-all;"><?php echo htmlspecialchars($acc['url']); ?></a>
                <button type="button" onclick="copyText('<?php echo htmlspecialchars(addslashes($acc['url'])); ?>', this)" style="background:rgba(0,150,255,.15); border:1px solid rgba(0,150,255,.3); color:var(--bright); padding:3px 8px; border-radius:4px; cursor:pointer; font-size:10px; font-family:inherit; white-space:nowrap;" title="Copy URL">📋</button>
              </div>
            </div>
            <?php endif; ?>

            <!-- Email -->
            <div style="margin-bottom:8px;">
              <div style="font-size:9px; color:var(--muted); text-transform:uppercase; letter-spacing:.5px; margin-bottom:3px;">📧 Email / Username</div>
              <div style="display:flex; align-items:center; gap:6px; background:rgba(0,10,30,.5); padding:7px 10px; border-radius:6px; border:1px solid rgba(255,255,255,.05);">
                <span style="flex:1; font-size:12px; color:var(--text); word-break:break-all;"><?php echo htmlspecialchars($acc['email'] ?? '-'); ?></span>
                <button type="button" onclick="copyText('<?php echo htmlspecialchars(addslashes($acc['email'] ?? '')); ?>', this)" style="background:rgba(0,150,255,.15); border:1px solid rgba(0,150,255,.3); color:var(--bright); padding:3px 8px; border-radius:4px; cursor:pointer; font-size:10px; font-family:inherit; white-space:nowrap;" title="Copy Email">📋</button>
              </div>
            </div>

            <!-- Password -->
            <?php if (!empty($acc['password'])): ?>
            <div style="margin-bottom:8px;">
              <div style="font-size:9px; color:var(--muted); text-transform:uppercase; letter-spacing:.5px; margin-bottom:3px;">🔑 Password</div>
              <div style="display:flex; align-items:center; gap:6px; background:rgba(0,10,30,.5); padding:7px 10px; border-radius:6px; border:1px solid rgba(255,255,255,.05);">
                <span class="pwd-mask" style="flex:1; font-size:12px; color:#ffaa00; font-family:monospace; letter-spacing:1px; word-break:break-all;" data-pwd="<?php echo htmlspecialchars($acc['password']); ?>">••••••••</span>
                <button type="button" onclick="togglePwd(this)" style="background:rgba(255,170,0,.12); border:1px solid rgba(255,170,0,.3); color:#ffaa00; padding:3px 8px; border-radius:4px; cursor:pointer; font-size:10px; font-family:inherit; white-space:nowrap;" title="Tampilkan/Sembunyikan">👁</button>
                <button type="button" onclick="copyText('<?php echo htmlspecialchars(addslashes($acc['password'])); ?>', this)" style="background:rgba(0,150,255,.15); border:1px solid rgba(0,150,255,.3); color:var(--bright); padding:3px 8px; border-radius:4px; cursor:pointer; font-size:10px; font-family:inherit; white-space:nowrap;" title="Copy Password">📋</button>
              </div>
            </div>
            <?php endif; ?>

            <!-- Notes -->
            <?php if (!empty($acc['notes'])): ?>
            <div style="margin-top:8px; padding:8px 10px; background:rgba(255,255,255,.03); border-radius:6px; border:1px solid rgba(255,255,255,.05);">
              <div style="font-size:9px; color:var(--muted); margin-bottom:3px;">📌 Catatan</div>
              <div style="font-size:11px; color:var(--sub);"><?php echo htmlspecialchars($acc['notes']); ?></div>
            </div>
            <?php endif; ?>
          </div>
        <?php endforeach; ?>
      </div>
    <?php endif; ?>
  </div>
</div>

<?php if ($role === 'owner'): 
$finance = loadData('finance.json');
$withdrawn = $finance['total_withdrawn'] ?? 0;
$shares = $finance['profit_shares'] ?? [];
$history = $finance['history'] ?? [];
// Calculate Gross All Time
$all_time_gross = 0;
foreach (loadData('members.json') as $am) {
    $all_time_gross += (int)($am['price_paid'] ?? 0);
}
$net_balance = max(0, $all_time_gross - $withdrawn);
?>
<!-- FINANCE TAB -->
<div id="tab-finance" class="tab-content <?php echo $tab==='finance'?'active':''; ?>">
  <div style="display:grid; grid-template-columns:repeat(auto-fit, minmax(250px, 1fr)); gap:15px; margin-bottom:20px;">
    <div class="sc r" style="background:rgba(0,150,255,0.1); border-color:rgba(0,150,255,0.3);">
      <div class="sv" style="color:#0096ff; font-size:20px;">Rp <?php echo number_format($all_time_gross,0,',','.'); ?></div>
      <div class="sl" style="color:#0096ff;">Total Pendapatan Kotor (All Time)</div>
    </div>
    <div class="sc r" style="background:rgba(255,170,0,0.1); border-color:rgba(255,170,0,0.3);">
      <div class="sv" style="color:#ffaa00; font-size:20px;">Rp <?php echo number_format($withdrawn,0,',','.'); ?></div>
      <div class="sl" style="color:#ffaa00;">Total Sudah Ditarik (Tutup Buku)</div>
    </div>
    <div class="sc r" style="background:rgba(0,230,118,0.1); border-color:rgba(0,230,118,0.3);">
      <div class="sv" style="color:#00e676; font-size:20px;">Rp <?php echo number_format($net_balance,0,',','.'); ?></div>
      <div class="sl" style="color:#00e676;">Saldo Belum Ditarik (Bersih)</div>
    </div>
  </div>

  <div style="display:flex; flex-wrap:wrap; gap:20px;">
    <!-- Form Tutup Buku Manual -->
    <div class="sc" style="flex:1; min-width:300px;">
      <h3 style="margin-bottom:15px; color:var(--bright); border-bottom:1px solid var(--border); padding-bottom:10px;">📉 Tutup Buku / Tarik Saldo</h3>
      <form method="POST" action="?tab=finance">
        <input type="hidden" name="action" value="finance_withdraw"/>
        <div class="fi full">
          <label>Jumlah Penarikan (Rp)</label>
          <input type="number" name="amount" min="1" max="<?php echo $net_balance; ?>" required placeholder="Contoh: 1500000" />
        </div>
        <div class="fi full">
          <label>Catatan / Keterangan</label>
          <input type="text" name="note" required placeholder="Contoh: Penarikan profit tgl 1-14" />
        </div>
        <button type="submit" class="btn" style="width:100%;" onclick="return confirm('Anda yakin ingin menarik saldo ini? Total pendapatan di dashboard akan otomatis berkurang.')">Tarik Saldo & Tutup Buku</button>
      </form>
    </div>

    <!-- Form Pengaturan Bagi Hasil -->
    <div class="sc" style="flex:1; min-width:300px;">
      <h3 style="margin-bottom:15px; color:var(--bright); border-bottom:1px solid var(--border); padding-bottom:10px;">⚙️ Pengaturan Bagi Hasil</h3>
      <form method="POST" action="?tab=finance">
        <input type="hidden" name="action" value="finance_save_shares"/>
        <div id="shares-container">
          <?php if (empty($shares)): ?>
          <div style="display:flex; gap:10px; margin-bottom:10px;">
            <input type="text" name="share_name[]" placeholder="Nama / Role" style="flex:2;" required />
            <input type="number" name="share_percent[]" placeholder="Persentase (%)" style="flex:1;" min="1" max="100" required />
          </div>
          <?php else: foreach ($shares as $ps): ?>
          <div style="display:flex; gap:10px; margin-bottom:10px;">
            <input type="text" name="share_name[]" value="<?php echo htmlspecialchars($ps['name']); ?>" placeholder="Nama / Role" style="flex:2;" required />
            <input type="number" name="share_percent[]" value="<?php echo $ps['percent']; ?>" placeholder="Persentase (%)" style="flex:1;" min="1" max="100" required />
          </div>
          <?php endforeach; endif; ?>
        </div>
        <button type="button" class="btn bt" onclick="addShareField()" style="margin-bottom:10px; font-size:11px;">+ Tambah Pihak</button>
        <button type="submit" class="btn bsm" style="width:100%; background:#107c41; color:#fff; border:none;">Simpan Pengaturan</button>
      </form>
    </div>

    <!-- Kalkulator & Distribusi Bagi Hasil -->
    <div class="sc" style="flex:1; min-width:300px;">
      <h3 style="margin-bottom:15px; color:var(--bright); border-bottom:1px solid var(--border); padding-bottom:10px;">🧮 Distribusi Bagi Hasil</h3>
      <form method="POST" action="?tab=finance" id="distributeForm">
        <input type="hidden" name="action" value="finance_distribute"/>
        <div class="fi full">
          <label>Total Dana yang Dibagikan (Rp)</label>
          <input type="number" name="amount" id="distAmount" min="1" max="<?php echo $net_balance; ?>" required placeholder="Contoh: 1000000" oninput="calcShares()" />
        </div>
        <div class="fi full">
          <label>Keterangan</label>
          <input type="text" name="note" required placeholder="Contoh: Bagi Hasil Akhir Bulan" />
        </div>
        <div id="sharePreview" style="background:rgba(0,0,0,0.2); padding:10px; border-radius:6px; margin-bottom:15px; font-size:12px; color:var(--muted); min-height:50px;">
          <i>Masukkan jumlah untuk melihat kalkulasi...</i>
        </div>
        <button type="submit" class="btn" style="width:100%; background:linear-gradient(135deg, #0096ff, #0066cc); color:#fff; border:none;" onclick="return confirm('Bagikan profit dan potong saldo utama?')">Proses Bagi Hasil</button>
      </form>
    </div>
  </div>

  <div class="sc mt-4" style="margin-top:20px;">
    <h3 style="margin-bottom:15px; color:var(--bright);">📜 Riwayat Transaksi & Tutup Buku</h3>
    <div class="tw">
      <table>
        <thead>
          <tr>
            <th>Tanggal</th>
            <th>Tipe</th>
            <th>Jumlah</th>
            <th>Keterangan / Detail</th>
          </tr>
        </thead>
        <tbody>
          <?php if(empty($history)): ?>
          <tr><td colspan="4" style="text-align:center;color:var(--muted);">Belum ada riwayat transaksi</td></tr>
          <?php else: foreach($history as $h): ?>
          <tr>
            <td><?php echo $h['date']; ?></td>
            <td><span style="background:rgba(0,150,255,.1); color:#0096ff; padding:2px 6px; border-radius:4px; font-size:10px; border:1px solid rgba(0,150,255,.3);"><?php echo htmlspecialchars($h['type'] ?? 'Tutup Buku'); ?></span></td>
            <td style="color:#ffaa00;">Rp <?php echo number_format($h['amount'],0,',','.'); ?></td>
            <td style="font-size:11px; max-width:300px; line-height:1.4;"><?php echo htmlspecialchars($h['note']); ?></td>
          </tr>
          <?php endforeach; endif; ?>
        </tbody>
      </table>
    </div>
  </div>
</div>
<script>
function addShareField() {
    const div = document.createElement('div');
    div.style.cssText = 'display:flex; gap:10px; margin-bottom:10px;';
    div.innerHTML = `
        <input type="text" name="share_name[]" placeholder="Nama / Role" style="flex:2;" required />
        <input type="number" name="share_percent[]" placeholder="Persentase (%)" style="flex:1;" min="1" max="100" required />
        <button type="button" class="btn bt" style="padding:0 10px; background:rgba(255,40,40,.2); color:#ff4d4d;" onclick="this.parentElement.remove()">X</button>
    `;
    document.getElementById('shares-container').appendChild(div);
}
function calcShares() {
    const amt = parseFloat(document.getElementById('distAmount').value) || 0;
    const preview = document.getElementById('sharePreview');
    const shares = <?php echo json_encode($shares); ?>;
    if (shares.length === 0) {
        preview.innerHTML = '<span style="color:#ff6666;">Silakan simpan pengaturan persentase bagi hasil terlebih dahulu.</span>';
        return;
    }
    if (amt <= 0) {
        preview.innerHTML = '<i>Masukkan jumlah untuk melihat kalkulasi...</i>';
        return;
    }
    
    let html = '<div style="margin-bottom:5px; font-weight:bold; color:var(--bright);">Estimasi Pembagian:</div>';
    let totalPct = 0;
    shares.forEach(s => {
        const val = (amt * s.percent) / 100;
        totalPct += parseFloat(s.percent);
        html += `<div style="display:flex; justify-content:space-between; margin-bottom:3px;">
            <span>${s.name} (${s.percent}%)</span>
            <span style="color:#00e676;">Rp ${val.toLocaleString('id-ID')}</span>
        </div>`;
    });
    if (totalPct !== 100) {
        html += `<div style="margin-top:5px; color:#ff6666; font-size:10px;">⚠️ Total persentase saat ini: ${totalPct}% (Seharusnya 100%)</div>`;
    }
    preview.innerHTML = html;
}
</script>
<?php endif; ?>

<p style="text-align:center;font-size:10px;color:var(--muted);opacity:.5;margin-top:30px">TEKNO-APPS Member Manager &copy; 2026 (JSON Mode)</p>
</div>
<script>
const PKG_PRICES = <?php echo json_encode($pkg_prices); ?>;

function recalculatePrice() {
    const daysInput = document.getElementById('add_days');
    const pkgInput = document.getElementById('add_pkg_val');
    const manualPriceInput = document.getElementById('add_manual_price');
    
    if (daysInput && pkgInput && manualPriceInput) {
        const days = parseInt(daysInput.value) || 0;
        const pkg = pkgInput.value || 'basic';
        const basePrice = PKG_PRICES[pkg] || 0;
        
        const calculatedPrice = Math.round((basePrice / 30) * days);
        manualPriceInput.placeholder = `Otomatis: Rp ${calculatedPrice.toLocaleString('id-ID')}`;
        if (pkg === 'custom') {
            manualPriceInput.placeholder = 'Harga wajib diisi (misal: 250000)';
        }
    }
}

document.addEventListener('DOMContentLoaded', () => {
    recalculatePrice();
});

function addServerRow(containerId) {
    const container = document.getElementById(containerId);
    const row = document.createElement('div');
    row.className = 'srv-row';
    row.style.cssText = 'display:flex; gap:10px; margin-bottom:8px;';
    row.innerHTML = `
        <input type="text" name="server_names[]" placeholder="Nama Server (Misal: Flow 1)" style="flex:1;" required/>
        <input type="url" name="server_urls[]" placeholder="URL Target (Opsional)" style="flex:2;"/>
        <button type="button" class="btn bsm bd" onclick="this.parentElement.remove()">X</button>
    `;
    container.appendChild(row);
}
function setDays(d) {
  document.getElementById('add_days').value = d;
  document.querySelectorAll('.dur-btn').forEach(b => b.classList.remove('selected'));
  const btn = document.querySelector('.dur-btn[data-days="'+d+'"]');
  if(btn) btn.classList.add('selected');
  const customInput = document.getElementById('custom_days_input');
  if(customInput && customInput.value != d) customInput.value = '';
  recalculatePrice();
}
function setCustomDays(d) {
  if(d && d > 0) {
    document.getElementById('add_days').value = d;
    document.querySelectorAll('.dur-btn').forEach(b => b.classList.remove('selected'));
    recalculatePrice();
  } else {
    setDays(7); // fallback
  }
}

function switchTab(tabId) {
    document.querySelectorAll('.tab-btn').forEach(b => b.classList.remove('active'));
    document.querySelectorAll('.tab-content').forEach(c => c.classList.remove('active'));
    const btn = document.querySelector(".tab-btn[onclick=\"switchTab('" + tabId + "')\"]");
    if (btn) btn.classList.add('active');
    const tab = document.getElementById('tab-' + tabId);
    if (tab) tab.classList.add('active');
    
    // Update URL without reloading the page
    const url = new URL(window.location);
    url.searchParams.set('tab', tabId);
    // Don't lose target if we are on packages tab
    if (tabId === 'packages') {
        const target = document.getElementById('pkg_target')?.value || 'main';
        url.searchParams.set('target', target);
    } else {
        url.searchParams.delete('target');
    }
    window.history.pushState({}, '', url);
}

function toggleMenu(btn) {
    const menu = btn.nextElementSibling;
    const isVisible = menu.classList.contains('show');
    
    // Close any other open menus
    document.querySelectorAll('.act-menu.show').forEach(m => {
        m.classList.remove('show');
    });
    
    // Toggle current menu
    if (!isVisible) {
        menu.classList.add('show');
    }
}

// Close menu when clicking outside
window.addEventListener('click', function(event) {
    if (!event.target.matches('.act-btn')) {
        document.querySelectorAll('.act-menu.show').forEach(m => {
            m.classList.remove('show');
        });
    }
});

window.addEventListener('load', () => {
    const urlParams = new URLSearchParams(window.location.search);
    if (urlParams.has('edit_app') || urlParams.get('tab') === 'apps') switchTab('apps');
    else if (urlParams.has('edit') || urlParams.get('tab') === 'members') switchTab('members');
    else if (urlParams.get('tab') === 'settings') switchTab('settings');
    if (!urlParams.has('edit')) setPkg('add', 'basic');
});

const APP_MAX = <?php echo json_encode($APP_MAX); ?>;
const COOKIE_META = <?php echo json_encode($cookieMeta); ?>;

function updateCookieInfo() {
    const appId = document.getElementById('c-app').value;
    const srvIdx = document.getElementById('c-server').value;
    const infoDiv = document.getElementById('c-info');
    
    if (appId && srvIdx) {
        const key = appId + '_' + srvIdx;
        infoDiv.style.display = 'block';
        if (COOKIE_META[key]) {
            infoDiv.innerHTML = '&#x2139;&#xFE0F; Cookies terakhir diubah oleh: <strong style="color:var(--bright)">' + COOKIE_META[key].updated_by + '</strong> pada <span style="color:var(--muted)">' + COOKIE_META[key].updated_at + '</span>';
            infoDiv.style.borderLeft = '3px solid var(--bright)';
        } else {
            infoDiv.innerHTML = '&#x26A0;&#xFE0F; Belum ada cookies yang disimpan untuk server ini.';
            infoDiv.style.borderLeft = '3px solid var(--warn)';
        }
    } else {
        infoDiv.style.display = 'none';
    }
}

document.getElementById('c-app').addEventListener('change', function() {
    const APP_URLS = <?php echo json_encode($APP_URLS_PHP); ?>;
    const srvSelect = document.getElementById('c-server');
    const urlInput = document.getElementById('c-url');
    srvSelect.innerHTML = '<option value="">-- Pilih Server --</option>';
    const max = APP_MAX[this.value] || 0;
    if (APP_URLS[this.value]) urlInput.value = APP_URLS[this.value]; else urlInput.value = '';
    for (let i = 1; i <= max; i++) {
        const opt = document.createElement('option');
        opt.value = i; opt.textContent = 'Server ' + i;
        srvSelect.appendChild(opt);
    }
    updateCookieInfo();
});

async function loadExistingCookies() {
    const appId = document.getElementById('c-app').value;
    const srvIdx = document.getElementById('c-server').value;
    const urlInput = document.getElementById('c-url');
    const container = document.getElementById('cookie-payloads-container');
    
    if (!appId || !srvIdx) return;
    
    try {
        const res = await fetch(`index.php?action=get_cookies_info&app_id=${appId}&server_index=${srvIdx}`);
        const data = await res.json();
        
        container.innerHTML = ''; // Clear current inputs
        
        if (data.success && data.data && data.data.cookie_data && data.data.cookie_data.length > 0) {
            urlInput.value = data.data.target_url || '';
            
            data.data.cookie_data.forEach((payload, index) => {
                const div = document.createElement('div');
                div.className = 'cookie-payload-group';
                div.style.position = 'relative';
                div.innerHTML = `
                    <div style="font-size:10px; color:var(--light); margin-bottom:4px; font-weight:bold;">Payload ${index + 1}</div>
                    <textarea class="c-data-input" required></textarea>
                    <button type="button" onclick="this.parentElement.remove(); updatePayloadLabels();" style="position:absolute; top:0; right:0; background:none; border:none; color:var(--err); cursor:pointer; font-size:12px; font-weight:bold;">✕ Hapus</button>
                `;
                div.querySelector('textarea').value = JSON.stringify(payload);
                container.appendChild(div);
            });
        } else {
            // No data, show 1 empty box
            addCookiePayloadField();
        }
    } catch(err) {
        console.error("Failed to load existing cookies", err);
        container.innerHTML = '';
        addCookiePayloadField();
    }
}

document.getElementById('c-server').addEventListener('change', () => {
    updateCookieInfo();
    loadExistingCookies();
});

async function saveC() {
    const btn = document.getElementById('c-submit-btn');
    const msg = document.getElementById('c-msg');
    const app_id = document.getElementById('c-app').value;
    const server_index = document.getElementById('c-server').value;
    const target_url = document.getElementById('c-url').value;
    
    const textareas = document.querySelectorAll('.c-data-input');
    const payloads = [];
    let hasError = false;
    textareas.forEach(t => {
        const val = t.value.trim();
        if (val) {
            try {
                const parsed = JSON.parse(val);
                payloads.push(parsed);
            } catch(e) {
                hasError = true;
            }
        }
    });
    
    if (hasError) { msg.textContent = '❌ Ada JSON Payload yang tidak valid.'; msg.style.color = '#ff4d4d'; return; }
    if (!app_id || !server_index || payloads.length === 0) { msg.textContent = '❌ Mohon lengkapi parameter & minimal 1 payload.'; msg.style.color = '#ff4d4d'; return; }
    msg.textContent = 'Menyimpan...'; msg.style.color = '#4db8ff'; btn.disabled = true;
    try {
        const fd = new FormData();
        fd.append('app_id', app_id); fd.append('server_index', server_index);
        fd.append('target_url', target_url); fd.append('cookie_data', JSON.stringify(payloads));
        const res = await fetch('index.php?action=save_cookies', { method: 'POST', body: fd });
        const data = await res.json();
        if(data.success) { 
            msg.textContent = '✅ Berhasil! Data disimpan (' + data.payloads_count + ' payload).'; msg.style.color = '#00e676'; 
            // We intentionally DO NOT clear the textareas here so they remain visible
            // Update local meta
            const key = app_id + '_' + server_index;
            COOKIE_META[key] = { updated_by: '<?php echo addslashes($_SESSION["user_name"] ?? "System"); ?> (Baru saja)', updated_at: new Date().toLocaleString('id-ID') };
            updateCookieInfo();
            // Format the saved json nicely
            if (data.payload_data) {
                textareas.forEach((t, i) => {
                    if (data.payload_data[i]) t.value = JSON.stringify(data.payload_data[i]);
                });
            }
        }
        else { msg.textContent = '❌ Gagal: ' + (data.message || 'Error'); msg.style.color = '#ff4d4d'; }
    } catch(err) { msg.textContent = '❌ Error koneksi.'; msg.style.color = '#ff4d4d'; }
    finally { btn.disabled = false; setTimeout(() => { if(msg.textContent.includes('Berhasil')) msg.textContent=''; }, 5000); }
}

function setDays(d) {
  document.getElementById('add_days').value = d;
  document.querySelectorAll('.dur-btn').forEach(b => b.classList.remove('selected'));
  const btn = document.querySelector('.dur-btn[data-days="'+d+'"]');
  if(btn) btn.classList.add('selected');
  const customInput = document.getElementById('custom_days_input');
  if(customInput && customInput.value != d) customInput.value = '';
}
function setCustomDays(d) {
  if(d && d > 0) {
    document.getElementById('add_days').value = d;
    document.querySelectorAll('.dur-btn').forEach(b => b.classList.remove('selected'));
  } else {
    setDays(7); // fallback
  }
}

function setPkg(prefix, pkg) {
    document.getElementById(prefix + '_pkg_val').value = pkg;
    document.querySelectorAll('.pkg-btn').forEach(b => {
        if (b.closest('form') === document.getElementById(prefix + '_pkg_val').closest('form'))
            b.classList.toggle('selected', b.dataset.pkg === pkg);
    });
    
    // Get target config based on selected Mitra (if any)
    let target = 'main';
    const mitraDropdown = document.getElementById(prefix + '_mitra_id');
    if (mitraDropdown && mitraDropdown.value) {
        target = 'mitra_' + mitraDropdown.value;
    } else if (typeof MITRA_ID_FOR_JS !== 'undefined' && MITRA_ID_FOR_JS) {
        target = 'mitra_' + MITRA_ID_FOR_JS;
    }
    
    const config = (typeof PACKAGES_CONFIG !== 'undefined' ? (PACKAGES_CONFIG[target] || PACKAGES_CONFIG['main'] || {}) : {});
    const pkgData = config[pkg] || {};

    if (pkg !== 'custom') {
        const cc = document.getElementById(prefix + '_custom');
        if (cc) {
            cc.querySelectorAll('input[type="checkbox"]').forEach(chk => {
                const appId = chk.id.replace(prefix + '_', '');
                const srvInput = document.getElementById(prefix + '_' + appId + '_srv');
                
                let shouldCheck = false, srvCount = 1;
                if (pkgData[appId]) {
                    shouldCheck = true;
                    srvCount = pkgData[appId];
                }
                
                chk.checked = shouldCheck;
                chk.disabled = true; // Kunci jika bukan custom
                
                if (srvInput) { 
                    srvInput.disabled = true; // Kunci jika bukan custom
                    if (shouldCheck) srvInput.value = Math.min(srvCount, parseInt(srvInput.max)); 
                }
                
                toggleRowColor(prefix + '_row_' + appId, shouldCheck);
            });
        }
    } else {
        const cc = document.getElementById(prefix + '_custom');
        if (cc) {
            cc.querySelectorAll('input[type="checkbox"]').forEach(chk => {
                const appId = chk.id.replace(prefix + '_', '');
                const srvInput = document.getElementById(prefix + '_' + appId + '_srv');
                
                chk.disabled = false; // Buka kunci jika custom
                if (srvInput) { 
                    srvInput.disabled = !chk.checked; 
                }
                
                toggleRowColor(prefix + '_row_' + appId, chk.checked);
            });
        }
    }
    
    if (prefix === 'add') {
        recalculatePrice();
    }
}
function toggleSrv(inputId, enabled) { const el = document.getElementById(inputId); if (el) el.disabled = !enabled; }
function toggleRowColor(rowId, isChecked) {
    const row = document.getElementById(rowId);
    if (!row) return;
    if (isChecked) {
        row.style.background = 'rgba(0, 230, 118, 0.1)';
        row.style.borderLeft = '3px solid #00e676';
        row.style.opacity = '1';
        row.style.filter = 'none';
        const label = row.querySelector('label[for]');
        if (label) label.style.color = '#00e676';
        const srvLabel = row.querySelector('.srv-ctrl label');
        if (srvLabel) srvLabel.style.color = '#00e676';
        const srvInput = row.querySelector('.srv-ctrl input');
        if (srvInput) {
            srvInput.style.background = 'rgba(0, 230, 118, 0.15)';
            srvInput.style.borderColor = 'rgba(0, 230, 118, 0.3)';
            srvInput.style.color = '#00e676';
        }
    } else {
        row.style.background = 'transparent';
        row.style.borderLeft = 'none';
        row.style.opacity = '0.5';
        row.style.filter = 'grayscale(100%)';
        const label = row.querySelector('label[for]');
        if (label) label.style.color = 'var(--text)';
        const srvLabel = row.querySelector('.srv-ctrl label');
        if (srvLabel) srvLabel.style.color = 'var(--muted)';
        const srvInput = row.querySelector('.srv-ctrl input');
        if (srvInput) {
            srvInput.style.background = 'var(--deep)';
            srvInput.style.borderColor = 'var(--border)';
            srvInput.style.color = 'var(--text)';
        }
    }
}

// MAGIC HTML ANALYZER
function processHtmlToRules(htmlString) {
    const parser = new DOMParser();
    const doc = parser.parseFromString(htmlString, 'text/html');
    let rules = [];

    // Check for images with specific src or alt
    const imgs = doc.querySelectorAll('img');
    imgs.forEach(img => {
        if (img.alt) rules.push(`img[alt="${img.alt}"]`);
        else if (img.src && img.src.includes('googleusercontent')) rules.push(`img[src*="googleusercontent"]`);
    });

    // Extract deepest text nodes to formulate EXACT or TEXT rules
    const walker = document.createTreeWalker(doc.body, NodeFilter.SHOW_TEXT, null, false);
    let node;
    while (node = walker.nextNode()) {
        const text = node.nodeValue.trim();
        if (text.length >= 1 && text.length < 50) { // Support short text like "x4"
            const parent = node.parentElement;
            // If it looks like a menu item with an icon, use EXACT
            const hasIcon = parent.closest('button, div') && parent.closest('button, div').querySelector('i, svg, img');
            if (hasIcon) {
                rules.push(`EXACT:${text}`);
            } else {
                rules.push(`TEXT:${text}`);
            }
        }
    }

    // Deduplicate
    return [...new Set(rules)];
}

function analyzeHtml() {
    const input = document.getElementById('html_analyzer_input').value;
    if (!input.trim()) return alert('Paste kode HTML terlebih dahulu!');
    
    const newRules = processHtmlToRules(input);
    if (newRules.length === 0) return alert('Tidak menemukan teks atau gambar spesifik yang bisa diekstrak dari HTML ini.');

    const targetInput = document.getElementById('hidden_elements_input');
    let currentVal = targetInput.value.trim();
    
    if (currentVal && !currentVal.endsWith(',')) currentVal += ', ';
    else if (currentVal && currentVal.endsWith(',')) currentVal += ' ';
    
    targetInput.value = currentVal + newRules.join(', ');
    document.getElementById('html_analyzer_input').value = '';
    
    // Animate to show success
    targetInput.style.backgroundColor = 'rgba(0, 230, 118, 0.2)';
    setTimeout(() => targetInput.style.backgroundColor = '', 500);
}

function analyzeHtmlAdd() {
    const input = document.getElementById('html_analyzer_input_add').value;
    if (!input.trim()) return alert('Paste kode HTML terlebih dahulu!');
    
    const newRules = processHtmlToRules(input);
    if (newRules.length === 0) return alert('Tidak menemukan teks atau gambar spesifik yang bisa diekstrak dari HTML ini.');

    const targetInput = document.getElementById('hidden_elements_input_add');
    let currentVal = targetInput.value.trim();
    
    if (currentVal && !currentVal.endsWith(',')) currentVal += ', ';
    else if (currentVal && currentVal.endsWith(',')) currentVal += ' ';
    
    targetInput.value = currentVal + newRules.join(', ');
    document.getElementById('html_analyzer_input_add').value = '';
    
    // Animate to show success
    targetInput.style.backgroundColor = 'rgba(0, 230, 118, 0.2)';
    setTimeout(() => targetInput.style.backgroundColor = '', 500);
}

function addCookiePayloadField(val = '') {
    const container = document.getElementById('cookie-payloads-container');
    const div = document.createElement('div');
    div.className = 'cookie-payload-group';
    div.style.position = 'relative';
    div.innerHTML = `
        <div style="font-size:10px; color:var(--light); margin-bottom:4px; font-weight:bold;">Payload Baru</div>
        <textarea class="c-data-input" placeholder='[{"name":"session_id","value":"xyz","domain":".google.com",...}]' required></textarea>
        <button type="button" onclick="this.parentElement.remove(); updatePayloadLabels();" style="position:absolute; top:0; right:0; background:none; border:none; color:var(--err); cursor:pointer; font-size:12px; font-weight:bold;">✕ Hapus</button>
    `;
    div.querySelector('textarea').value = val;
    container.appendChild(div);
    updatePayloadLabels();
}

function updatePayloadLabels() {
    const groups = document.querySelectorAll('.cookie-payload-group');
    groups.forEach((g, i) => {
        g.querySelector('div').textContent = 'Payload ' + (i + 1);
    });
}
</script>
<script>
function submitFormAction(actionName, idValue) {
    const form = document.createElement('form');
    form.method = 'POST';
    form.style.display = 'none';
    
    const actionInput = document.createElement('input');
    actionInput.name = 'action';
    actionInput.value = actionName;
    form.appendChild(actionInput);
    
    const idInput = document.createElement('input');
    idInput.name = 'id';
    idInput.value = idValue;
    form.appendChild(idInput);
    
    document.body.appendChild(form);
    form.submit();
}



function promptResetMitra(mitraId) {
    document.getElementById('reset-mitra-id').value = mitraId;
    document.getElementById('reset-owner-pwd').value = '';
    const modal = document.getElementById('reset-mitra-modal');
    modal.style.display = 'flex';
}
function closeResetModal() {
    document.getElementById('reset-mitra-modal').style.display = 'none';
}

function deleteMitra(mitraId, mitraName) {
    document.getElementById('delete-mitra-id').value = mitraId;
    document.getElementById('delete-mitra-name').textContent = mitraName;
    document.getElementById('delete-mitra-modal').style.display = 'flex';
}
function closeDeleteModal() {
    document.getElementById('delete-mitra-modal').style.display = 'none';
}

// Top Up Modal
function showTopupModal(mitraId, mitraName) {
    document.getElementById('topup-mitra-id').value = mitraId;
    document.getElementById('topup-mitra-name').textContent = 'Mitra: ' + mitraName;
    const modal = document.getElementById('topup-modal');
    modal.style.display = 'flex';
}
function closeTopupModal() {
    document.getElementById('topup-modal').style.display = 'none';
}

// Mitra Config Modal
function showMitraConfigModal(mitraId, minusLimit, mitraLevel) {
    document.getElementById('config-mitra-id').value = mitraId;
    document.getElementById('config-minus-limit').value = minusLimit;
    document.getElementById('config-mitra-level').value = mitraLevel;
    const modal = document.getElementById('mitra-config-modal');
    modal.style.display = 'flex';
}
function closeMitraConfigModal() {
    document.getElementById('mitra-config-modal').style.display = 'none';
}

// Cookie Countdown Timers
function updateCookieCountdowns() {
    document.querySelectorAll('[id^="countdown-"]').forEach(el => {
        const updated = el.dataset.updated;
        if (!updated || updated === 'Unknown') { el.textContent = 'Tidak diketahui'; return; }
        const updatedTime = new Date(updated).getTime();
        const now = Date.now();
        const elapsed = now - updatedTime;
        const hours = Math.floor(elapsed / 3600000);
        const mins = Math.floor((elapsed % 3600000) / 60000);
        el.textContent = `${hours}j ${mins}m yang lalu`;
    });
}
updateCookieCountdowns();
setInterval(updateCookieCountdowns, 60000);

// =============================================
// NOTEPAD & ACCOUNT MANAGER JS
// =============================================
function copyText(text, btn) {
    navigator.clipboard.writeText(text).then(() => {
        const orig = btn.textContent;
        btn.textContent = '✅';
        btn.style.background = 'rgba(0,230,118,.2)';
        btn.style.borderColor = 'rgba(0,230,118,.4)';
        btn.style.color = '#00e676';
        setTimeout(() => {
            btn.textContent = orig;
            btn.style.background = '';
            btn.style.borderColor = '';
            btn.style.color = '';
        }, 1500);
    }).catch(() => {
        // Fallback for older browsers
        const ta = document.createElement('textarea');
        ta.value = text;
        ta.style.position = 'fixed';
        ta.style.opacity = '0';
        document.body.appendChild(ta);
        ta.select();
        document.execCommand('copy');
        document.body.removeChild(ta);
        btn.textContent = '✅';
        setTimeout(() => { btn.textContent = '📋'; }, 1500);
    });
}

function togglePwd(btn) {
    const pwdEl = btn.parentElement.querySelector('.pwd-mask');
    if (!pwdEl) return;
    const realPwd = pwdEl.getAttribute('data-pwd');
    if (pwdEl.textContent === '••••••••') {
        pwdEl.textContent = realPwd;
        btn.textContent = '🙈';
    } else {
        pwdEl.textContent = '••••••••';
        btn.textContent = '👁';
    }
}

// Notepad character counter
const notepadEl = document.getElementById('notepad_content');
const notepadStatus = document.getElementById('notepad_status');
if (notepadEl && notepadStatus) {
    const updateCount = () => {
        const len = notepadEl.value.length;
        notepadStatus.textContent = len + ' karakter';
    };
    notepadEl.addEventListener('input', updateCount);
    updateCount();
}
</script>
</body>
</html>
