<?php
/**
 * PAKClub Admin Panel - AJAX API Handler
 * Handles all admin panel CRUD operations
 */

session_name('PAKCLUB_ADMIN_SESSION');
session_start();

require_once __DIR__ . '/../config.php';

header('Content-Type: application/json; charset=utf-8');

// ── Auth check ──
if (!isset($_SESSION['admin_logged_in']) || $_SESSION['admin_logged_in'] !== true) {
    http_response_code(401);
    echo json_encode(['status' => 'error', 'message' => 'Unauthorized']);
    exit;
}

$action = $_POST['action'] ?? $_GET['action'] ?? '';
$db = getDB();

try {
    switch ($action) {

        // ════════════════════════════════════
        //  APPS CRUD
        // ════════════════════════════════════

        case 'get_apps':
            $search = $_GET['search'] ?? '';
            $status = $_GET['status'] ?? '';
            $page = max(1, (int)($_GET['page'] ?? 1));
            $perPage = 12;
            $offset = ($page - 1) * $perPage;

            $where = "1=1";
            $params = [];

            if (!empty($search)) {
                $where .= " AND (app_name LIKE ? OR pkg_name LIKE ?)";
                $params[] = "%{$search}%";
                $params[] = "%{$search}%";
            }
            if (!empty($status)) {
                $where .= " AND app_status = ?";
                $params[] = $status;
            }

            // Count total
            $countStmt = $db->prepare("SELECT COUNT(*) FROM apps WHERE {$where}");
            $countStmt->execute($params);
            $total = $countStmt->fetchColumn();

            // Fetch apps
            $stmt = $db->prepare("SELECT * FROM apps WHERE {$where} ORDER BY created_at DESC LIMIT {$perPage} OFFSET {$offset}");
            $stmt->execute($params);
            $apps = $stmt->fetchAll();

            // Build logo URLs
            foreach ($apps as &$app) {
                if (!empty($app['app_logo']) && !filter_var($app['app_logo'], FILTER_VALIDATE_URL)) {
                    $app['app_logo_url'] = getUploadBaseUrl() . $app['app_logo'];
                } else {
                    $app['app_logo_url'] = $app['app_logo'] ?? '';
                }
                if (!empty($app['refer_link'])) {
                    $app['full_refer_link'] = buildReferLink($app['refer_link'], $app['app_domain'] ?? '');
                }
            }

            echo json_encode([
                'status' => 'success',
                'data' => $apps,
                'total' => $total,
                'page' => $page,
                'pages' => ceil($total / $perPage)
            ]);
            break;

        case 'get_app':
            $id = (int)($_GET['id'] ?? 0);
            $stmt = $db->prepare("SELECT * FROM apps WHERE id = ?");
            $stmt->execute([$id]);
            $app = $stmt->fetch();
            if (!$app) {
                echo json_encode(['status' => 'error', 'message' => 'App not found']);
            } else {
                if (!empty($app['app_logo']) && !filter_var($app['app_logo'], FILTER_VALIDATE_URL)) {
                    $app['app_logo_url'] = getUploadBaseUrl() . $app['app_logo'];
                } else {
                    $app['app_logo_url'] = $app['app_logo'] ?? '';
                }
                echo json_encode(['status' => 'success', 'data' => $app]);
            }
            break;

        case 'save_app':
            $id = (int)($_POST['id'] ?? 0);
            $fields = [
                'pkg_name' => trim($_POST['pkg_name'] ?? ''),
                'app_name' => trim($_POST['app_name'] ?? ''),
                'app_domain' => trim($_POST['app_domain'] ?? ''),
                'app_logo' => trim($_POST['app_logo'] ?? ''),
                'whatsapp_link' => trim($_POST['whatsapp_link'] ?? ''),
                'refer_link' => trim($_POST['refer_link'] ?? ''),
                'app_version' => trim($_POST['app_version'] ?? '1.0.0'),
                'app_status' => $_POST['app_status'] ?? 'active',
                'min_version' => trim($_POST['min_version'] ?? '1.0.0'),
                'force_update' => (int)($_POST['force_update'] ?? 0),
                'update_url' => trim($_POST['update_url'] ?? ''),
                'app_description' => trim($_POST['app_description'] ?? ''),
                'notification_title' => trim($_POST['notification_title'] ?? ''),
                'notification_body' => trim($_POST['notification_body'] ?? ''),
                'notification_image' => trim($_POST['notification_image'] ?? ''),
                'notification_url' => trim($_POST['notification_url'] ?? ''),
                'popup_enabled' => (int)($_POST['popup_enabled'] ?? 0),
                'popup_title' => trim($_POST['popup_title'] ?? ''),
                'popup_message' => trim($_POST['popup_message'] ?? ''),
                'popup_button_text' => trim($_POST['popup_button_text'] ?? 'OK'),
                'popup_button_url' => trim($_POST['popup_button_url'] ?? ''),
                'popup_image' => trim($_POST['popup_image'] ?? ''),
                'interstitial_ad_id' => trim($_POST['interstitial_ad_id'] ?? ''),
                'banner_ad_id' => trim($_POST['banner_ad_id'] ?? ''),
                'rewarded_ad_id' => trim($_POST['rewarded_ad_id'] ?? ''),
                'native_ad_id' => trim($_POST['native_ad_id'] ?? ''),
                'ad_network' => $_POST['ad_network'] ?? 'none',
                'ads_enabled' => (int)($_POST['ads_enabled'] ?? 0),
                'custom_data' => trim($_POST['custom_data'] ?? ''),
            ];

            if (empty($fields['pkg_name'])) {
                echo json_encode(['status' => 'error', 'message' => 'Package name is required']);
                break;
            }
            if (empty($fields['app_name'])) {
                echo json_encode(['status' => 'error', 'message' => 'App name is required']);
                break;
            }

            // Validate custom data JSON
            if (!empty($fields['custom_data'])) {
                $decoded = json_decode($fields['custom_data']);
                if ($decoded === null && json_last_error() !== JSON_ERROR_NONE) {
                    echo json_encode(['status' => 'error', 'message' => 'Invalid JSON in custom data']);
                    break;
                }
            } else {
                $fields['custom_data'] = null;
            }

            if ($id > 0) {
                // Update
                $sets = [];
                $params = [];
                foreach ($fields as $key => $value) {
                    $sets[] = "`{$key}` = ?";
                    $params[] = $value;
                }
                $params[] = $id;
                $stmt = $db->prepare("UPDATE apps SET " . implode(', ', $sets) . " WHERE id = ?");
                $stmt->execute($params);

                // Log
                $logStmt = $db->prepare("INSERT INTO admin_logs (action, details, ip_address) VALUES ('update_app', ?, ?)");
                $logStmt->execute(["Updated app: {$fields['app_name']} ({$fields['pkg_name']})", $_SERVER['REMOTE_ADDR'] ?? '']);

                echo json_encode(['status' => 'success', 'message' => 'App updated successfully', 'id' => $id]);
            } else {
                // Check duplicate pkg
                $checkStmt = $db->prepare("SELECT id FROM apps WHERE pkg_name = ?");
                $checkStmt->execute([$fields['pkg_name']]);
                if ($checkStmt->fetch()) {
                    echo json_encode(['status' => 'error', 'message' => 'An app with this package name already exists']);
                    break;
                }

                // Insert
                $cols = array_keys($fields);
                $placeholders = array_fill(0, count($cols), '?');
                $stmt = $db->prepare("INSERT INTO apps (`" . implode('`, `', $cols) . "`) VALUES (" . implode(', ', $placeholders) . ")");
                $stmt->execute(array_values($fields));
                $newId = $db->lastInsertId();

                // Log
                $logStmt = $db->prepare("INSERT INTO admin_logs (action, details, ip_address) VALUES ('create_app', ?, ?)");
                $logStmt->execute(["Created app: {$fields['app_name']} ({$fields['pkg_name']})", $_SERVER['REMOTE_ADDR'] ?? '']);

                echo json_encode(['status' => 'success', 'message' => 'App created successfully', 'id' => $newId]);
            }
            break;

        case 'delete_app':
            $id = (int)($_POST['id'] ?? 0);
            
            // Get app info for logging
            $stmt = $db->prepare("SELECT app_name, pkg_name, app_logo FROM apps WHERE id = ?");
            $stmt->execute([$id]);
            $app = $stmt->fetch();
            
            if ($app) {
                // Delete logo file
                if (!empty($app['app_logo'])) {
                    $logoPath = UPLOAD_DIR . $app['app_logo'];
                    if (file_exists($logoPath)) unlink($logoPath);
                }
                
                $delStmt = $db->prepare("DELETE FROM apps WHERE id = ?");
                $delStmt->execute([$id]);

                $logStmt = $db->prepare("INSERT INTO admin_logs (action, details, ip_address) VALUES ('delete_app', ?, ?)");
                $logStmt->execute(["Deleted app: {$app['app_name']} ({$app['pkg_name']})", $_SERVER['REMOTE_ADDR'] ?? '']);

                echo json_encode(['status' => 'success', 'message' => 'App deleted successfully']);
            } else {
                echo json_encode(['status' => 'error', 'message' => 'App not found']);
            }
            break;

        case 'toggle_app_status':
            $id = (int)($_POST['id'] ?? 0);
            $newStatus = $_POST['status'] ?? 'active';
            $stmt = $db->prepare("UPDATE apps SET app_status = ? WHERE id = ?");
            $stmt->execute([$newStatus, $id]);
            echo json_encode(['status' => 'success', 'message' => 'Status updated']);
            break;

        case 'duplicate_app':
            $id = (int)($_POST['id'] ?? 0);
            $stmt = $db->prepare("SELECT * FROM apps WHERE id = ?");
            $stmt->execute([$id]);
            $app = $stmt->fetch();
            if ($app) {
                unset($app['id'], $app['created_at'], $app['updated_at'], $app['api_calls'], $app['last_api_call']);
                $app['pkg_name'] = $app['pkg_name'] . '.copy';
                $app['app_name'] = $app['app_name'] . ' (Copy)';
                $cols = array_keys($app);
                $placeholders = array_fill(0, count($cols), '?');
                $insStmt = $db->prepare("INSERT INTO apps (`" . implode('`, `', $cols) . "`) VALUES (" . implode(', ', $placeholders) . ")");
                $insStmt->execute(array_values($app));
                echo json_encode(['status' => 'success', 'message' => 'App duplicated', 'id' => $db->lastInsertId()]);
            } else {
                echo json_encode(['status' => 'error', 'message' => 'App not found']);
            }
            break;

        // ════════════════════════════════════
        //  LOGO UPLOAD
        // ════════════════════════════════════

        case 'upload_logo':
            if (!isset($_FILES['logo'])) {
                echo json_encode(['status' => 'error', 'message' => 'No file uploaded']);
                break;
            }

            $file = $_FILES['logo'];
            
            if ($file['error'] !== UPLOAD_ERR_OK) {
                $errorMessages = [
                    UPLOAD_ERR_INI_SIZE => 'File exceeds server limit',
                    UPLOAD_ERR_FORM_SIZE => 'File exceeds form limit',
                    UPLOAD_ERR_PARTIAL => 'File partially uploaded',
                    UPLOAD_ERR_NO_FILE => 'No file uploaded',
                    UPLOAD_ERR_NO_TMP_DIR => 'Missing temp folder',
                    UPLOAD_ERR_CANT_WRITE => 'Failed to write to disk',
                ];
                $msg = $errorMessages[$file['error']] ?? 'Unknown upload error';
                echo json_encode(['status' => 'error', 'message' => $msg]);
                break;
            }

            if ($file['size'] > MAX_UPLOAD_SIZE) {
                echo json_encode(['status' => 'error', 'message' => 'File too large. Max: ' . (MAX_UPLOAD_SIZE / 1024 / 1024) . 'MB']);
                break;
            }

            $ext = strtolower(pathinfo($file['name'], PATHINFO_EXTENSION));
            if (!in_array($ext, ALLOWED_EXTENSIONS)) {
                echo json_encode(['status' => 'error', 'message' => 'Invalid file type. Allowed: ' . implode(', ', ALLOWED_EXTENSIONS)]);
                break;
            }

            // Verify MIME type
            $finfo = finfo_open(FILEINFO_MIME_TYPE);
            $mimeType = finfo_file($finfo, $file['tmp_name']);
            finfo_close($finfo);
            $allowedMimes = ['image/jpeg', 'image/png', 'image/gif', 'image/webp', 'image/svg+xml'];
            if (!in_array($mimeType, $allowedMimes)) {
                echo json_encode(['status' => 'error', 'message' => 'Invalid image file']);
                break;
            }

            // Create upload dir if needed
            if (!is_dir(UPLOAD_DIR)) {
                mkdir(UPLOAD_DIR, 0755, true);
            }

            // Generate unique filename
            $filename = 'logo_' . time() . '_' . bin2hex(random_bytes(8)) . '.' . $ext;
            $destination = UPLOAD_DIR . $filename;

            if (move_uploaded_file($file['tmp_name'], $destination)) {
                // If replacing an existing app logo, update DB
                $appId = (int)($_POST['app_id'] ?? 0);
                if ($appId > 0) {
                    // Delete old logo
                    $oldStmt = $db->prepare("SELECT app_logo FROM apps WHERE id = ?");
                    $oldStmt->execute([$appId]);
                    $oldApp = $oldStmt->fetch();
                    if ($oldApp && !empty($oldApp['app_logo'])) {
                        $oldPath = UPLOAD_DIR . $oldApp['app_logo'];
                        if (file_exists($oldPath)) unlink($oldPath);
                    }
                    // Update app with new logo
                    $updStmt = $db->prepare("UPDATE apps SET app_logo = ? WHERE id = ?");
                    $updStmt->execute([$filename, $appId]);
                }

                echo json_encode([
                    'status' => 'success',
                    'message' => 'Logo uploaded successfully',
                    'filename' => $filename,
                    'url' => getUploadBaseUrl() . $filename
                ]);
            } else {
                echo json_encode(['status' => 'error', 'message' => 'Failed to save file']);
            }
            break;

        case 'delete_logo':
            $filename = $_POST['filename'] ?? '';
            $appId = (int)($_POST['app_id'] ?? 0);
            if (!empty($filename)) {
                $path = UPLOAD_DIR . basename($filename);
                if (file_exists($path)) unlink($path);
            }
            if ($appId > 0) {
                $stmt = $db->prepare("UPDATE apps SET app_logo = NULL WHERE id = ?");
                $stmt->execute([$appId]);
            }
            echo json_encode(['status' => 'success', 'message' => 'Logo deleted']);
            break;

        // ════════════════════════════════════
        //  SETTINGS
        // ════════════════════════════════════

        case 'get_settings':
            $stmt = $db->query("SELECT * FROM settings ORDER BY id ASC");
            $settings = $stmt->fetchAll();
            echo json_encode(['status' => 'success', 'data' => $settings]);
            break;

        case 'save_settings':
            $settingsData = $_POST['settings'] ?? [];
            if (is_string($settingsData)) {
                $settingsData = json_decode($settingsData, true) ?? [];
            }

            foreach ($settingsData as $key => $value) {
                setSetting($key, $value);
            }

            $logStmt = $db->prepare("INSERT INTO admin_logs (action, details, ip_address) VALUES ('update_settings', 'Settings updated', ?)");
            $logStmt->execute([$_SERVER['REMOTE_ADDR'] ?? '']);

            echo json_encode(['status' => 'success', 'message' => 'Settings saved successfully']);
            break;

        // ════════════════════════════════════
        //  API KEYS
        // ════════════════════════════════════

        case 'get_api_keys':
            $stmt = $db->query("SELECT * FROM api_keys ORDER BY created_at DESC");
            echo json_encode(['status' => 'success', 'data' => $stmt->fetchAll()]);
            break;

        case 'create_api_key':
            $name = trim($_POST['key_name'] ?? 'New Key');
            $rateLimit = (int)($_POST['rate_limit'] ?? 100);
            $key = bin2hex(random_bytes(32));
            $stmt = $db->prepare("INSERT INTO api_keys (key_name, api_key, rate_limit) VALUES (?, ?, ?)");
            $stmt->execute([$name, $key, $rateLimit]);
            echo json_encode(['status' => 'success', 'message' => 'API key created', 'api_key' => $key, 'id' => $db->lastInsertId()]);
            break;

        case 'toggle_api_key':
            $id = (int)($_POST['id'] ?? 0);
            $stmt = $db->prepare("UPDATE api_keys SET is_active = NOT is_active WHERE id = ?");
            $stmt->execute([$id]);
            echo json_encode(['status' => 'success', 'message' => 'API key toggled']);
            break;

        case 'delete_api_key':
            $id = (int)($_POST['id'] ?? 0);
            $stmt = $db->prepare("DELETE FROM api_keys WHERE id = ?");
            $stmt->execute([$id]);
            echo json_encode(['status' => 'success', 'message' => 'API key deleted']);
            break;

        // ════════════════════════════════════
        //  BLOCKED DEVICES
        // ════════════════════════════════════

        case 'get_blocked_devices':
            $stmt = $db->query("SELECT * FROM blocked_devices ORDER BY blocked_at DESC");
            echo json_encode(['status' => 'success', 'data' => $stmt->fetchAll()]);
            break;

        case 'block_device':
            $deviceId = trim($_POST['device_id'] ?? '');
            $reason = trim($_POST['reason'] ?? '');
            $deviceInfo = trim($_POST['device_info'] ?? '');
            if (empty($deviceId)) {
                echo json_encode(['status' => 'error', 'message' => 'Device ID required']);
                break;
            }
            $stmt = $db->prepare("INSERT IGNORE INTO blocked_devices (device_id, device_info, reason) VALUES (?, ?, ?)");
            $stmt->execute([$deviceId, $deviceInfo, $reason]);
            echo json_encode(['status' => 'success', 'message' => 'Device blocked']);
            break;

        case 'unblock_device':
            $id = (int)($_POST['id'] ?? 0);
            $stmt = $db->prepare("DELETE FROM blocked_devices WHERE id = ?");
            $stmt->execute([$id]);
            echo json_encode(['status' => 'success', 'message' => 'Device unblocked']);
            break;

        // ════════════════════════════════════
        //  LOGS
        // ════════════════════════════════════

        case 'get_logs':
            $page = max(1, (int)($_GET['page'] ?? 1));
            $perPage = 25;
            $offset = ($page - 1) * $perPage;
            $actionFilter = $_GET['action_filter'] ?? '';

            $where = "1=1";
            $params = [];
            if (!empty($actionFilter)) {
                $where .= " AND action = ?";
                $params[] = $actionFilter;
            }

            $countStmt = $db->prepare("SELECT COUNT(*) FROM admin_logs WHERE {$where}");
            $countStmt->execute($params);
            $total = $countStmt->fetchColumn();

            $stmt = $db->prepare("SELECT * FROM admin_logs WHERE {$where} ORDER BY created_at DESC LIMIT {$perPage} OFFSET {$offset}");
            $stmt->execute($params);
            
            echo json_encode([
                'status' => 'success',
                'data' => $stmt->fetchAll(),
                'total' => $total,
                'page' => $page,
                'pages' => ceil($total / $perPage)
            ]);
            break;

        case 'clear_logs':
            $db->exec("TRUNCATE TABLE admin_logs");
            echo json_encode(['status' => 'success', 'message' => 'Logs cleared']);
            break;

        // ════════════════════════════════════
        //  DASHBOARD STATS
        // ════════════════════════════════════

        case 'get_stats':
            $totalApps = $db->query("SELECT COUNT(*) FROM apps")->fetchColumn();
            $activeApps = $db->query("SELECT COUNT(*) FROM apps WHERE app_status = 'active'")->fetchColumn();
            $totalApiCalls = $db->query("SELECT COALESCE(SUM(api_calls), 0) FROM apps")->fetchColumn();
            $blockedDevices = $db->query("SELECT COUNT(*) FROM blocked_devices")->fetchColumn();
            $totalLogs = $db->query("SELECT COUNT(*) FROM admin_logs")->fetchColumn();
            $apiKeys = $db->query("SELECT COUNT(*) FROM api_keys WHERE is_active = 1")->fetchColumn();

            // Recent apps
            $recentApps = $db->query("SELECT id, app_name, pkg_name, app_status, api_calls, created_at FROM apps ORDER BY created_at DESC LIMIT 5")->fetchAll();
            
            // Recent logs
            $recentLogs = $db->query("SELECT action, details, ip_address, created_at FROM admin_logs ORDER BY created_at DESC LIMIT 8")->fetchAll();

            // Top apps by API calls
            $topApps = $db->query("SELECT app_name, pkg_name, api_calls FROM apps ORDER BY api_calls DESC LIMIT 5")->fetchAll();

            // API calls in last 24h
            $recentCalls = $db->query("SELECT COUNT(*) FROM admin_logs WHERE action = 'api_call' AND created_at >= DATE_SUB(NOW(), INTERVAL 24 HOUR)")->fetchColumn();

            echo json_encode([
                'status' => 'success',
                'data' => [
                    'total_apps' => $totalApps,
                    'active_apps' => $activeApps,
                    'total_api_calls' => $totalApiCalls,
                    'blocked_devices' => $blockedDevices,
                    'total_logs' => $totalLogs,
                    'active_api_keys' => $apiKeys,
                    'recent_apps' => $recentApps,
                    'recent_logs' => $recentLogs,
                    'top_apps' => $topApps,
                    'api_calls_24h' => $recentCalls,
                ]
            ]);
            break;

        // ════════════════════════════════════
        //  EXPORT / IMPORT
        // ════════════════════════════════════

        case 'export_apps':
            $stmt = $db->query("SELECT * FROM apps ORDER BY id ASC");
            $apps = $stmt->fetchAll();
            header('Content-Disposition: attachment; filename="pakclub_apps_export_' . date('Y-m-d') . '.json"');
            echo json_encode(['apps' => $apps, 'exported_at' => date('Y-m-d H:i:s')], JSON_PRETTY_PRINT);
            break;

        case 'import_apps':
            $input = json_decode(file_get_contents('php://input'), true);
            $apps = $input['apps'] ?? [];
            $imported = 0;
            $skipped = 0;
            foreach ($apps as $app) {
                $checkStmt = $db->prepare("SELECT id FROM apps WHERE pkg_name = ?");
                $checkStmt->execute([$app['pkg_name']]);
                if ($checkStmt->fetch()) {
                    $skipped++;
                    continue;
                }
                unset($app['id'], $app['created_at'], $app['updated_at']);
                $cols = array_keys($app);
                $placeholders = array_fill(0, count($cols), '?');
                $insStmt = $db->prepare("INSERT INTO apps (`" . implode('`, `', $cols) . "`) VALUES (" . implode(', ', $placeholders) . ")");
                $insStmt->execute(array_values($app));
                $imported++;
            }
            echo json_encode(['status' => 'success', 'message' => "Imported: {$imported}, Skipped: {$skipped}"]);
            break;

        // ════════════════════════════════════
        //  BULK ACTIONS
        // ════════════════════════════════════

        case 'bulk_action':
            $ids = $_POST['ids'] ?? [];
            if (is_string($ids)) $ids = json_decode($ids, true) ?? [];
            $bulkAction = $_POST['bulk_action'] ?? '';
            
            if (empty($ids)) {
                echo json_encode(['status' => 'error', 'message' => 'No items selected']);
                break;
            }

            $placeholders = implode(',', array_fill(0, count($ids), '?'));
            
            switch ($bulkAction) {
                case 'activate':
                    $stmt = $db->prepare("UPDATE apps SET app_status = 'active' WHERE id IN ({$placeholders})");
                    $stmt->execute($ids);
                    echo json_encode(['status' => 'success', 'message' => count($ids) . ' apps activated']);
                    break;
                case 'deactivate':
                    $stmt = $db->prepare("UPDATE apps SET app_status = 'inactive' WHERE id IN ({$placeholders})");
                    $stmt->execute($ids);
                    echo json_encode(['status' => 'success', 'message' => count($ids) . ' apps deactivated']);
                    break;
                case 'delete':
                    // Delete logos first
                    $logoStmt = $db->prepare("SELECT app_logo FROM apps WHERE id IN ({$placeholders})");
                    $logoStmt->execute($ids);
                    while ($row = $logoStmt->fetch()) {
                        if (!empty($row['app_logo'])) {
                            $path = UPLOAD_DIR . $row['app_logo'];
                            if (file_exists($path)) unlink($path);
                        }
                    }
                    $stmt = $db->prepare("DELETE FROM apps WHERE id IN ({$placeholders})");
                    $stmt->execute($ids);
                    echo json_encode(['status' => 'success', 'message' => count($ids) . ' apps deleted']);
                    break;
                default:
                    echo json_encode(['status' => 'error', 'message' => 'Unknown bulk action']);
            }
            break;

        // ════════════════════════════════════
        //  AUDIO MANAGEMENT
        // ════════════════════════════════════

        case 'get_audios':
            $appFilter = $_GET['app_id'] ?? '';
            $where = "1=1";
            $params = [];
            if (!empty($appFilter)) {
                $where .= " AND a.app_id = ?";
                $params[] = (int)$appFilter;
            }
            $stmt = $db->prepare("SELECT a.*, ap.app_name as linked_app_name FROM audios a LEFT JOIN apps ap ON a.app_id = ap.id WHERE {$where} ORDER BY a.created_at DESC");
            $stmt->execute($params);
            $audios = $stmt->fetchAll();
            foreach ($audios as &$audio) {
                if (!empty($audio['audio_file']) && !filter_var($audio['audio_file'], FILTER_VALIDATE_URL)) {
                    $audio['audio_url'] = getAudioBaseUrl() . $audio['audio_file'];
                } else {
                    $audio['audio_url'] = $audio['audio_file'] ?? '';
                }
            }
            echo json_encode(['status' => 'success', 'data' => $audios]);
            break;

        case 'upload_audio':
            if (!isset($_FILES['audio'])) {
                echo json_encode(['status' => 'error', 'message' => 'No audio file uploaded']);
                break;
            }
            $file = $_FILES['audio'];
            if ($file['error'] !== UPLOAD_ERR_OK) {
                echo json_encode(['status' => 'error', 'message' => 'Upload error']);
                break;
            }
            if ($file['size'] > MAX_AUDIO_SIZE) {
                echo json_encode(['status' => 'error', 'message' => 'File too large. Max: ' . (MAX_AUDIO_SIZE / 1024 / 1024) . 'MB']);
                break;
            }
            $ext = strtolower(pathinfo($file['name'], PATHINFO_EXTENSION));
            if (!in_array($ext, ALLOWED_AUDIO_EXTENSIONS)) {
                echo json_encode(['status' => 'error', 'message' => 'Invalid audio type. Allowed: ' . implode(', ', ALLOWED_AUDIO_EXTENSIONS)]);
                break;
            }
            if (!is_dir(AUDIO_UPLOAD_DIR)) mkdir(AUDIO_UPLOAD_DIR, 0755, true);
            $filename = 'audio_' . time() . '_' . bin2hex(random_bytes(6)) . '.' . $ext;
            $dest = AUDIO_UPLOAD_DIR . $filename;
            if (move_uploaded_file($file['tmp_name'], $dest)) {
                echo json_encode(['status' => 'success', 'filename' => $filename, 'url' => getAudioBaseUrl() . $filename]);
            } else {
                echo json_encode(['status' => 'error', 'message' => 'Failed to save audio']);
            }
            break;

        case 'save_audio':
            $id = (int)($_POST['id'] ?? 0);
            $className = trim($_POST['class_name'] ?? '');
            $audioTitle = trim($_POST['audio_title'] ?? '');
            $audioFile = trim($_POST['audio_file'] ?? '');
            $appId = !empty($_POST['app_id']) ? (int)$_POST['app_id'] : null;
            $isActive = (int)($_POST['is_active'] ?? 1);

            if (empty($className)) {
                echo json_encode(['status' => 'error', 'message' => 'Class name is required']);
                break;
            }
            if (empty($audioFile)) {
                echo json_encode(['status' => 'error', 'message' => 'Audio file is required']);
                break;
            }

            if ($id > 0) {
                $stmt = $db->prepare("UPDATE audios SET class_name=?, audio_title=?, audio_file=?, app_id=?, is_active=? WHERE id=?");
                $stmt->execute([$className, $audioTitle, $audioFile, $appId, $isActive, $id]);
                echo json_encode(['status' => 'success', 'message' => 'Audio updated']);
            } else {
                $stmt = $db->prepare("INSERT INTO audios (class_name, audio_title, audio_file, app_id, is_active) VALUES (?,?,?,?,?)");
                $stmt->execute([$className, $audioTitle, $audioFile, $appId, $isActive]);
                echo json_encode(['status' => 'success', 'message' => 'Audio created', 'id' => $db->lastInsertId()]);
            }
            break;

        case 'delete_audio':
            $id = (int)($_POST['id'] ?? 0);
            $stmt = $db->prepare("SELECT audio_file FROM audios WHERE id = ?");
            $stmt->execute([$id]);
            $audio = $stmt->fetch();
            if ($audio && !empty($audio['audio_file'])) {
                $path = AUDIO_UPLOAD_DIR . $audio['audio_file'];
                if (file_exists($path)) unlink($path);
            }
            $db->prepare("DELETE FROM audios WHERE id = ?")->execute([$id]);
            echo json_encode(['status' => 'success', 'message' => 'Audio deleted']);
            break;

        case 'toggle_audio':
            $id = (int)($_POST['id'] ?? 0);
            $db->prepare("UPDATE audios SET is_active = NOT is_active WHERE id = ?")->execute([$id]);
            echo json_encode(['status' => 'success', 'message' => 'Audio toggled']);
            break;

        default:
            echo json_encode(['status' => 'error', 'message' => 'Unknown action: ' . $action]);
            break;
    }
} catch (PDOException $e) {
    http_response_code(500);
    echo json_encode(['status' => 'error', 'message' => 'Database error: ' . $e->getMessage()]);
} catch (Exception $e) {
    http_response_code(500);
    echo json_encode(['status' => 'error', 'message' => 'Server error: ' . $e->getMessage()]);
}
