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

// =============================================
// TEXA 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;
    $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,'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,'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,'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,'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,'is_active'=>1,'sort_order'=>5],
    ];
    saveData('applications.json', $apps);
}
seedApps();

// =============================================
// PACKAGE DEFINITIONS
// =============================================
$PACKAGES = [
    '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],
];
$PKG_LABELS = ['basic'=>'Basic','pro'=>'Pro','ultimate'=>'Ultimate','custom'=>'Custom'];

// 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'];
    $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']; }

// =============================================
// TEXA CANVAS-PRO MODE
// =============================================
if (isset($_GET['canvas']) || isset($_GET['admin']) && $_GET['admin'] == '1' && !isset($_GET['action'])) {
    $canvasHtmlPath = __DIR__ . '/canvas.html';
    if (file_exists($canvasHtmlPath)) {
        include $canvasHtmlPath;
    } else {
        echo "Error: canvas.html not found. Please upload the canvas HTML file to the inject directory.";
    }
    exit;
}

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

if ($action !== '') {
    header('Content-Type: application/json');
    header('Access-Control-Allow-Origin: *');
    header('Access-Control-Allow-Methods: GET, POST, OPTIONS');
    header('Access-Control-Allow-Headers: Content-Type');
    if ($_SERVER['REQUEST_METHOD'] === 'OPTIONS') { http_response_code(200); exit(); }

    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 === '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) {
                if (!$m['is_active']) { echo json_encode(['valid'=>false,'reason'=>'inactive']); exit(); }
                if (!empty($m['active_device_id']) && $m['active_device_id'] !== $device_id) {
                    echo json_encode(['valid'=>false,'reason'=>'device_in_use']); exit();
                }
                echo json_encode(['valid'=>true]); exit();
            }
        }
        echo json_encode(['valid'=>false,'reason'=>'not_found']); 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; } }

        if (!$row) { echo json_encode(['valid'=>false,'reason'=>'not_found']); exit(); }
        if (!$row['is_active']) { echo json_encode(['valid'=>false,'reason'=>'inactive']); exit(); }

        $today = new DateTime(); $expiry = new DateTime($row['expiry_date']);
        if ($today > $expiry) { echo json_encode(['valid'=>false,'reason'=>'expired','expiry'=>$row['expiry_date']]); 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';
        $app_limits = [];
        if (!empty($row['custom_config']) && is_array($row['custom_config'])) {
            $app_limits = $row['custom_config'];
        } else {
            $activeApps = loadData('applications.json');
            foreach ($activeApps as $a) {
                if (!$a['is_active']) continue;
                if ($pkg === 'basic' && in_array($a['id'], ['grok','bulk-sora'])) continue;
                if ($pkg === 'pro' && in_array($a['id'], ['bulk-sora'])) continue;
                $max_srv = (int)$a['max_servers'];
                $app_limits[$a['id']] = ($pkg === 'basic' || $pkg === 'pro') ? min(3, $max_srv) : $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'] || !isset($app_limits[$ra['id']])) continue;
            
            $icon_val = $ra['icon_value'];
            if ($ra['icon_type'] === 'image' && strpos($icon_val, 'http') !== 0) {
                $icon_val = $base_url . '/' . ltrim($icon_val, '/');
            }

            $apps[] = [
                'id' => $ra['id'], 'name' => $ra['name'],
                'icon_type' => $ra['icon_type'], 'icon_value' => $icon_val,
                'type' => 'grid-app', 'servers' => $app_limits[$ra['id']],
                'url' => $ra['default_url'], 'requires_cookie' => (bool)$ra['requires_cookie']
            ];
        }

        // 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);

        echo json_encode(['valid'=>true,'name'=>$row['name'],'expiry'=>$row['expiry_date'],'package'=>$pkg,'apps'=>$apps]);
        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();
    }

    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; } }
        if (!$user || !$user['is_active'] || ($user['active_device_id'] && $user['active_device_id'] !== $device_id) || (new DateTime() > new DateTime($user['expiry_date']))) {
            echo json_encode(['valid'=>false,'reason'=>'unauthorized']); exit();
        }

        $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;
            }
        }
        echo json_encode(['valid'=>true,'cookies'=>$cookieData,'target_url'=>$targetUrl]); exit();
    }

    if ($action === 'save_cookies') {
        $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();
        }

        // Support various JSON export formats
        if (isset($parsed['cookies']) && is_array($parsed['cookies'])) {
            $parsed = $parsed['cookies']; // Extract actual array if wrapped in an object like {"url":"...", "cookies":[...]}
        } elseif (isset($parsed[0]) && is_array($parsed[0]) && isset($parsed[0]['cookies'])) {
            $parsed = $parsed[0]['cookies']; // Format like [{"cookies": [...]}]
        }
        
        // Ensure it's a direct array of objects
        $parsed = array_values($parsed);

        $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'] = $parsed;
                $cookies[$i]['target_url'] = $target_url;
                $found = true; break;
            }
        }
        if (!$found) $cookies[] = ['app_id'=>$app_id,'server_index'=>$server_index,'target_url'=>$target_url,'cookie_data'=>$parsed];
        saveData('cookies.json', $cookies);
        echo json_encode(['success'=>true]); 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();
}

