cd /var/www/clients/client0/web3/web

cat << 'EOF' > admin_ajax.php
<?php
setlocale(LC_CTYPE, "pl_PL.UTF-8", "en_US.UTF-8", "C.UTF-8");
require_once 'functions.php';
checkAuth();
if ($_SESSION['role'] !== 'admin') die(json_encode(['status'=>'error', 'msg'=>'Odmowa dostępu!']));

$cfg = cfg();
$action = $_POST['action'] ?? '';
$folderKey = $_POST['folder'] ?? '';
$subPath = sanitizePath($_POST['path'] ?? '');

if (!isset($cfg['allowedFolders'][$folderKey])) die(json_encode(['status'=>'error']));
$basePath = '/mnt/mega' . $cfg['allowedFolders'][$folderKey];
$targetDir = rtrim($basePath . '/' . $subPath, '/');

if ($action === 'delete') {
    $file = basename($_POST['file'] ?? '');
    $fullPath = $targetDir . '/' . $file;
    if (file_exists($fullPath)) { is_dir($fullPath) ? exec("rm -rf " . escapeshellarg($fullPath)) : unlink($fullPath); echo json_encode(['status'=>'ok']); } else echo json_encode(['status'=>'error']);
}
elseif ($action === 'multi_delete') {
    $files = $_POST['files'] ?? [];
    foreach($files as $file) {
        $safeName = basename($file);
        $fullPath = $targetDir . '/' . $safeName;
        if(file_exists($fullPath)) {
            is_dir($fullPath) ? exec("rm -rf " . escapeshellarg($fullPath)) : unlink($fullPath);
        }
    }
    echo json_encode(['status'=>'ok']);
}
elseif ($action === 'rename') {
    $old = basename($_POST['old_name'] ?? ''); $new = basename($_POST['new_name'] ?? '');
    if(rename($targetDir . '/' . $old, $targetDir . '/' . $new)) echo json_encode(['status'=>'ok']); else echo json_encode(['status'=>'error']);
}
elseif ($action === 'upload') {
    if (!empty($_FILES['files']['name'][0])) {
        $errors = [];
        foreach($_FILES['files']['name'] as $k => $name) {
            $filename = basename($name);
            $tmpName = $_FILES['files']['tmp_name'][$k];
            if(!move_uploaded_file($tmpName, $targetDir . '/' . $filename)) $errors[] = $filename;
        }
        
        // ZABEZPIECZENIE DYSKU (WGRYWANIE RĘCZNE): Czeka 10 minut by rclone zdążył wysłać pliki z bufora i usuwa VFS!
        exec("nohup bash -c 'sleep 600 && sudo -n rm -rf /root/.cache/rclone/vfs/* 2>/dev/null' >/dev/null 2>&1 &");
        
        if (empty($errors)) echo json_encode(['status'=>'ok']); else echo json_encode(['status'=>'error', 'msg'=>'Błąd wgrywania: ' . implode(', ', $errors)]);
    } else echo json_encode(['status'=>'error', 'msg'=>'Brak plików.']);
}
elseif ($action === 'upload_cookies') {
    if (!empty($_FILES['cookie_file']['tmp_name'])) {
        $target = __DIR__ . '/data/cookies.txt';
        $content = file_get_contents($_FILES['cookie_file']['tmp_name']);
        if ($content === false) die(json_encode(['status'=>'error', 'msg'=>'Serwer nie mógł odczytać wgranego pliku!']));
        if(file_put_contents($target, $content) !== false) {
            chmod($target, 0666);
            echo json_encode(['status'=>'ok', 'msg'=>'Sukces! Ciasteczka wgrane!']);
        } else echo json_encode(['status'=>'error', 'msg'=>'Błąd zapisu!']);
    } else echo json_encode(['status'=>'error', 'msg'=>'Nie przesłano żadnego pliku.']);
}
elseif ($action === 'mkdir') {
    $name = basename($_POST['name'] ?? '');
    if(mkdir($targetDir . '/' . $name, 0777, true)) echo json_encode(['status'=>'ok']); else echo json_encode(['status'=>'error', 'msg'=>'Błąd tworzenia folderu.']);
}
elseif ($action === 'move' || $action === 'copy') {
    $files = $_POST['files'] ?? [];
    $destFolderKey = $_POST['dest_folder'] ?? ''; $destSubPath = sanitizePath($_POST['dest_path'] ?? '');
    if (!isset($cfg['allowedFolders'][$destFolderKey])) die(json_encode(['status'=>'error', 'msg'=>'Błędny folder docelowy']));
    $destBase = rtrim('/mnt/mega' . $cfg['allowedFolders'][$destFolderKey] . '/' . $destSubPath, '/');
    if (!is_dir($destBase)) mkdir($destBase, 0777, true);

    foreach($files as $file) {
        $safeName = basename($file);
        $src = $targetDir . '/' . $safeName; $dst = $destBase . '/' . $safeName;
        if(file_exists($src)) {
            if ($action === 'move') rename($src, $dst);
            if ($action === 'copy') exec("cp -r " . escapeshellarg($src) . " " . escapeshellarg($dst));
        }
    }
    echo json_encode(['status'=>'ok']);
}
elseif ($action === 'unpack') {
    $files = $_POST['files'] ?? [];
    if (empty($files)) die(json_encode(['status'=>'error', 'msg'=>'Brak plików.']));
    
    $localTempDir = __DIR__ . '/data/yt_temp';
    @mkdir($localTempDir, 0777, true);
    $uniq = uniqid();
    
    $shPath = $localTempDir . '/unpack_' . $uniq . '.sh';
    $logFile = __DIR__ . '/data/unpack.log';
    
    $sh = "#!/bin/bash\n";
    foreach($files as $file) {
        $fullPath = $targetDir . '/' . basename($file);
        $extractDir = $localTempDir . '/dir_' . $uniq;
        $archiveName = pathinfo(basename($file), PATHINFO_FILENAME);
        $finalDir = $targetDir . '/' . preg_replace('/[^A-Za-z0-9_\-\.]/', '_', $archiveName);
        
        $sh .= "echo '[$(date)] START: ".basename($file)."' >> ".escapeshellarg($logFile)."\n";
        $sh .= "mkdir -p ".escapeshellarg($extractDir)."\n";
        if (strtolower(pathinfo($fullPath, PATHINFO_EXTENSION)) == 'zip') 
            $sh .= "unzip -o ".escapeshellarg($fullPath)." -d ".escapeshellarg($extractDir)." >> ".escapeshellarg($logFile)." 2>&1\n";
        else 
            $sh .= "unrar x -y -o+ ".escapeshellarg($fullPath)." ".escapeshellarg($extractDir)."/ >> ".escapeshellarg($logFile)." 2>&1\n";
            
        $sh .= "\\cp -rf ".escapeshellarg($extractDir)."/* ".escapeshellarg($finalDir)."/ >> ".escapeshellarg($logFile)." 2>&1\n";
        
        // ZABEZPIECZENIE DYSKU (ROZPAKOWYWANIE): Natychmiast usuwa bezpośredni katalog tymczasowy
        $sh .= "rm -rf ".escapeshellarg($extractDir)."\n";
    }
    
    // ZABEZPIECZENIE DYSKU (ROZPAKOWYWANIE): Czeka 10 minut i czyści główny Cache FUSE
    $sh .= "echo '[$(date)] Odliczam 10 minut, aby rclone wypluł pliki na serwery MEGA...' >> ".escapeshellarg($logFile)."\n";
    $sh .= "sleep 600\n";
    $sh .= "echo '[$(date)] Opróżniam dysk z ukrytych plików (VFS Cache)...' >> ".escapeshellarg($logFile)."\n";
    $sh .= "sudo -n rm -rf /root/.cache/rclone/vfs/* 2>/dev/null\n";
    $sh .= "echo '[$(date)] ZADANIE W PEŁNI ZAKOŃCZONE!' >> ".escapeshellarg($logFile)."\n";
    $sh .= "rm -f \"\$0\"";
    
    file_put_contents($shPath, $sh);
    chmod($shPath, 0777);
    exec("nohup bash ".escapeshellarg($shPath)." >/dev/null 2>&1 < /dev/null &");
    
    echo json_encode(['status'=>'ok', 'msg'=>'Zadanie rozpakowywania w toku.']);
}
elseif ($action === 'ytdlp') {
    $urls = $_POST['url'] ?? '';
    if (empty(trim($urls))) die(json_encode(['status'=>'error', 'msg'=>'Brak linków.']));
    
    $localTempDir = __DIR__ . '/data/yt_temp';
    @mkdir($localTempDir, 0777, true);
    $uniq = uniqid();

    // MASOWE POBIERANIE - Zamiana wpisanych linków z pola tekstowego na format batchowy
    $urlArray = preg_split('/\r\n|\r|\n|,/', $urls);
    $validUrls = [];
    $playlistArg = "--no-playlist"; 
    
    foreach($urlArray as $u) {
        $u = trim($u);
        if(!empty($u)) {
            $validUrls[] = $u;
            // Inteligentna kontrola playlist (odblokowuje jeśli natrafi na link samej playlisty)
            if (strpos($u, 'watch?v=') === false && strpos($u, 'youtu.be/') === false && strpos($u, '/shorts/') === false && (strpos($u, 'list=') !== false || strpos($u, '/playlist') !== false)) {
                $playlistArg = "--yes-playlist";
            }
        }
    }
    
    if(empty($validUrls)) die(json_encode(['status'=>'error', 'msg'=>'Brak prawidłowych linków.']));
    
    // Zapis listy linków do formatu Batch, żeby pobrał wszystkie naraz
    $batchFile = $localTempDir . '/batch_' . $uniq . '.txt';
    file_put_contents($batchFile, implode("\n", $validUrls));
    
    $logFile = __DIR__ . '/data/yt.log';
    file_put_contents($logFile, "\n=== NOWE ZADANIE MASOWE (" . date('H:i:s') . ") - Zlecono " . count($validUrls) . " link(ów) ===\n", FILE_APPEND);
    
    $dlSess = $localTempDir . '/dl_' . $uniq;
    $shPath = $localTempDir . '/run_yt_' . $uniq . '.sh';
    
    $sh  = "#!/bin/bash\n";
    $sh .= "echo '[$(date)] Rozpoczynam pobieranie (yt-dlp)...' >> ".escapeshellarg($logFile)."\n";
    
    // Komenda pobierania (czyta pliki batch)
    $sh .= "sudo -n /usr/local/bin/yt-dlp --cache-dir ".escapeshellarg(__DIR__ . '/data/yt_cache')." --cookies ".escapeshellarg(__DIR__ . '/data/cookies.txt')." -f 'bestvideo[ext=mp4]+bestaudio[ext=m4a]/best[ext=mp4]/best' -o ".escapeshellarg($dlSess.'/%(title)s.%(ext)s')." ".$playlistArg." -a ".escapeshellarg($batchFile)." >> ".escapeshellarg($logFile)." 2>&1\n";
    
    $sh .= "echo '[$(date)] Pobieranie zakończone. Kopiuję pliki na chmurę MEGA...' >> ".escapeshellarg($logFile)."\n";
    $sh .= "\\cp -rf ".escapeshellarg($dlSess)."/* ".escapeshellarg($targetDir)."/ >> ".escapeshellarg($logFile)." 2>&1\n";
    
    $sh .= "echo '[$(date)] Niszczę pobrane częściowo pliki tymczasowe z dysku VPS (yt_temp)...' >> ".escapeshellarg($logFile)."\n";
    // ZABEZPIECZENIE DYSKU (YT): Natychmiast usuwa ogromne pliki tymczasowe
    $sh .= "rm -rf ".escapeshellarg($dlSess)." ".escapeshellarg($batchFile)."\n";
    
    $sh .= "echo '[$(date)] Zabezpieczenie chmury: Odliczam 10 minut, aby rclone spokojnie wysłał dane z VFS Cache...' >> ".escapeshellarg($logFile)."\n";
    // ZABEZPIECZENIE DYSKU (YT): 10 Minut opóźnienia, żeby nie przerwać uploadu rclone, potem kasuje VFS
    $sh .= "sleep 600\n";
    $sh .= "echo '[$(date)] Opróżniam VFS Cache - Dysk został oswobodzony!' >> ".escapeshellarg($logFile)."\n";
    $sh .= "sudo -n rm -rf /root/.cache/rclone/vfs/* 2>/dev/null\n";
    $sh .= "echo '[$(date)] CAŁA OPERACJA W PEŁNI ZAKOŃCZONA!' >> ".escapeshellarg($logFile)."\n";
    $sh .= "rm -f \"\$0\"";
    
    file_put_contents($shPath, $sh);
    chmod($shPath, 0777);
    exec("nohup bash ".escapeshellarg($shPath)." >/dev/null 2>&1 < /dev/null &");
    
    echo json_encode(['status'=>'ok', 'msg'=>'Pobieranie wielu linków uruchomione! Zajrzyj do zakładki z logami.']);
}
elseif ($action === 'yt_log') {
    $logFile = __DIR__ . '/data/yt.log';
    $log = file_exists($logFile) ? shell_exec("tail -n 100 " . escapeshellarg($logFile)) : "Brak logów.";
    echo json_encode(['status'=>'ok', 'log'=>$log]);
}
elseif ($action === 'yt_log_clear') {
    $logFile = __DIR__ . '/data/yt.log';
    if(file_exists($logFile)) file_put_contents($logFile, "");
    echo json_encode(['status'=>'ok']);
}
?>
EOF

chown web3:client0 admin_ajax.php
echo "Panel został wzbogacony o masowe pobieranie i bezpieczne sprzątanie dysku!"