// =============================================
// ADMIN PANEL MODE - HTML UI
// =============================================
$msg = ''; $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; } }
}

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

    if ($pa === 'add') {
        $name = trim($_POST['name'] ?? ''); $days = (int)($_POST['expiry_days'] ?? 7);
        $custom_code = trim($_POST['custom_code'] ?? '');
        $pkg = $_POST['package'] ?? 'basic';
        if (!array_key_exists($pkg, $PKG_LABELS)) $pkg = 'basic';
        $cfg = [];
        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) || !in_array($days, [3,7,30])) { $msg='Nama wajib diisi dan pilih durasi.'; $msgType='error'; }
        else {
            $members = loadData('members.json');
            $code = !empty($custom_code) ? $custom_code : generateCode();
            // Check uniqueness
            $exists = false;
            foreach ($members as $m) { if ($m['code'] === $code) { $exists = true; break; } }
            if ($exists) { $msg='Kode sudah digunakan, coba lagi.'; $msgType='error'; }
            else {
                $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];
                saveData('members.json', $members);
                $msg="Member <strong>{$name}</strong> ditambahkan. Kode: <strong>{$code}</strong> | Paket: <strong>{$PKG_LABELS[$pkg]}</strong>"; $msgType='success';
            }
        }
    }
    if ($pa === 'update') {
        $id = (int)($_POST['id'] ?? 0); $name = trim($_POST['name'] ?? '');
        $code = trim($_POST['code'] ?? ''); $expiry = trim($_POST['expiry_date'] ?? '');
        $pkg = $_POST['package'] ?? 'basic';
        if (!array_key_exists($pkg, $PKG_LABELS)) $pkg = 'basic';
        $cfg = [];
        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]['expiry_date'] = $expiry; $members[$i]['package'] = $pkg;
                    $members[$i]['custom_config'] = $custom_cfg; 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; break; } }
        saveData('members.json', $members); $msg='Status diperbarui.'; $msgType='info';
    }
    if ($pa === 'delete') {
        $id = (int)($_POST['id'] ?? 0); $members = loadData('members.json');
        $members = array_values(array_filter($members, function($m) use ($id) { return $m['id'] !== $id; }));
        saveData('members.json', $members); $msg='Member dihapus.'; $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'] ?? '');
        $req_cookie = isset($_POST['requires_cookie']) ? 1 : 0;
        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,'is_active'=>1,'sort_order'=>$maxSort+1];
                saveData('applications.json', $apps);
                $msg="Aplikasi <strong>{$name}</strong> berhasil ditambahkan."; $msgType='success';
                echo "<script>window.location.href='index.php?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'] ?? '');
        $req_cookie = isset($_POST['requires_cookie']) ? 1 : 0;
        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;
                    // 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='index.php?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='index.php?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='index.php?tab=apps';</script>"; exit();
    }
}

// Prepare member list
$members = loadData('members.json');
usort($members, function($a,$b){ return strtotime($b['created_at']??'0') - strtotime($a['created_at']??'0'); });
$search = trim($_GET['q'] ?? '');
if ($search) {
    $s = strtolower($search);
    $members = array_filter($members, function($m) use ($s) {
        return stripos($m['name'],$s) !== false || stripos($m['code'],$s) !== false;
    });
    $members = array_values($members);
}
$today = new DateTime();
$total = count(loadData('members.json'));
$active = 0; $expired = 0;
foreach (loadData('members.json') as $m) {
    $exp = new DateTime($m['expiry_date']);
    if ($today > $exp) $expired++;
    elseif ($m['is_active']) $active++;
}

// 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'];
        $APP_URLS_PHP[$app['id']] = $app['default_url'] ?? '';
    }
}
?>
<!DOCTYPE html>
<html lang="id">
<head>
<meta charset="UTF-8"/>
<meta name="viewport" content="width=device-width,initial-scale=1.0"/>
<title>TEXA 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:940px;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}
.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}
table{width:100%;border-collapse:collapse}
th{font-size:10px;font-weight:700;color:var(--muted);letter-spacing:.7px;text-transform:uppercase;padding:7px 11px;text-align:left;border-bottom:1px solid var(--border)}
td{padding:10px 11px;font-size:12px;border-bottom:1px solid rgba(0,80,160,.1);vertical-align:middle}
tr:last-child td{border-bottom:none}
tr:hover td{background:rgba(0,60,140,.12)}
code.kd{background:rgba(0,80,160,.25);border:1px solid var(--border);border-radius:6px;padding:3px 10px;font-size:11.5px;font-family:"Courier New",monospace;color:var(--light);letter-spacing:1px}
.badge{display:inline-flex;align-items:center;padding:2px 9px;border-radius:20px;font-size:10px;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:11px}
.sisa.ok{color:var(--ok)}.sisa.warn{color:var(--warn)}.sisa.err{color:var(--err)}
.acts{display:flex;gap:5px;flex-wrap:nowrap;white-space:nowrap}
.empty{text-align:center;padding:36px;color:var(--muted);font-size:13px}
.tabs{display:flex;gap:10px;margin-bottom:20px;border-bottom:1px solid var(--border);padding-bottom:12px}
.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}
@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}
  th{padding:6px 8px;font-size:9px}td{padding:8px 8px;font-size:11px}
  code.kd{font-size:10.5px;padding:2px 7px}.bsm{padding:5px 9px;font-size:10px}
  .sr{flex-direction:column;gap:8px}.pkg-group{gap:6px}
}
@media (max-width: 480px) {
  .wrap{padding:14px 10px}.stats{grid-template-columns:1fr}.hdr-text p{display:none}
  .tw table thead{display:none}
  .tw table tr{display:block;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:5px 0;font-size:11px}
  .tw table td::before{content:attr(data-label);font-size:9px;font-weight:700;color:var(--muted);text-transform:uppercase;letter-spacing:.6px;flex-shrink:0;margin-right:8px}
  .acts{justify-content:flex-end}.pkg-btn{min-width:60px;font-size:11px}
}
</style>
</head>
<body>
<div class="wrap">
<div class="hdr">
  <div class="logo">TX</div>
  <div class="hdr-text"><h1>TEXA Apps &mdash; Member Manager</h1><p>Kelola kode akses member extension (JSON Mode)</p></div>
</div>
<div class="stats">
  <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>
<?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">
  <button class="tab-btn active" onclick="switchTab('members')">Kelola Member</button>
  <button class="tab-btn" onclick="switchTab('apps')">Kelola Aplikasi</button>
  <button class="tab-btn" onclick="switchTab('cookies')">Inject Cookies</button>
  <button class="tab-btn" onclick="switchTab('settings')">Pengaturan</button>
</div>

<div id="tab-members" class="tab-content active">
<?php
function renderPkgSelector($selPkg, $prefix, $customCfg, $APP_LABELS, $APP_MAX) { ?>
<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">
    <button type="button" class="pkg-btn<?php echo $selPkg==='basic'?' selected':''; ?>" data-pkg="basic" onclick="setPkg('<?php echo $prefix;?>','basic')"><span class="pkg-name">Basic</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')"><span class="pkg-name">Pro</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')"><span class="pkg-name">Ultimate</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')"><span class="pkg-name">Custom</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">
      <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)"/>
        <label for="<?php echo $prefix;?>_<?php echo $aid;?>"><?php echo $alabel; ?></label>
      </div>
      <?php if ($maxSrv > 1): ?>
      <div class="srv-ctrl">
        <label>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?'':'disabled';?>/>
      </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"><label>Tanggal Expire</label><input type="date" name="expiry_date" value="<?php echo $editData['expiry_date']; ?>" required/></div>
      <?php renderPkgSelector($editPkg, 'ed', $editCustom, $APP_LABELS_ALL, $APP_MAX_ALL); ?>
      <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 endif; ?>

<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>
        <div class="dur-group">
          <button type="button" class="dur-btn" data-days="3" onclick="setDays(3)">3 Hari<span class="dur-badge">Short</span></button>
          <button type="button" class="dur-btn selected" data-days="7" onclick="setDays(7)">7 Hari<span class="dur-badge">Standard</span></button>
          <button type="button" class="dur-btn" data-days="30" onclick="setDays(30)">30 Hari<span class="dur-badge">Premium</span></button>
        </div>
      </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>

<div class="card">
  <div class="ct">Daftar Member</div>
  <div class="sr">
    <form method="GET" style="display:flex;gap:9px;flex:1">
      <input type="search" name="q" value="<?php echo htmlspecialchars($search); ?>" placeholder="Cari nama atau kode..."/>
      <button type="submit" class="btn bt">Cari</button>
      <?php if ($search): ?><a href="?" class="btn bt">Reset</a><?php endif; ?>
    </form>
  </div>
  <div class="tw"><table>
    <thead><tr><th>#</th><th>Nama</th><th>Kode</th><th>Paket</th><th>Expire</th><th>Sisa</th><th>Login</th><th>Status</th><th>Aksi</th></tr></thead>
    <tbody>
    <?php $i=1;
    if (empty($members)): ?>
      <tr><td colspan="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></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"><div class="acts">
          <a href="?edit=<?php echo $r['id']; ?>" class="btn bsm be2">Edit</a>
          <form method="POST" style="display:inline"><input type="hidden" name="action" value="toggle"/><input type="hidden" name="id" value="<?php echo $r['id']; ?>"/><button class="btn bsm bt"><?php echo $r['is_active']?'Nonaktifkan':'Aktifkan'; ?></button></form>
          <form method="POST" style="display:inline" onsubmit="return confirm('Hapus member ini?')"><input type="hidden" name="action" value="delete"/><input type="hidden" name="id" value="<?php echo $r['id']; ?>"/><button class="btn bsm bd">Hapus</button></form>
        </div></td>
      </tr>
    <?php endforeach; endif; ?>
    </tbody>
  </table></div>
</div>
</div>

<!-- APP MANAGEMENT TAB -->
<div id="tab-apps" class="tab-content">
<?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</label><input type="number" name="max_servers" value="<?php echo $editApp['max_servers']; ?>" min="1" max="20" required/></div>
        <div class="fi"><label>Upload Icon Baru (Opsional)</label><input type="file" name="icon_file" accept=".png,.jpg,.jpeg,.gif,.svg"/></div>
        <div class="fi"><label>URL Default (Tujuan)</label><input type="url" name="default_url" value="<?php echo htmlspecialchars($editApp['default_url']); ?>" placeholder="https://..."/></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>
        <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">
          <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>
      <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="acts">
            <a href="?edit_app=<?php echo urlencode($app['id']); ?>&tab=apps" class="btn bsm be2">Edit</a>
            <form method="POST" style="display:inline"><input type="hidden" name="action" value="toggle_app"/><input type="hidden" name="id" value="<?php echo htmlspecialchars($app['id']); ?>"/><button class="btn bsm bt"><?php echo $app['is_active'] ? 'Matikan' : 'Nyalakan'; ?></button></form>
            <form method="POST" style="display:inline" onsubmit="return confirm('Hapus aplikasi beserta cookies-nya?')"><input type="hidden" name="action" value="delete_app"/><input type="hidden" name="id" value="<?php echo htmlspecialchars($app['id']); ?>"/><button class="btn bsm bd">Hapus</button></form>
          </div></td>
        </tr>
      <?php endforeach; endif; ?>
      </tbody>
    </table></div>
  </div>
</div>

<!-- INJECT COOKIES TAB -->
<div id="tab-cookies" class="tab-content">
  <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;">
          <label>Paste JSON Payload (J2TEAM / EditThisCookie)</label>
          <textarea id="c-data" placeholder='[{"name":"session_id","value":"xyz","domain":".google.com",...}]' required></textarea>
        </div>
        <div class="fi full">
           <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>

<!-- SETTINGS TAB -->
<div id="tab-settings" class="tab-content">
  <div class="card">
    <div class="ct">Pengaturan Ekstensi</div>
    <?php
      $settings = loadData('settings.json');
      if ($_SERVER['REQUEST_METHOD'] === 'POST' && isset($_POST['action']) && $_POST['action'] === 'save_settings') {
          $settings['catalog_url'] = trim($_POST['catalog_url'] ?? '');
          saveData('settings.json', $settings);
          echo '<div class="alert alert-success">Pengaturan berhasil disimpan.</div>';
      }
    ?>
    <form method="POST">
      <input type="hidden" name="action" value="save_settings"/>
      <div class="fg">
        <div class="fi full">
          <label>URL Full Katalog AI Tools</label>
          <input type="url" name="catalog_url" value="<?php echo htmlspecialchars($settings['catalog_url'] ?? ''); ?>" placeholder="https://texa.web.id/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="display:flex;justify-content:flex-end;margin-top:4px">
          <button type="submit" class="btn bp">&#x1F4BE; Simpan Pengaturan</button>
        </div>
      </div>
    </form>
  </div>
</div>

<p style="text-align:center;font-size:10px;color:var(--muted);opacity:.5;margin-top:30px">TEXA Apps Member Manager &copy; 2026 (JSON Mode)</p>
</div>
<script>
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');
}
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); ?>;
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);
    }
});

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 cookie_data = document.getElementById('c-data').value;
    if (!app_id || !server_index || !cookie_data) { msg.textContent = 'âŒ Mohon lengkapi parameter.'; 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', cookie_data);
        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.'; msg.style.color = '#00e676'; document.getElementById('c-data').value = ''; }
        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('expiry_days').value = d;
    document.querySelectorAll('.dur-btn').forEach(b => b.classList.toggle('selected', parseInt(b.dataset.days) === d));
}
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);
    });
    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 (pkg === 'basic') { if (['google-flow','google-whisk','single-sora'].includes(appId)) { shouldCheck = true; srvCount = 3; } if (appId === 'single-sora') srvCount = 1; }
                else if (pkg === 'pro') { if (['google-flow','google-whisk','single-sora','grok'].includes(appId)) { shouldCheck = true; srvCount = 3; } if (appId === 'single-sora') srvCount = 1; }
                else if (pkg === 'ultimate') { shouldCheck = true; srvCount = srvInput ? srvInput.max : 5; }
                chk.checked = shouldCheck;
                if (srvInput) { srvInput.disabled = !shouldCheck; if (shouldCheck) srvInput.value = Math.min(srvCount, parseInt(srvInput.max)); }
            });
        }
    }
}
function toggleSrv(inputId, enabled) { const el = document.getElementById(inputId); if (el) el.disabled = !enabled; }
</script>
</body>
</html>
